diff --git a/.babelrc b/.babelrc index d3c4480..a29ac99 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,5 @@ { "presets": [ - ["env", { "modules": false }] - ], - "plugins": ["external-helpers"] + "@babel/preset-env" + ] } diff --git a/dist/shuffle.js b/dist/shuffle.js index ec12132..40d3ae5 100644 --- a/dist/shuffle.js +++ b/dist/shuffle.js @@ -4,6 +4,75 @@ (global.Shuffle = factory()); }(this, (function () { 'use strict'; + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); + if (superClass) _setPrototypeOf(subClass, superClass); + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + function _possibleConstructorReturn(self, call) { + if (call && (typeof call === "object" || typeof call === "function")) { + return call; + } + + return _assertThisInitialized(self); + } + function E () { // Keep this empty so it's easier to inherit from // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) @@ -182,67 +251,20 @@ return parseFloat(value) || 0; } - var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - }; - - var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); - - var inherits = function (subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true - } - }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - }; - - var possibleConstructorReturn = function (self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return call && (typeof call === "object" || typeof call === "function") ? call : self; - }; - - var Point = function () { + var Point = + /*#__PURE__*/ + function () { /** * Represents a coordinate pair. * @param {number} [x=0] X. * @param {number} [y=0] Y. */ function Point(x, y) { - classCallCheck(this, Point); + _classCallCheck(this, Point); this.x = getNumber(x); this.y = getNumber(y); } - /** * Whether two points are equal. * @param {Point} a Point A. @@ -251,16 +273,19 @@ */ - createClass(Point, null, [{ - key: 'equals', + _createClass(Point, null, [{ + key: "equals", value: function equals(a, b) { return a.x === b.x && a.y === b.y; } }]); + return Point; }(); - var Rect = function () { + var Rect = + /*#__PURE__*/ + function () { /** * Class for representing rectangular regions. * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js @@ -272,23 +297,22 @@ * @constructor */ function Rect(x, y, w, h, id) { - classCallCheck(this, Rect); + _classCallCheck(this, Rect); this.id = id; - /** @type {number} */ - this.left = x; + this.left = x; /** @type {number} */ - this.top = y; + this.top = y; /** @type {number} */ - this.width = w; + this.width = w; /** @type {number} */ + this.height = h; } - /** * Returns whether two rectangles intersect. * @param {Rect} a A Rectangle. @@ -297,12 +321,13 @@ */ - createClass(Rect, null, [{ + _createClass(Rect, null, [{ key: "intersects", value: function intersects(a, b) { return a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height; } }]); + return Rect; }(); @@ -313,32 +338,34 @@ HIDDEN: 'shuffle-item--hidden' }; - var id = 0; + var id$1 = 0; - var ShuffleItem = function () { + var ShuffleItem = + /*#__PURE__*/ + function () { function ShuffleItem(element) { - classCallCheck(this, ShuffleItem); + _classCallCheck(this, ShuffleItem); - id += 1; - this.id = id; + id$1 += 1; + this.id = id$1; this.element = element; - /** * Used to separate items for layout and shrink. */ - this.isVisible = true; + this.isVisible = true; /** * Used to determine if a transition will happen. By the time the _layout * and _shrink methods get the ShuffleItem instances, the `isVisible` value * has already been changed by the separation methods, so this property is * needed to know if the item was visible/hidden before the shrink/layout. */ + this.isHidden = false; } - createClass(ShuffleItem, [{ - key: 'show', + _createClass(ShuffleItem, [{ + key: "show", value: function show() { this.isVisible = true; this.element.classList.remove(Classes.HIDDEN); @@ -346,7 +373,7 @@ this.element.removeAttribute('aria-hidden'); } }, { - key: 'hide', + key: "hide", value: function hide() { this.isVisible = false; this.element.classList.remove(Classes.VISIBLE); @@ -354,7 +381,7 @@ this.element.setAttribute('aria-hidden', true); } }, { - key: 'init', + key: "init", value: function init() { this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]); this.applyCss(ShuffleItem.Css.INITIAL); @@ -362,7 +389,7 @@ this.point = new Point(); } }, { - key: 'addClasses', + key: "addClasses", value: function addClasses(classes) { var _this = this; @@ -371,7 +398,7 @@ }); } }, { - key: 'removeClasses', + key: "removeClasses", value: function removeClasses(classes) { var _this2 = this; @@ -380,7 +407,7 @@ }); } }, { - key: 'applyCss', + key: "applyCss", value: function applyCss(obj) { var _this3 = this; @@ -389,14 +416,14 @@ }); } }, { - key: 'dispose', + key: "dispose", value: function dispose() { this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); - this.element.removeAttribute('style'); this.element = null; } }]); + return ShuffleItem; }(); @@ -427,7 +454,6 @@ } } }; - ShuffleItem.Scale = { VISIBLE: 1, HIDDEN: 0.001 @@ -443,11 +469,8 @@ var e = document.createElement('div'); e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;'; element.appendChild(e); - value = window.getComputedStyle(e, null).width === '10px'; - element.removeChild(e); - return value; }); @@ -461,12 +484,11 @@ * will return 'auto' when the element doesn't have margins instead of * the computed style. */ + function getNumberStyle(element, style) { var styles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window.getComputedStyle(element, null); + var value = getNumber(styles[style]); // Support IE<=11 and W3C spec. - var value = getNumber(styles[style]); - - // Support IE<=11 and W3C spec. if (!testComputedSize() && style === 'width') { value += getNumber(styles.paddingLeft) + getNumber(styles.paddingRight) + getNumber(styles.borderLeftWidth) + getNumber(styles.borderRightWidth); } else if (!testComputedSize() && style === 'height') { @@ -497,27 +519,22 @@ return array; } - var defaults$1 = { + var defaults = { // Use array.reverse() to reverse the results reverse: false, - // Sorting function by: null, - // Custom sort function compare: null, - // If true, this will skip the sorting and return a randomized order in the array randomize: false, - // Determines which property of each item in the array is passed to the // sorting method. key: 'element' - }; + }; // You can return `undefined` from the `by` function to revert to DOM order. - // You can return `undefined` from the `by` function to revert to DOM order. function sorter(arr, options) { - var opts = Object.assign({}, defaults$1, options); + var opts = Object.assign({}, defaults, options); var original = Array.from(arr); var revert = false; @@ -527,10 +544,10 @@ if (opts.randomize) { return randomize(arr); - } - - // Sort the elements by the opts.by function. + } // Sort the elements by the opts.by function. // If we don't have opts.by, default to DOM order + + if (typeof opts.by === 'function') { arr.sort(function (a, b) { // Exit early if we already know we want to revert @@ -539,9 +556,8 @@ } var valA = opts.by(a[opts.key]); - var valB = opts.by(b[opts.key]); + var valB = opts.by(b[opts.key]); // If both values are undefined, use the DOM order - // If both values are undefined, use the DOM order if (valA === undefined && valB === undefined) { revert = true; return 0; @@ -559,9 +575,9 @@ }); } else if (typeof opts.compare === 'function') { arr.sort(opts.compare); - } + } // Revert to the original array if necessary + - // Revert to the original array if necessary if (revert) { return original; } @@ -591,9 +607,9 @@ return false; } - function onTransitionEnd(element, callback) { var id = uniqueId(); + var listener = function listener(evt) { if (evt.currentTarget === evt.target) { cancelTransitionEnd(id); @@ -602,9 +618,10 @@ }; element.addEventListener(eventName, listener); - - transitions[id] = { element: element, listener: listener }; - + transitions[id] = { + element: element, + listener: listener + }; return id; } @@ -624,34 +641,32 @@ * @param {number} threshold A buffer value for the size of the column to fit. * @return {number} */ - function getColumnSpan(itemWidth, columnWidth, columns, threshold) { - var columnSpan = itemWidth / columnWidth; - // If the difference between the rounded column span number and the + function getColumnSpan(itemWidth, columnWidth, columns, threshold) { + var columnSpan = itemWidth / columnWidth; // If the difference between the rounded column span number and the // calculated column span number is really small, round the number to // make it fit. + if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) { // e.g. columnSpan = 4.0089945390298745 columnSpan = Math.round(columnSpan); - } + } // Ensure the column span is not more than the amount of columns in the whole layout. + - // Ensure the column span is not more than the amount of columns in the whole layout. return Math.min(Math.ceil(columnSpan), columns); } - /** * Retrieves the column set to use for placement. * @param {number} columnSpan The number of columns this current item spans. * @param {number} columns The total columns in the grid. * @return {Array.} An array of numbers represeting the column set. */ + function getAvailablePositions(positions, columnSpan, columns) { // The item spans only one column. if (columnSpan === 1) { return positions; - } - - // The item spans more than one column, figure out how many different + } // The item spans more than one column, figure out how many different // places it could fit horizontally. // The group count is the number of places within the positions this block // could fit, ignoring the current positions of items. @@ -673,9 +688,10 @@ // // Another example where the second column's item extends past the first: // [10, 20, 10, 0] => [20, 20, 10] => 10 - var available = []; - // For how many possible positions for this item there are. + + var available = []; // For how many possible positions for this item there are. + for (var i = 0; i <= columns - columnSpan; i++) { // Find the bigger value for each place it could fit. available.push(arrayMax(positions.slice(i, i + columnSpan))); @@ -683,7 +699,6 @@ return available; } - /** * Find index of short column, the first from the left where this item will go. * @@ -692,8 +707,10 @@ * is a percentage of the width. * @return {number} Index of the short column. */ + function getShortColumn(positions, buffer) { var minPosition = arrayMin(positions); + for (var i = 0, len = positions.length; i < len; i++) { if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) { return i; @@ -702,7 +719,6 @@ return 0; } - /** * Determine the location of the next item, based on its size. * @param {Object} itemSize Object with width and height. @@ -713,6 +729,7 @@ * @param {number} buffer Vertical buffer for the height of items. * @return {Point} */ + function getItemPosition(_ref) { var itemSize = _ref.itemSize, positions = _ref.positions, @@ -720,25 +737,22 @@ total = _ref.total, threshold = _ref.threshold, buffer = _ref.buffer; - var span = getColumnSpan(itemSize.width, gridSize, total, threshold); var setY = getAvailablePositions(positions, span, total); - var shortColumnIndex = getShortColumn(setY, buffer); + var shortColumnIndex = getShortColumn(setY, buffer); // Position the item - // Position the item - var point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); - - // Update the columns array with the new values for each column. + var point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); // Update the columns array with the new values for each column. // e.g. before the update the columns could be [250, 0, 0, 0] for an item // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0]. + var setHeight = setY[shortColumnIndex] + itemSize.height; + for (var i = 0; i < span; i++) { positions[shortColumnIndex + i] = setHeight; } return point; } - /** * This method attempts to center items. This method could potentially be slow * with a large number of items because it must place items, then check every @@ -747,12 +761,12 @@ * @param {number} containerWidth Width of the containing element. * @return {Array.} */ - function getCenteredPositions(itemRects, containerWidth) { - var rowMap = {}; - // Populate rows by their offset because items could jump between rows like: + function getCenteredPositions(itemRects, containerWidth) { + var rowMap = {}; // Populate rows by their offset because items could jump between rows like: // a c // bbb + itemRects.forEach(function (itemRect) { if (rowMap[itemRect.top]) { // Push the point to the last row array. @@ -761,11 +775,10 @@ // Start of a new row. rowMap[itemRect.top] = [itemRect]; } - }); - - // For each row, find the end of the last item, then calculate + }); // For each row, find the end of the last item, then calculate // the remaining space by dividing it by 2. Then add that // offset to the x position of each point. + var rects = []; var rows = []; var centeredRows = []; @@ -775,45 +788,43 @@ var lastItem = itemRects[itemRects.length - 1]; var end = lastItem.left + lastItem.width; var offset = Math.round((containerWidth - end) / 2); - var finalRects = itemRects; var canMove = false; + if (offset > 0) { var newRects = []; canMove = itemRects.every(function (r) { - var newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); + var newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); // Check all current rects to make sure none overlap. - // Check all current rects to make sure none overlap. var noOverlap = !rects.some(function (r) { return Rect.intersects(newRect, r); }); - newRects.push(newRect); return noOverlap; - }); + }); // If none of the rectangles overlapped, the whole group can be centered. - // If none of the rectangles overlapped, the whole group can be centered. if (canMove) { finalRects = newRects; } - } - - // If the items are not going to be offset, ensure that the original + } // If the items are not going to be offset, ensure that the original // placement for this row will not overlap previous rows (row-spanning // elements could be in the way). + + if (!canMove) { - var intersectingRect = void 0; + var intersectingRect; var hasOverlap = itemRects.some(function (itemRect) { return rects.some(function (r) { var intersects = Rect.intersects(itemRect, r); + if (intersects) { intersectingRect = r; } + return intersects; }); - }); + }); // If there is any overlap, replace the overlapping row with the original. - // If there is any overlap, replace the overlapping row with the original. if (hasOverlap) { var rowIndex = centeredRows.findIndex(function (items) { return items.includes(intersectingRect); @@ -824,12 +835,11 @@ rects = rects.concat(finalRects); centeredRows.push(finalRects); - }); - - // Reduce array of arrays to a single array of points. + }); // Reduce array of arrays to a single array of points. // https://stackoverflow.com/a/10865042/373422 // Then reset sort back to how the items were passed to this method. // Remove the wrapper object with index, map to a Point. + return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread .sort(function (a, b) { return a.id - b.id; @@ -846,19 +856,21 @@ */ function hyphenate(str) { return str.replace(/([A-Z])/g, function (str, m1) { - return "-" + m1.toLowerCase(); + return "-".concat(m1.toLowerCase()); }); } function arrayUnique(x) { return Array.from(new Set(x)); - } + } // Used for unique instance variables - // Used for unique instance variables - var id$1 = 0; - var Shuffle = function (_TinyEmitter) { - inherits(Shuffle, _TinyEmitter); + var id$2 = 0; + + var Shuffle = + /*#__PURE__*/ + function (_TinyEmitter) { + _inherits(Shuffle, _TinyEmitter); /** * Categorize, sort, and filter a responsive grid of items. @@ -868,15 +880,16 @@ * @constructor */ function Shuffle(element) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - classCallCheck(this, Shuffle); + var _this; - var _this = possibleConstructorReturn(this, (Shuffle.__proto__ || Object.getPrototypeOf(Shuffle)).call(this)); + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - _this.options = Object.assign({}, Shuffle.options, options); + _classCallCheck(this, Shuffle); - // Allow misspelling of delimiter since that's how it used to be. + _this = _possibleConstructorReturn(this, _getPrototypeOf(Shuffle).call(this)); + _this.options = Object.assign({}, Shuffle.options, options); // Allow misspelling of delimiter since that's how it used to be. // Remove in v6. + if (_this.options.delimeter) { _this.options.delimiter = _this.options.delimeter; } @@ -898,65 +911,60 @@ } _this.element = el; - _this.id = 'shuffle_' + id$1; - id$1 += 1; + _this.id = 'shuffle_' + id$2; + id$2 += 1; _this._init(); + _this.isInitialized = true; return _this; } - createClass(Shuffle, [{ - key: '_init', + _createClass(Shuffle, [{ + key: "_init", value: function _init() { this.items = this._getItems(); + this.options.sizer = this._getElementOption(this.options.sizer); // Add class and invalidate styles - this.options.sizer = this._getElementOption(this.options.sizer); + this.element.classList.add(Shuffle.Classes.BASE); // Set initial css for each item - // Add class and invalidate styles - this.element.classList.add(Shuffle.Classes.BASE); + this._initItems(this.items); // Bind resize events - // Set initial css for each item - this._initItems(this.items); - // Bind resize events this._onResize = this._getResizeFunction(); - window.addEventListener('resize', this._onResize); - - // If the page has not already emitted the `load` event, call layout on load. + window.addEventListener('resize', this._onResize); // If the page has not already emitted the `load` event, call layout on load. // This avoids layout issues caused by images and fonts loading after the // instance has been initialized. + if (document.readyState !== 'complete') { var layout = this.layout.bind(this); window.addEventListener('load', function onLoad() { window.removeEventListener('load', onLoad); layout(); }); - } + } // Get container css all in one request. Causes reflow - // Get container css all in one request. Causes reflow - var containerCss = window.getComputedStyle(this.element, null); - var containerWidth = Shuffle.getSize(this.element).width; - // Add styles to the container if it doesn't have them. - this._validateStyles(containerCss); + var containerCss = window.getComputedStyle(this.element, null); + var containerWidth = Shuffle.getSize(this.element).width; // Add styles to the container if it doesn't have them. - // We already got the container's width above, no need to cause another + this._validateStyles(containerCss); // We already got the container's width above, no need to cause another // reflow getting it again... Calculate the number of columns there will be - this._setColumns(containerWidth); - // Kick off! - this.filter(this.options.group, this.options.initialSort); - // The shuffle items haven't had transitions set on them yet so the user + this._setColumns(containerWidth); // Kick off! + + + this.filter(this.options.group, this.options.initialSort); // The shuffle items haven't had transitions set on them yet so the user // doesn't see the first layout. Set them now that the first layout is done. // First, however, a synchronous layout must be caused for the previous // styles to be applied without transitions. + this.element.offsetWidth; // eslint-disable-line no-unused-expressions + this.setItemTransitions(this.items); - this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing; + this.element.style.transition = "height ".concat(this.options.speed, "ms ").concat(this.options.easing); } - /** * Returns a throttled and proxied function for the resize handler. * @return {function} @@ -964,12 +972,12 @@ */ }, { - key: '_getResizeFunction', + key: "_getResizeFunction", value: function _getResizeFunction() { var resizeFunction = this._handleResize.bind(this); + return this.options.throttle ? this.options.throttle(resizeFunction, this.options.throttleTime) : resizeFunction; } - /** * Retrieve an element from an option. * @param {string|jQuery|Element} option The option to check. @@ -978,25 +986,20 @@ */ }, { - key: '_getElementOption', + key: "_getElementOption", value: function _getElementOption(option) { // If column width is a string, treat is as a selector and search for the // sizer element within the outermost container if (typeof option === 'string') { - return this.element.querySelector(option); - - // Check for an element + return this.element.querySelector(option); // Check for an element } else if (option && option.nodeType && option.nodeType === 1) { - return option; - - // Check for jQuery object + return option; // Check for jQuery object } else if (option && option.jquery) { return option[0]; } return null; } - /** * Ensures the shuffle container has the css styles it needs applied to it. * @param {Object} styles Key value pairs for position and overflow. @@ -1004,19 +1007,18 @@ */ }, { - key: '_validateStyles', + key: "_validateStyles", value: function _validateStyles(styles) { // Position cannot be static. if (styles.position === 'static') { this.element.style.position = 'relative'; - } + } // Overflow has to be hidden. + - // Overflow has to be hidden. if (styles.overflow !== 'hidden') { this.element.style.overflow = 'hidden'; } } - /** * Filter the elements by a category. * @param {string|string[]|function(Element):boolean} [category] Category to @@ -1028,28 +1030,26 @@ */ }, { - key: '_filter', + key: "_filter", value: function _filter() { var category = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastFilter; var collection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.items; - var set$$1 = this._getFilteredSets(category, collection); + var set = this._getFilteredSets(category, collection); // Individually add/remove hidden/visible classes - // Individually add/remove hidden/visible classes - this._toggleFilterClasses(set$$1); - // Save the last filter in case elements are appended. - this.lastFilter = category; + this._toggleFilterClasses(set); // Save the last filter in case elements are appended. - // This is saved mainly because providing a filter function (like searching) + + this.lastFilter = category; // This is saved mainly because providing a filter function (like searching) // will overwrite the `lastFilter` property every time its called. + if (typeof category === 'string') { this.group = category; } - return set$$1; + return set; } - /** * Returns an object containing the visible and hidden elements. * @param {string|string[]|function(Element):boolean} category Category or function to filter by. @@ -1059,18 +1059,15 @@ */ }, { - key: '_getFilteredSets', + key: "_getFilteredSets", value: function _getFilteredSets(category, items) { var _this2 = this; var visible = []; - var hidden = []; + var hidden = []; // category === 'all', add visible class to everything - // category === 'all', add visible class to everything if (category === Shuffle.ALL_ITEMS) { - visible = items; - - // Loop through each item and use provided function to determine + visible = items; // Loop through each item and use provided function to determine // whether to hide it or not. } else { items.forEach(function (item) { @@ -1087,7 +1084,6 @@ hidden: hidden }; } - /** * Test an item to see if it passes a category. * @param {string|string[]|function():boolean} category Category or function to filter by. @@ -1097,13 +1093,13 @@ */ }, { - key: '_doesPassFilter', + key: "_doesPassFilter", value: function _doesPassFilter(category, element) { if (typeof category === 'function') { return category.call(element, element, this); - } + } // Check each element's data-groups attribute against the given category. + - // Check each element's data-groups attribute against the given category. var attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); var keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); @@ -1115,12 +1111,12 @@ if (this.options.filterMode === Shuffle.FilterMode.ANY) { return category.some(testCategory); } + return category.every(testCategory); } return keys.includes(category); } - /** * Toggles the visible and hidden class names. * @param {{visible, hidden}} Object with visible and hidden arrays. @@ -1128,20 +1124,17 @@ */ }, { - key: '_toggleFilterClasses', + key: "_toggleFilterClasses", value: function _toggleFilterClasses(_ref) { var visible = _ref.visible, hidden = _ref.hidden; - visible.forEach(function (item) { item.show(); }); - hidden.forEach(function (item) { item.hide(); }); } - /** * Set the initial css for each item * @param {ShuffleItem[]} items Set to initialize. @@ -1149,13 +1142,12 @@ */ }, { - key: '_initItems', + key: "_initItems", value: function _initItems(items) { items.forEach(function (item) { item.init(); }); } - /** * Remove element reference and styles. * @param {ShuffleItem[]} items Set to dispose. @@ -1163,24 +1155,22 @@ */ }, { - key: '_disposeItems', + key: "_disposeItems", value: function _disposeItems(items) { items.forEach(function (item) { item.dispose(); }); } - /** * Updates the visible item count. * @private */ }, { - key: '_updateItemCount', + key: "_updateItemCount", value: function _updateItemCount() { this.visibleItems = this._getFilteredItems().length; } - /** * Sets css transform transition on a group of elements. This is not executed * at the same time as `item.init` so that transitions don't occur upon @@ -1190,21 +1180,18 @@ */ }, { - key: 'setItemTransitions', + key: "setItemTransitions", value: function setItemTransitions(items) { - var _options = this.options, - speed = _options.speed, - easing = _options.easing; - - var positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; - - // Allow users to transtion other properties if they exist in the `before` + var _this$options = this.options, + speed = _this$options.speed, + easing = _this$options.easing; + var positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; // Allow users to transtion other properties if they exist in the `before` // css mapping of the shuffle item. + var cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(function (k) { return hyphenate(k); }); var properties = positionProps.concat(cssProps).join(); - items.forEach(function (item) { item.element.style.transitionDuration = speed + 'ms'; item.element.style.transitionTimingFunction = easing; @@ -1212,7 +1199,7 @@ }); } }, { - key: '_getItems', + key: "_getItems", value: function _getItems() { var _this3 = this; @@ -1222,7 +1209,6 @@ return new ShuffleItem(el); }); } - /** * Combine the current items array with a new one and sort it by DOM order. * @param {ShuffleItem[]} items Items to track. @@ -1230,7 +1216,7 @@ */ }, { - key: '_mergeNewItems', + key: "_mergeNewItems", value: function _mergeNewItems(items) { var children = Array.from(this.element.children); return sorter(this.items.concat(items), { @@ -1240,20 +1226,19 @@ }); } }, { - key: '_getFilteredItems', + key: "_getFilteredItems", value: function _getFilteredItems() { return this.items.filter(function (item) { return item.isVisible; }); } }, { - key: '_getConcealedItems', + key: "_getConcealedItems", value: function _getConcealedItems() { return this.items.filter(function (item) { return !item.isVisible; }); } - /** * Returns the column size, based on column width and sizer options. * @param {number} containerWidth Size of the parent container. @@ -1263,39 +1248,29 @@ */ }, { - key: '_getColumnSize', + key: "_getColumnSize", value: function _getColumnSize(containerWidth, gutterSize) { - var size = void 0; + var size; // If the columnWidth property is a function, then the grid is fluid - // If the columnWidth property is a function, then the grid is fluid if (typeof this.options.columnWidth === 'function') { - size = this.options.columnWidth(containerWidth); - - // columnWidth option isn't a function, are they using a sizing element? + size = this.options.columnWidth(containerWidth); // columnWidth option isn't a function, are they using a sizing element? } else if (this.options.sizer) { - size = Shuffle.getSize(this.options.sizer).width; - - // if not, how about the explicitly set option? + size = Shuffle.getSize(this.options.sizer).width; // if not, how about the explicitly set option? } else if (this.options.columnWidth) { - size = this.options.columnWidth; - - // or use the size of the first item + size = this.options.columnWidth; // or use the size of the first item } else if (this.items.length > 0) { - size = Shuffle.getSize(this.items[0].element, true).width; - - // if there's no items, use size of container + size = Shuffle.getSize(this.items[0].element, true).width; // if there's no items, use size of container } else { size = containerWidth; - } + } // Don't let them set a column width of zero. + - // Don't let them set a column width of zero. if (size === 0) { size = containerWidth; } return size + gutterSize; } - /** * Returns the gutter size, based on gutter width and sizer options. * @param {number} containerWidth Size of the parent container. @@ -1304,9 +1279,10 @@ */ }, { - key: '_getGutterSize', + key: "_getGutterSize", value: function _getGutterSize(containerWidth) { - var size = void 0; + var size; + if (typeof this.options.gutterWidth === 'function') { size = this.options.gutterWidth(containerWidth); } else if (this.options.sizer) { @@ -1317,7 +1293,6 @@ return size; } - /** * Calculate the number of columns to be used. Gets css if using sizer element. * @param {number} [containerWidth] Optionally specify a container width if @@ -1325,15 +1300,16 @@ */ }, { - key: '_setColumns', + key: "_setColumns", value: function _setColumns() { var containerWidth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Shuffle.getSize(this.element).width; var gutter = this._getGutterSize(containerWidth); + var columnWidth = this._getColumnSize(containerWidth, gutter); - var calculatedColumns = (containerWidth + gutter) / columnWidth; - // Widths given from getStyles are not precise enough... + var calculatedColumns = (containerWidth + gutter) / columnWidth; // Widths given from getStyles are not precise enough... + if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) < this.options.columnThreshold) { // e.g. calculatedColumns = 11.998876 calculatedColumns = Math.round(calculatedColumns); @@ -1343,17 +1319,15 @@ this.containerWidth = containerWidth; this.colWidth = columnWidth; } - /** * Adjust the height of the grid */ }, { - key: '_setContainerSize', + key: "_setContainerSize", value: function _setContainerSize() { this.element.style.height = this._getContainerSize() + 'px'; } - /** * Based on the column heights, it returns the biggest one. * @return {number} @@ -1361,11 +1335,10 @@ */ }, { - key: '_getContainerSize', + key: "_getContainerSize", value: function _getContainerSize() { return arrayMax(this.positions); } - /** * Get the clamped stagger amount. * @param {number} index Index of the item to be staggered. @@ -1373,11 +1346,10 @@ */ }, { - key: '_getStaggerAmount', + key: "_getStaggerAmount", value: function _getStaggerAmount(index) { return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax); } - /** * Emit an event from this instance. * @param {string} name Event name. @@ -1385,7 +1357,7 @@ */ }, { - key: '_dispatch', + key: "_dispatch", value: function _dispatch(name) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -1396,23 +1368,22 @@ data.shuffle = this; this.emit(name, data); } - /** * Zeros out the y columns array, which is used to determine item placement. * @private */ }, { - key: '_resetCols', + key: "_resetCols", value: function _resetCols() { var i = this.cols; this.positions = []; + while (i) { i -= 1; this.positions.push(0); } } - /** * Loops through each item that should be shown and calculates the x, y position. * @param {ShuffleItem[]} items Array of items that will be shown/layed @@ -1420,7 +1391,7 @@ */ }, { - key: '_layout', + key: "_layout", value: function _layout(items) { var _this4 = this; @@ -1430,10 +1401,10 @@ items.forEach(function (item, i) { function callback() { item.applyCss(ShuffleItem.Css.VISIBLE.after); - } - - // If the item will not change its position, do not add it to the render + } // If the item will not change its position, do not add it to the render // queue. Transitions don't fire when setting a property to the same value. + + if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) { item.applyCss(ShuffleItem.Css.VISIBLE.before); callback(); @@ -1442,11 +1413,11 @@ item.point = itemPositions[i]; item.scale = ShuffleItem.Scale.VISIBLE; - item.isHidden = false; - - // Clone the object so that the `before` object isn't modified when the + item.isHidden = false; // Clone the object so that the `before` object isn't modified when the // transition delay is added. + var styles = _this4.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before); + styles.transitionDelay = _this4._getStaggerAmount(count) + 'ms'; _this4._queue.push({ @@ -1458,7 +1429,6 @@ count += 1; }); } - /** * Return an array of Point instances representing the future positions of * each item. @@ -1468,7 +1438,7 @@ */ }, { - key: '_getNextPositions', + key: "_getNextPositions", value: function _getNextPositions(items) { var _this5 = this; @@ -1477,20 +1447,20 @@ if (this.options.isCentered) { var itemsData = items.map(function (item, i) { var itemSize = Shuffle.getSize(item.element, true); + var point = _this5._getItemPosition(itemSize); + return new Rect(point.x, point.y, itemSize.width, itemSize.height, i); }); - return this.getTransformedPositions(itemsData, this.containerWidth); - } - - // If no transforms are going to happen, simply return an array of the + } // If no transforms are going to happen, simply return an array of the // future points of each item. + + return items.map(function (item) { return _this5._getItemPosition(Shuffle.getSize(item.element, true)); }); } - /** * Determine the location of the next item, based on its size. * @param {{width: number, height: number}} itemSize Object with width and height. @@ -1499,7 +1469,7 @@ */ }, { - key: '_getItemPosition', + key: "_getItemPosition", value: function _getItemPosition(itemSize) { return getItemPosition({ itemSize: itemSize, @@ -1510,7 +1480,6 @@ buffer: this.options.buffer }); } - /** * Mutate positions before they're applied. * @param {Rect[]} itemRects Item data objects. @@ -1520,11 +1489,10 @@ */ }, { - key: 'getTransformedPositions', + key: "getTransformedPositions", value: function getTransformedPositions(itemRects, containerWidth) { return getCenteredPositions(itemRects, containerWidth); } - /** * Hides the elements that don't match our filter. * @param {ShuffleItem[]} collection Collection to shrink. @@ -1532,24 +1500,23 @@ */ }, { - key: '_shrink', + key: "_shrink", value: function _shrink() { var _this6 = this; var collection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._getConcealedItems(); - var count = 0; collection.forEach(function (item) { function callback() { item.applyCss(ShuffleItem.Css.HIDDEN.after); - } - - // Continuing would add a transitionend event listener to the element, but + } // Continuing would add a transitionend event listener to the element, but // that listener would not execute because the transform and opacity would // stay the same. // The callback is executed here because it is not guaranteed to be called // after the transitionend event because the transitionend could be // canceled if another animation starts. + + if (item.isHidden) { item.applyCss(ShuffleItem.Css.HIDDEN.before); callback(); @@ -1560,6 +1527,7 @@ item.isHidden = true; var styles = _this6.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before); + styles.transitionDelay = _this6._getStaggerAmount(count) + 'ms'; _this6._queue.push({ @@ -1571,14 +1539,13 @@ count += 1; }); } - /** * Resize handler. * @private */ }, { - key: '_handleResize', + key: "_handleResize", value: function _handleResize() { // If shuffle is disabled, destroyed, don't do anything if (!this.isEnabled || this.isDestroyed) { @@ -1587,7 +1554,6 @@ this.update(); } - /** * Returns styles which will be applied to the an item for a transition. * @param {ShuffleItem} item Item to get styles for. Should have updated @@ -1598,7 +1564,7 @@ */ }, { - key: 'getStylesForTransition', + key: "getStylesForTransition", value: function getStylesForTransition(item, styleObject) { // Clone the object to avoid mutating the original. var styles = Object.assign({}, styleObject); @@ -1606,7 +1572,7 @@ if (this.options.useTransforms) { var x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x; var y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y; - styles.transform = 'translate(' + x + 'px, ' + y + 'px) scale(' + item.scale + ')'; + styles.transform = "translate(".concat(x, "px, ").concat(y, "px) scale(").concat(item.scale, ")"); } else { styles.left = item.point.x + 'px'; styles.top = item.point.y + 'px'; @@ -1614,7 +1580,6 @@ return styles; } - /** * Listen for the transition end on an element and execute the itemCallback * when it finishes. @@ -1624,7 +1589,7 @@ */ }, { - key: '_whenTransitionDone', + key: "_whenTransitionDone", value: function _whenTransitionDone(element, itemCallback, done) { var id = onTransitionEnd(element, function (evt) { itemCallback(); @@ -1633,7 +1598,6 @@ this._transitions.push(id); } - /** * Return a function which will set CSS styles and call the `done` function * when (if) the transition finishes. @@ -1642,16 +1606,16 @@ */ }, { - key: '_getTransitionFunction', + key: "_getTransitionFunction", value: function _getTransitionFunction(opts) { var _this7 = this; return function (done) { opts.item.applyCss(opts.styles); + _this7._whenTransitionDone(opts.item.element, opts.callback, done); }; } - /** * Execute the styles gathered in the style queue. This applies styles to elements, * triggering transitions. @@ -1659,7 +1623,7 @@ */ }, { - key: '_processQueue', + key: "_processQueue", value: function _processQueue() { if (this.isTransitioning) { this._cancelMovement(); @@ -1672,52 +1636,47 @@ this._startTransitions(this._queue); } else if (hasQueue) { this._styleImmediately(this._queue); - this._dispatch(Shuffle.EventType.LAYOUT); - // A call to layout happened, but none of the newly visible items will + this._dispatch(Shuffle.EventType.LAYOUT); // A call to layout happened, but none of the newly visible items will // change position or the transition duration is zero, which will not trigger // the transitionend event. + } else { this._dispatch(Shuffle.EventType.LAYOUT); - } + } // Remove everything in the style queue + - // Remove everything in the style queue this._queue.length = 0; } - /** * Wait for each transition to finish, the emit the layout event. * @param {Object[]} transitions Array of transition objects. */ }, { - key: '_startTransitions', + key: "_startTransitions", value: function _startTransitions(transitions) { var _this8 = this; // Set flag that shuffle is currently in motion. - this.isTransitioning = true; + this.isTransitioning = true; // Create an array of functions to be called. - // Create an array of functions to be called. var callbacks = transitions.map(function (obj) { return _this8._getTransitionFunction(obj); }); - arrayParallel(callbacks, this._movementFinished.bind(this)); } }, { - key: '_cancelMovement', + key: "_cancelMovement", value: function _cancelMovement() { // Remove the transition end event for each listener. - this._transitions.forEach(cancelTransitionEnd); + this._transitions.forEach(cancelTransitionEnd); // Reset the array. - // Reset the array. - this._transitions.length = 0; - // Show it's no longer active. + this._transitions.length = 0; // Show it's no longer active. + this.isTransitioning = false; } - /** * Apply styles without a transition. * @param {Object[]} objects Array of transition objects. @@ -1725,7 +1684,7 @@ */ }, { - key: '_styleImmediately', + key: "_styleImmediately", value: function _styleImmediately(objects) { if (objects.length) { var elements = objects.map(function (obj) { @@ -1741,13 +1700,13 @@ } } }, { - key: '_movementFinished', + key: "_movementFinished", value: function _movementFinished() { this._transitions.length = 0; this.isTransitioning = false; + this._dispatch(Shuffle.EventType.LAYOUT); } - /** * The magic. This is what makes the plugin 'shuffle' * @param {string|string[]|function(Element):boolean} [category] Category to filter by. @@ -1756,7 +1715,7 @@ */ }, { - key: 'filter', + key: "filter", value: function filter(category, sortObj) { if (!this.isEnabled) { return; @@ -1766,25 +1725,24 @@ category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign } - this._filter(category); + this._filter(category); // Shrink each hidden item - // Shrink each hidden item - this._shrink(); - // How many visible elements? - this._updateItemCount(); + this._shrink(); // How many visible elements? + + + this._updateItemCount(); // Update transforms on visible elements so they will animate to their new positions. + - // Update transforms on visible elements so they will animate to their new positions. this.sort(sortObj); } - /** * Gets the visible elements, sorts them, and passes them to layout. * @param {Object} [sortOptions] The options object to pass to `sorter`. */ }, { - key: 'sort', + key: "sort", value: function sort() { var sortOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastSort; @@ -1796,25 +1754,24 @@ var items = sorter(this._getFilteredItems(), sortOptions); - this._layout(items); - - // `_layout` always happens after `_shrink`, so it's safe to process the style + this._layout(items); // `_layout` always happens after `_shrink`, so it's safe to process the style // queue here with styles from the shrink method. - this._processQueue(); - // Adjust the height of the container. + + this._processQueue(); // Adjust the height of the container. + + this._setContainerSize(); this.lastSort = sortOptions; } - /** * Reposition everything. * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated. */ }, { - key: 'update', + key: "update", value: function update() { var isOnlyLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; @@ -1822,13 +1779,12 @@ if (!isOnlyLayout) { // Get updated colCount this._setColumns(); - } + } // Layout items + - // Layout items this.sort(); } } - /** * Use this instead of `update()` if you don't need the columns and gutters updated * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations @@ -1836,11 +1792,10 @@ */ }, { - key: 'layout', + key: "layout", value: function layout() { this.update(true); } - /** * New items have been appended to shuffle. Mix them in with the current * filter or sort status. @@ -1848,37 +1803,40 @@ */ }, { - key: 'add', + key: "add", value: function add(newItems) { var _this9 = this; var items = arrayUnique(newItems).map(function (el) { return new ShuffleItem(el); - }); + }); // Add classes and set initial positions. + + this._initItems(items); // Determine which items will go with the current filter. - // Add classes and set initial positions. - this._initItems(items); - // Determine which items will go with the current filter. this._resetCols(); var allItems = this._mergeNewItems(items); + var sortedItems = sorter(allItems, this.lastSort); + var allSortedItemsSet = this._filter(this.lastFilter, sortedItems); var isNewItem = function isNewItem(item) { return items.includes(item); }; + var applyHiddenState = function applyHiddenState(item) { item.scale = ShuffleItem.Scale.HIDDEN; item.isHidden = true; item.applyCss(ShuffleItem.Css.HIDDEN.before); item.applyCss(ShuffleItem.Css.HIDDEN.after); - }; - - // Layout all items again so that new items get positions. + }; // Layout all items again so that new items get positions. // Synchonously apply positions. + + var itemPositions = this._getNextPositions(allSortedItemsSet.visible); + allSortedItemsSet.visible.forEach(function (item, i) { if (isNewItem(item)) { item.point = itemPositions[i]; @@ -1886,52 +1844,45 @@ item.applyCss(_this9.getStylesForTransition(item, {})); } }); - allSortedItemsSet.hidden.forEach(function (item) { if (isNewItem(item)) { applyHiddenState(item); } - }); + }); // Cause layout so that the styles above are applied. - // Cause layout so that the styles above are applied. this.element.offsetWidth; // eslint-disable-line no-unused-expressions - // Add transition to each item. - this.setItemTransitions(items); - // Update the list of items. - this.items = this._mergeNewItems(items); + this.setItemTransitions(items); // Update the list of items. + + this.items = this._mergeNewItems(items); // Update layout/visibility of new and old items. - // Update layout/visibility of new and old items. this.filter(this.lastFilter); } - /** * Disables shuffle from updating dimensions and layout on resize */ }, { - key: 'disable', + key: "disable", value: function disable() { this.isEnabled = false; } - /** * Enables shuffle again * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters */ }, { - key: 'enable', + key: "enable", value: function enable() { var isUpdateLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - this.isEnabled = true; + if (isUpdateLayout) { this.update(); } } - /** * Remove 1 or more shuffle items. * @param {Element[]} elements An array containing one or more @@ -1940,7 +1891,7 @@ */ }, { - key: 'remove', + key: "remove", value: function remove(elements) { var _this10 = this; @@ -1949,7 +1900,6 @@ } var collection = arrayUnique(elements); - var oldItems = collection.map(function (element) { return _this10.getItemByElement(element); }).filter(function (item) { @@ -1957,17 +1907,19 @@ }); var handleLayout = function handleLayout() { - _this10._disposeItems(oldItems); + _this10._disposeItems(oldItems); // Remove the collection in the callback + - // Remove the collection in the callback collection.forEach(function (element) { element.parentNode.removeChild(element); }); - _this10._dispatch(Shuffle.EventType.REMOVED, { collection: collection }); - }; + _this10._dispatch(Shuffle.EventType.REMOVED, { + collection: collection + }); + }; // Hide collection first. + - // Hide collection first. this._toggleFilterClasses({ visible: [], hidden: oldItems @@ -1975,18 +1927,17 @@ this._shrink(oldItems); - this.sort(); - - // Update the list of items here because `remove` could be called again + this.sort(); // Update the list of items here because `remove` could be called again // with an item that is in the process of being removed. + this.items = this.items.filter(function (item) { return !oldItems.includes(item); }); + this._updateItemCount(); this.once(Shuffle.EventType.LAYOUT, handleLayout); } - /** * Retrieve a shuffle item by its element. * @param {Element} element Element to look for. @@ -1994,73 +1945,66 @@ */ }, { - key: 'getItemByElement', + key: "getItemByElement", value: function getItemByElement(element) { return this.items.find(function (item) { return item.element === element; }); } - /** * Dump the elements currently stored and reinitialize all child elements which * match the `itemSelector`. */ }, { - key: 'resetItems', + key: "resetItems", value: function resetItems() { var _this11 = this; // Remove refs to current items. this._disposeItems(this.items); - this.isInitialized = false; - // Find new items in the DOM. - this.items = this._getItems(); + this.isInitialized = false; // Find new items in the DOM. + + this.items = this._getItems(); // Set initial styles on the new items. - // Set initial styles on the new items. this._initItems(this.items); this.once(Shuffle.EventType.LAYOUT, function () { // Add transition to each item. _this11.setItemTransitions(_this11.items); + _this11.isInitialized = true; - }); + }); // Lay out all items. - // Lay out all items. this.filter(this.lastFilter); } - /** * Destroys shuffle, removes events, styles, and classes */ }, { - key: 'destroy', + key: "destroy", value: function destroy() { this._cancelMovement(); - window.removeEventListener('resize', this._onResize); - // Reset container styles + window.removeEventListener('resize', this._onResize); // Reset container styles + this.element.classList.remove('shuffle'); - this.element.removeAttribute('style'); + this.element.removeAttribute('style'); // Reset individual item styles - // Reset individual item styles this._disposeItems(this.items); this.items.length = 0; - this._transitions.length = 0; + this._transitions.length = 0; // Null DOM references - // Null DOM references this.options.sizer = null; - this.element = null; - - // Set a flag so if a debounced resize has been triggered, + this.element = null; // Set a flag so if a debounced resize has been triggered, // it can first check if it is actually isDestroyed and not doing anything + this.isDestroyed = true; this.isEnabled = false; } - /** * Returns the outer width of an element, optionally including its margins. * @@ -2085,10 +2029,9 @@ */ }], [{ - key: 'getSize', + key: "getSize", value: function getSize(element) { var includeMargins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - // Store the styles so that they can be used by others without asking for it again. var styles = window.getComputedStyle(element, null); var width = getNumberStyle(element, 'width', styles); @@ -2108,7 +2051,6 @@ height: height }; } - /** * Change a property or execute a function which will not have a transition * @param {Element[]} elements DOM elements that won't be transitioned. @@ -2118,137 +2060,110 @@ */ }, { - key: '_skipTransitions', + key: "_skipTransitions", value: function _skipTransitions(elements, callback) { - var zero = '0ms'; + var zero = '0ms'; // Save current duration and delay. - // Save current duration and delay. var data = elements.map(function (element) { var style = element.style; - var duration = style.transitionDuration; - var delay = style.transitionDelay; + var delay = style.transitionDelay; // Set the duration to zero so it happens immediately - // Set the duration to zero so it happens immediately style.transitionDuration = zero; style.transitionDelay = zero; - return { duration: duration, delay: delay }; }); + callback(); // Cause forced synchronous layout. - callback(); - - // Cause forced synchronous layout. elements[0].offsetWidth; // eslint-disable-line no-unused-expressions - // Put the duration back + elements.forEach(function (element, i) { element.style.transitionDuration = data[i].duration; element.style.transitionDelay = data[i].delay; }); } }]); + return Shuffle; }(tinyEmitter); Shuffle.ShuffleItem = ShuffleItem; - Shuffle.ALL_ITEMS = 'all'; Shuffle.FILTER_ATTRIBUTE_KEY = 'groups'; - /** @enum {string} */ + Shuffle.EventType = { LAYOUT: 'shuffle:layout', REMOVED: 'shuffle:removed' }; - /** @enum {string} */ - Shuffle.Classes = Classes; + Shuffle.Classes = Classes; /** @enum {string} */ + Shuffle.FilterMode = { ANY: 'any', ALL: 'all' - }; + }; // Overrideable options - // Overrideable options Shuffle.options = { // Initial filter group. group: Shuffle.ALL_ITEMS, - // Transition/animation speed (milliseconds). speed: 250, - // CSS easing function to use. easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)', - // e.g. '.picture-item'. itemSelector: '*', - // Element or selector string. Use an element to determine the size of columns // and gutters. sizer: null, - // A static number or function that tells the plugin how wide the gutters // between columns are (in pixels). gutterWidth: 0, - // A static number or function that returns a number which tells the plugin // how wide the columns are (in pixels). columnWidth: 0, - // If your group is not json, and is comma delimeted, you could set delimiter // to ','. delimiter: null, - // Useful for percentage based heights when they might not always be exactly // the same (in pixels). buffer: 0, - // Reading the width of elements isn't precise enough and can cause columns to // jump between values. columnThreshold: 0.01, - // Shuffle can be isInitialized with a sort object. It is the same object // given to the sort method. initialSort: null, - // By default, shuffle will throttle resize events. This can be changed or // removed. throttle: throttleit, - // How often shuffle can be called on resize (in milliseconds). throttleTime: 300, - // Transition delay offset for each item in milliseconds. staggerAmount: 15, - // Maximum stagger delay in milliseconds. staggerAmountMax: 150, - // Whether to use transforms or absolute positioning. useTransforms: true, - // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With "any", // the element passes the test if any of its groups are in the array. With "all", // the element only passes if all groups are in the array. filterMode: Shuffle.FilterMode.ANY, - // Attempt to center grid items in each row. isCentered: false, - // Whether to round pixel values used in translate(x, y). This usually avoids // blurriness. roundTransforms: true }; - Shuffle.Point = Point; - Shuffle.Rect = Rect; + Shuffle.Rect = Rect; // Expose for testing. Hack at your own risk. - // Expose for testing. Hack at your own risk. Shuffle.__sorter = sorter; Shuffle.__getColumnSpan = getColumnSpan; Shuffle.__getAvailablePositions = getAvailablePositions; diff --git a/dist/shuffle.js.map b/dist/shuffle.js.map index 067ee63..0358220 100644 --- a/dist/shuffle.js.map +++ b/dist/shuffle.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/hyphenate.js","../src/shuffle.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n"],"names":["getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","Object","keys","key","style","removeClasses","position","visibility","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","slice","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","data","shuffle","emit","itemPositions","_getNextPositions","equals","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","parallel","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","allItems","_mergeNewItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","once","find","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/hyphenate.js","../src/shuffle.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n"],"names":["getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","Object","keys","key","style","removeClasses","position","visibility","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","slice","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","data","shuffle","emit","itemPositions","_getNextPositions","equals","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","parallel","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","allItems","_mergeNewItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","once","find","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file diff --git a/dist/shuffle.min.js b/dist/shuffle.min.js index 1547d15..0e4d92b 100644 --- a/dist/shuffle.min.js +++ b/dist/shuffle.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Shuffle=e()}(this,function(){"use strict";function t(){}t.prototype={on:function(t,e,i){var n=this.e||(this.e={});return(n[t]||(n[t]=[])).push({fn:e,ctx:i}),this},once:function(t,e,i){var n=this;function s(){n.off(t,s),e.apply(i,arguments)}return s._=e,this.on(t,s,i)},emit:function(t){for(var e=[].slice.call(arguments,1),i=((this.e||(this.e={}))[t]||[]).slice(),n=0,s=i.length;n=e?l():o=setTimeout(l,e-t)),s};function l(){o=0,r=+new Date,s=t.apply(i,n),i=null,n=null}};function r(){}function l(t){return parseFloat(t)||0}var a=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},u=function(){function t(t,e){for(var i=0;i2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=l(i[e]);return y()||"width"!==e?y()||"height"!==e||(n+=l(i.paddingTop)+l(i.paddingBottom)+l(i.borderTopWidth)+l(i.borderBottomWidth)):n+=l(i.paddingLeft)+l(i.paddingRight)+l(i.borderLeftWidth)+l(i.borderRightWidth),n}var _={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function E(t,e){var i=Object.assign({},_,e),n=Array.from(t),s=!1;return t.length?i.randomize?function(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}(t):("function"==typeof i.by?t.sort(function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0}):"function"==typeof i.compare&&t.sort(i.compare),s?n:(i.reverse&&t.reverse(),t)):[]}var I={},b="transitionend",S=0;function T(t){return!!I[t]&&(I[t].element.removeEventListener(b,I[t].listener),I[t]=null,!0)}function k(t,e){var i=b+(S+=1),n=function(t){t.currentTarget===t.target&&(T(i),e(t))};return t.addEventListener(b,n),I[i]={element:t,listener:n},i}function w(t){return Math.max.apply(Math,t)}function C(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=n-e&&t[s]<=n+e)return s;return 0}function z(t,e){var i={};t.forEach(function(t){i[t.top]?i[t.top].push(t):i[t.top]=[t]});var n=[],s=[],o=[];return Object.keys(i).forEach(function(t){var r=i[t];s.push(r);var l=r[r.length-1],a=l.left+l.width,u=Math.round((e-a)/2),h=r,f=!1;if(u>0){var d=[];(f=r.every(function(t){var e=new c(t.left+u,t.top,t.width,t.height,t.id),i=!n.some(function(t){return c.intersects(e,t)});return d.push(e),i}))&&(h=d)}if(!f){var m=void 0;if(r.some(function(t){return n.some(function(e){var i=c.intersects(t,e);return i&&(m=e),i})})){var p=o.findIndex(function(t){return t.includes(m)});o.splice(p,1,s[p])}}n=n.concat(h),o.push(h)}),[].concat.apply([],o).sort(function(t,e){return t.id-e.id}).map(function(t){return new f(t.left,t.top)})}function M(t){return Array.from(new Set(t))}var A=0,F=function(t){function i(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};a(this,i);var n=h(this,(i.__proto__||Object.getPrototypeOf(i)).call(this));n.options=Object.assign({},i.options,e),n.options.delimeter&&(n.options.delimiter=n.options.delimeter),n.lastSort={},n.group=i.ALL_ITEMS,n.lastFilter=i.ALL_ITEMS,n.isEnabled=!0,n.isDestroyed=!1,n.isInitialized=!1,n._transitions=[],n.isTransitioning=!1,n._queue=[];var s=n._getElementOption(t);if(!s)throw new TypeError("Shuffle needs to be initialized with an element.");return n.element=s,n.id="shuffle_"+A,A+=1,n._init(),n.isInitialized=!0,n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(i,e),u(i,[{key:"_init",value:function(){if(this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(i.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){var t=this.layout.bind(this);window.addEventListener("load",function e(){window.removeEventListener("load",e),t()})}var e=window.getComputedStyle(this.element,null),n=i.getSize(this.element).width;this._validateStyles(e),this._setColumns(n),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition="height "+this.options.speed+"ms "+this.options.easing}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(t,e){var n=this,s=[],o=[];return t===i.ALL_ITEMS?s=e:e.forEach(function(e){n._doesPassFilter(t,e.element)?s.push(e):o.push(e)}),{visible:s,hidden:o}}},{key:"_doesPassFilter",value:function(t,e){if("function"==typeof t)return t.call(e,e,this);var n=e.getAttribute("data-"+i.FILTER_ATTRIBUTE_KEY),s=this.options.delimiter?n.split(this.options.delimiter):JSON.parse(n);function o(t){return s.includes(t)}return Array.isArray(t)?this.options.filterMode===i.FilterMode.ANY?t.some(o):t.every(o):s.includes(t)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach(function(t){t.show()}),i.forEach(function(t){t.hide()})}},{key:"_initItems",value:function(t){t.forEach(function(t){t.init()})}},{key:"_disposeItems",value:function(t){t.forEach(function(t){t.dispose()})}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"setItemTransitions",value:function(t){var e=this.options,i=e.speed,n=e.easing,s=this.options.useTransforms?["transform"]:["top","left"],o=Object.keys(p.Css.HIDDEN.before).map(function(t){return t.replace(/([A-Z])/g,function(t,e){return"-"+e.toLowerCase()})}),r=s.concat(o).join();t.forEach(function(t){t.element.style.transitionDuration=i+"ms",t.element.style.transitionTimingFunction=n,t.element.style.transitionProperty=r})}},{key:"_getItems",value:function(){var t=this;return Array.from(this.element.children).filter(function(e){return s(e,t.options.itemSelector)}).map(function(t){return new p(t)})}},{key:"_mergeNewItems",value:function(t){var e=Array.from(this.element.children);return E(this.items.concat(t),{by:function(t){return e.indexOf(t)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter(function(t){return t.isVisible})}},{key:"_getConcealedItems",value:function(){return this.items.filter(function(t){return!t.isVisible})}},{key:"_getColumnSize",value:function(t,e){var n=void 0;return 0===(n="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?i.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?i.getSize(this.items[0].element,!0).width:t)&&(n=t),n+e}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?g(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:i.getSize(this.element).width,e=this._getGutterSize(t),n=this._getColumnSize(t,e),s=(t+e)/n;Math.abs(Math.round(s)-s)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(t){var e=this,i=this._getNextPositions(t),n=0;t.forEach(function(t,s){function o(){t.applyCss(p.Css.VISIBLE.after)}if(f.equals(t.point,i[s])&&!t.isHidden)return t.applyCss(p.Css.VISIBLE.before),void o();t.point=i[s],t.scale=p.Scale.VISIBLE,t.isHidden=!1;var r=e.getStylesForTransition(t,p.Css.VISIBLE.before);r.transitionDelay=e._getStaggerAmount(n)+"ms",e._queue.push({item:t,styles:r,callback:o}),n+=1})}},{key:"_getNextPositions",value:function(t){var e=this;if(this.options.isCentered){var n=t.map(function(t,n){var s=i.getSize(t.element,!0),o=e._getItemPosition(s);return new c(o.x,o.y,s.width,s.height,n)});return this.getTransformedPositions(n,this.containerWidth)}return t.map(function(t){return e._getItemPosition(i.getSize(t.element,!0))})}},{key:"_getItemPosition",value:function(t){return function(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=C(e.width,n,s,o),a=L(i,l,s),u=D(a,r),h=new f(n*u,a[u]),c=a[u]+e.height,d=0;d0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach(function(e){function n(){e.applyCss(p.Css.HIDDEN.after)}if(e.isHidden)return e.applyCss(p.Css.HIDDEN.before),void n();e.scale=p.Scale.HIDDEN,e.isHidden=!0;var s=t.getStylesForTransition(e,p.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1})}},{key:"_handleResize",value:function(){this.isEnabled&&!this.isDestroyed&&this.update()}},{key:"getStylesForTransition",value:function(t,e){var i=Object.assign({},e);if(this.options.useTransforms){var n=this.options.roundTransforms?Math.round(t.point.x):t.point.x,s=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform="translate("+n+"px, "+s+"px) scale("+t.scale+")"}else i.left=t.point.x+"px",i.top=t.point.y+"px";return i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=k(t,function(t){e(),i(null,t)});this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(t.styles),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatch(i.EventType.LAYOUT)):this._dispatch(i.EventType.LAYOUT),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0,function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=r);var n=t&&t.length;if(!n)return i(null,[]);var s=!1,o=new Array(n);function l(t){return function(e,r){if(!s){if(e)return i(e,o),void(s=!0);o[t]=r,--n||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,l(i))}:function(t,e){t(l(e))})}(t.map(function(t){return e._getTransitionFunction(t)}),this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(T),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(t){if(t.length){var e=t.map(function(t){return t.item.element});i._skipTransitions(e,function(){t.forEach(function(t){t.item.applyCss(t.styles),t.callback()})})}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(i.EventType.LAYOUT)}},{key:"filter",value:function(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=i.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=E(this._getFilteredItems(),t);this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=this,i=M(t).map(function(t){return new p(t)});this._initItems(i),this._resetCols();var n=E(this._mergeNewItems(i),this.lastSort),s=this._filter(this.lastFilter,n),o=function(t){return i.includes(t)},r=function(t){t.scale=p.Scale.HIDDEN,t.isHidden=!0,t.applyCss(p.Css.HIDDEN.before),t.applyCss(p.Css.HIDDEN.after)},l=this._getNextPositions(s.visible);s.visible.forEach(function(t,i){o(t)&&(t.point=l[i],r(t),t.applyCss(e.getStylesForTransition(t,{})))}),s.hidden.forEach(function(t){o(t)&&r(t)}),this.element.offsetWidth,this.setItemTransitions(i),this.items=this._mergeNewItems(i),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}},{key:"remove",value:function(t){var e=this;if(t.length){var n=M(t),s=n.map(function(t){return e.getItemByElement(t)}).filter(function(t){return!!t});this._toggleFilterClasses({visible:[],hidden:s}),this._shrink(s),this.sort(),this.items=this.items.filter(function(t){return!s.includes(t)}),this._updateItemCount(),this.once(i.EventType.LAYOUT,function(){e._disposeItems(s),n.forEach(function(t){t.parentNode.removeChild(t)}),e._dispatch(i.EventType.REMOVED,{collection:n})})}}},{key:"getItemByElement",value:function(t){return this.items.find(function(e){return e.element===t})}},{key:"resetItems",value:function(){var t=this;this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(i.EventType.LAYOUT,function(){t.setItemTransitions(t.items),t.isInitialized=!0}),this.filter(this.lastFilter)}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(this.items),this.items.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}}],[{key:"getSize",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=window.getComputedStyle(t,null),n=g(t,"width",i),s=g(t,"height",i);e&&(n+=g(t,"marginLeft",i)+g(t,"marginRight",i),s+=g(t,"marginTop",i)+g(t,"marginBottom",i));return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map(function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}});e(),t[0].offsetWidth,t.forEach(function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay})}}]),i}();return F.ShuffleItem=p,F.ALL_ITEMS="all",F.FILTER_ATTRIBUTE_KEY="groups",F.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},F.Classes=d,F.FilterMode={ANY:"any",ALL:"all"},F.options={group:F.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimiter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:o,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:F.FilterMode.ANY,isCentered:!1,roundTransforms:!0},F.Point=f,F.Rect=c,F.__sorter=E,F.__getColumnSpan=C,F.__getAvailablePositions=L,F.__getShortColumn=D,F.__getCenteredPositions=z,F}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Shuffle=e()}(this,function(){"use strict";function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var i=0;i=e?l():o=setTimeout(l,e-t)),s};function l(){o=0,r=+new Date,s=t.apply(i,n),i=null,n=null}};function c(){}function d(t){return parseFloat(t)||0}var m=function(){function e(i,n){t(this,e),this.x=d(i),this.y=d(n)}return i(e,null,[{key:"equals",value:function(t,e){return t.x===e.x&&t.y===e.y}}]),e}(),p=function(){function e(i,n,s,o,r){t(this,e),this.id=r,this.left=i,this.top=n,this.width=s,this.height=o}return i(e,null,[{key:"intersects",value:function(t,e){return t.left2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=d(i[e]);return E()||"width"!==e?E()||"height"!==e||(n+=d(i.paddingTop)+d(i.paddingBottom)+d(i.borderTopWidth)+d(i.borderBottomWidth)):n+=d(i.paddingLeft)+d(i.paddingRight)+d(i.borderLeftWidth)+d(i.borderRightWidth),n}var b={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function S(t,e){var i=Object.assign({},b,e),n=Array.from(t),s=!1;return t.length?i.randomize?function(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}(t):("function"==typeof i.by?t.sort(function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0}):"function"==typeof i.compare&&t.sort(i.compare),s?n:(i.reverse&&t.reverse(),t)):[]}var T={},k="transitionend",w=0;function C(t){return!!T[t]&&(T[t].element.removeEventListener(k,T[t].listener),T[t]=null,!0)}function L(t,e){var i=k+(w+=1),n=function(t){t.currentTarget===t.target&&(C(i),e(t))};return t.addEventListener(k,n),T[i]={element:t,listener:n},i}function D(t){return Math.max.apply(Math,t)}function z(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=n-e&&t[s]<=n+e)return s;return 0}function F(t,e){var i={};t.forEach(function(t){i[t.top]?i[t.top].push(t):i[t.top]=[t]});var n=[],s=[],o=[];return Object.keys(i).forEach(function(t){var r=i[t];s.push(r);var l,a=r[r.length-1],u=a.left+a.width,h=Math.round((e-u)/2),f=r,c=!1;if(h>0){var d=[];(c=r.every(function(t){var e=new p(t.left+h,t.top,t.width,t.height,t.id),i=!n.some(function(t){return p.intersects(e,t)});return d.push(e),i}))&&(f=d)}if(!c&&r.some(function(t){return n.some(function(e){var i=p.intersects(t,e);return i&&(l=e),i})})){var m=o.findIndex(function(t){return t.includes(l)});o.splice(m,1,s[m])}n=n.concat(f),o.push(f)}),[].concat.apply([],o).sort(function(t,e){return t.id-e.id}).map(function(t){return new m(t.left,t.top)})}function x(t){return Array.from(new Set(t))}var O=0,N=function(e){function r(e){var i,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,r),(i=o(this,n(r).call(this))).options=Object.assign({},r.options,s),i.options.delimeter&&(i.options.delimiter=i.options.delimeter),i.lastSort={},i.group=r.ALL_ITEMS,i.lastFilter=r.ALL_ITEMS,i.isEnabled=!0,i.isDestroyed=!1,i.isInitialized=!1,i._transitions=[],i.isTransitioning=!1,i._queue=[];var l=i._getElementOption(e);if(!l)throw new TypeError("Shuffle needs to be initialized with an element.");return i.element=l,i.id="shuffle_"+O,O+=1,i._init(),i.isInitialized=!0,i}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&s(t,e)}(r,l),i(r,[{key:"_init",value:function(){if(this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(r.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){var t=this.layout.bind(this);window.addEventListener("load",function e(){window.removeEventListener("load",e),t()})}var e=window.getComputedStyle(this.element,null),i=r.getSize(this.element).width;this._validateStyles(e),this._setColumns(i),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition="height ".concat(this.options.speed,"ms ").concat(this.options.easing)}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(t,e){var i=this,n=[],s=[];return t===r.ALL_ITEMS?n=e:e.forEach(function(e){i._doesPassFilter(t,e.element)?n.push(e):s.push(e)}),{visible:n,hidden:s}}},{key:"_doesPassFilter",value:function(t,e){if("function"==typeof t)return t.call(e,e,this);var i=e.getAttribute("data-"+r.FILTER_ATTRIBUTE_KEY),n=this.options.delimiter?i.split(this.options.delimiter):JSON.parse(i);function s(t){return n.includes(t)}return Array.isArray(t)?this.options.filterMode===r.FilterMode.ANY?t.some(s):t.every(s):n.includes(t)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach(function(t){t.show()}),i.forEach(function(t){t.hide()})}},{key:"_initItems",value:function(t){t.forEach(function(t){t.init()})}},{key:"_disposeItems",value:function(t){t.forEach(function(t){t.dispose()})}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"setItemTransitions",value:function(t){var e=this.options,i=e.speed,n=e.easing,s=this.options.useTransforms?["transform"]:["top","left"],o=Object.keys(g.Css.HIDDEN.before).map(function(t){return t.replace(/([A-Z])/g,function(t,e){return"-".concat(e.toLowerCase())})}),r=s.concat(o).join();t.forEach(function(t){t.element.style.transitionDuration=i+"ms",t.element.style.transitionTimingFunction=n,t.element.style.transitionProperty=r})}},{key:"_getItems",value:function(){var t=this;return Array.from(this.element.children).filter(function(e){return h(e,t.options.itemSelector)}).map(function(t){return new g(t)})}},{key:"_mergeNewItems",value:function(t){var e=Array.from(this.element.children);return S(this.items.concat(t),{by:function(t){return e.indexOf(t)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter(function(t){return t.isVisible})}},{key:"_getConcealedItems",value:function(){return this.items.filter(function(t){return!t.isVisible})}},{key:"_getColumnSize",value:function(t,e){var i;return 0===(i="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?r.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?r.getSize(this.items[0].element,!0).width:t)&&(i=t),i+e}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?I(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:r.getSize(this.element).width,e=this._getGutterSize(t),i=this._getColumnSize(t,e),n=(t+e)/i;Math.abs(Math.round(n)-n)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(t){var e=this,i=this._getNextPositions(t),n=0;t.forEach(function(t,s){function o(){t.applyCss(g.Css.VISIBLE.after)}if(m.equals(t.point,i[s])&&!t.isHidden)return t.applyCss(g.Css.VISIBLE.before),void o();t.point=i[s],t.scale=g.Scale.VISIBLE,t.isHidden=!1;var r=e.getStylesForTransition(t,g.Css.VISIBLE.before);r.transitionDelay=e._getStaggerAmount(n)+"ms",e._queue.push({item:t,styles:r,callback:o}),n+=1})}},{key:"_getNextPositions",value:function(t){var e=this;if(this.options.isCentered){var i=t.map(function(t,i){var n=r.getSize(t.element,!0),s=e._getItemPosition(n);return new p(s.x,s.y,n.width,n.height,i)});return this.getTransformedPositions(i,this.containerWidth)}return t.map(function(t){return e._getItemPosition(r.getSize(t.element,!0))})}},{key:"_getItemPosition",value:function(t){return function(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=z(e.width,n,s,o),a=M(i,l,s),u=A(a,r),h=new m(n*u,a[u]),f=a[u]+e.height,c=0;c0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach(function(e){function n(){e.applyCss(g.Css.HIDDEN.after)}if(e.isHidden)return e.applyCss(g.Css.HIDDEN.before),void n();e.scale=g.Scale.HIDDEN,e.isHidden=!0;var s=t.getStylesForTransition(e,g.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1})}},{key:"_handleResize",value:function(){this.isEnabled&&!this.isDestroyed&&this.update()}},{key:"getStylesForTransition",value:function(t,e){var i=Object.assign({},e);if(this.options.useTransforms){var n=this.options.roundTransforms?Math.round(t.point.x):t.point.x,s=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform="translate(".concat(n,"px, ").concat(s,"px) scale(").concat(t.scale,")")}else i.left=t.point.x+"px",i.top=t.point.y+"px";return i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=L(t,function(t){e(),i(null,t)});this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(t.styles),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatch(r.EventType.LAYOUT)):this._dispatch(r.EventType.LAYOUT),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0,function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=c);var n=t&&t.length;if(!n)return i(null,[]);var s=!1,o=new Array(n);function r(t){return function(e,r){if(!s){if(e)return i(e,o),void(s=!0);o[t]=r,--n||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,r(i))}:function(t,e){t(r(e))})}(t.map(function(t){return e._getTransitionFunction(t)}),this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(C),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(t){if(t.length){var e=t.map(function(t){return t.item.element});r._skipTransitions(e,function(){t.forEach(function(t){t.item.applyCss(t.styles),t.callback()})})}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(r.EventType.LAYOUT)}},{key:"filter",value:function(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=r.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=S(this._getFilteredItems(),t);this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=this,i=x(t).map(function(t){return new g(t)});this._initItems(i),this._resetCols();var n=S(this._mergeNewItems(i),this.lastSort),s=this._filter(this.lastFilter,n),o=function(t){return i.includes(t)},r=function(t){t.scale=g.Scale.HIDDEN,t.isHidden=!0,t.applyCss(g.Css.HIDDEN.before),t.applyCss(g.Css.HIDDEN.after)},l=this._getNextPositions(s.visible);s.visible.forEach(function(t,i){o(t)&&(t.point=l[i],r(t),t.applyCss(e.getStylesForTransition(t,{})))}),s.hidden.forEach(function(t){o(t)&&r(t)}),this.element.offsetWidth,this.setItemTransitions(i),this.items=this._mergeNewItems(i),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}},{key:"remove",value:function(t){var e=this;if(t.length){var i=x(t),n=i.map(function(t){return e.getItemByElement(t)}).filter(function(t){return!!t});this._toggleFilterClasses({visible:[],hidden:n}),this._shrink(n),this.sort(),this.items=this.items.filter(function(t){return!n.includes(t)}),this._updateItemCount(),this.once(r.EventType.LAYOUT,function(){e._disposeItems(n),i.forEach(function(t){t.parentNode.removeChild(t)}),e._dispatch(r.EventType.REMOVED,{collection:i})})}}},{key:"getItemByElement",value:function(t){return this.items.find(function(e){return e.element===t})}},{key:"resetItems",value:function(){var t=this;this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(r.EventType.LAYOUT,function(){t.setItemTransitions(t.items),t.isInitialized=!0}),this.filter(this.lastFilter)}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(this.items),this.items.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}}],[{key:"getSize",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=window.getComputedStyle(t,null),n=I(t,"width",i),s=I(t,"height",i);e&&(n+=I(t,"marginLeft",i)+I(t,"marginRight",i),s+=I(t,"marginTop",i)+I(t,"marginBottom",i));return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map(function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}});e(),t[0].offsetWidth,t.forEach(function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay})}}]),r}();return N.ShuffleItem=g,N.ALL_ITEMS="all",N.FILTER_ATTRIBUTE_KEY="groups",N.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},N.Classes=v,N.FilterMode={ANY:"any",ALL:"all"},N.options={group:N.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimiter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:f,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:N.FilterMode.ANY,isCentered:!1,roundTransforms:!0},N.Point=m,N.Rect=p,N.__sorter=S,N.__getColumnSpan=z,N.__getAvailablePositions=M,N.__getShortColumn=A,N.__getCenteredPositions=F,N}); //# sourceMappingURL=shuffle.min.js.map diff --git a/dist/shuffle.min.js.map b/dist/shuffle.min.js.map index b2396b1..ff8bd84 100644 --- a/dist/shuffle.min.js.map +++ b/dist/shuffle.min.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.min.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/layout.js","../src/array-min.js","../src/shuffle.js","../src/hyphenate.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","proto","Element","vendor","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","el","selector","nodeType","nodes","parentNode","querySelectorAll","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","HIDDEN","add","VISIBLE","removeAttribute","setAttribute","addClasses","SHUFFLE_ITEM","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","keys","key","style","removeClasses","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","sorter","arr","options","opts","Object","assign","original","Array","from","revert","randomize","array","n","Math","floor","random","temp","by","sort","valA","valB","undefined","compare","reverse","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","_this","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","TinyEmitter","_getItems","sizer","BASE","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_this2","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","before","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","_this3","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","shuffle","itemPositions","_getNextPositions","after","equals","_this4","getStylesForTransition","transitionDelay","_getStaggerAmount","isCentered","itemsData","itemSize","_this5","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_getConcealedItems","_this6","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","_this8","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","sortedItems","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","_this9","isUpdateLayout","oldItems","_this10","getItemByElement","_disposeItems","REMOVED","find","_this11","includeMargins","duration","delay","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.min.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/layout.js","../src/array-min.js","../src/shuffle.js","../src/hyphenate.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","proto","Element","vendor","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","el","selector","nodeType","nodes","parentNode","querySelectorAll","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","_this","_this2","obj","Object","keys","key","_this3","style","removeClasses","position","visibility","before","opacity","after","transitionDelay","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","reverse","by","compare","randomize","sorter","arr","options","opts","assign","original","Array","from","revert","array","n","Math","floor","random","temp","sort","valA","valB","undefined","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","intersectingRect","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","TinyEmitter","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","shuffle","itemPositions","_getNextPositions","equals","_this4","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","itemSize","_this5","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_getConcealedItems","_this6","update","styleObject","roundTransforms","transform","itemCallback","done","_this7","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","parallel","_this8","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","sortedItems","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","_this9","isUpdateLayout","oldItems","_this10","getItemByElement","_disposeItems","REMOVED","find","_this11","includeMargins","duration","delay","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"+4BAAA,SAASA,KAKTA,EAAEC,UAAY,CACZC,GAAI,SAAUC,EAAMC,EAAUC,GAC5B,IAAIC,EAAIC,KAAKD,IAAMC,KAAKD,EAAI,IAO5B,OALCA,EAAEH,KAAUG,EAAEH,GAAQ,KAAKK,KAAK,CAC/BC,GAAIL,EACJC,IAAKA,IAGAE,MAGTG,KAAM,SAAUP,EAAMC,EAAUC,GAC9B,IAAIM,EAAOJ,KACX,SAASK,IACPD,EAAKE,IAAIV,EAAMS,GACfR,EAASU,MAAMT,EAAKU,WAItB,OADAH,EAASI,EAAIZ,EACNG,KAAKL,GAAGC,EAAMS,EAAUP,IAGjCY,KAAM,SAAUd,GAMd,IALA,IAAIe,EAAO,GAAGC,MAAMC,KAAKL,UAAW,GAChCM,IAAWd,KAAKD,IAAMC,KAAKD,EAAI,KAAKH,IAAS,IAAIgB,QACjDG,EAAI,EACJC,EAAMF,EAAOG,OAETF,EAAIC,EAAKD,IACfD,EAAOC,GAAGb,GAAGK,MAAMO,EAAOC,GAAGjB,IAAKa,GAGpC,OAAOX,MAGTM,IAAK,SAAUV,EAAMC,GACnB,IAAIE,EAAIC,KAAKD,IAAMC,KAAKD,EAAI,IACxBmB,EAAOnB,EAAEH,GACTuB,EAAa,GAEjB,GAAID,GAAQrB,EACV,IAAK,IAAIkB,EAAI,EAAGC,EAAME,EAAKD,OAAQF,EAAIC,EAAKD,IACtCG,EAAKH,GAAGb,KAAOL,GAAYqB,EAAKH,GAAGb,GAAGO,IAAMZ,GAC9CsB,EAAWlB,KAAKiB,EAAKH,IAY3B,OAJCI,EAAiB,OACdpB,EAAEH,GAAQuB,SACHpB,EAAEH,GAENI,OAIX,MAAiBP,EC/Db2B,EAA2B,oBAAZC,QAA0BA,QAAQ3B,UAAY,GAC7D4B,EAASF,EAAMG,SACdH,EAAMI,iBACNJ,EAAMK,uBACNL,EAAMM,oBACNN,EAAMO,mBACNP,EAAMQ,mBAaX,SAAeC,EAAIC,GACjB,IAAKD,GAAsB,IAAhBA,EAAGE,SAAgB,OAAO,EACrC,GAAIT,EAAQ,OAAOA,EAAOT,KAAKgB,EAAIC,GAEnC,IADA,IAAIE,EAAQH,EAAGI,WAAWC,iBAAiBJ,GAClCf,EAAI,EAAGA,EAAIiB,EAAMf,OAAQF,IAChC,GAAIiB,EAAMjB,IAAMc,EAAI,OAAO,EAE7B,OAAO,GC5BT,MAUA,SAAmBM,EAAMC,GACvB,IAAItC,EAAKuC,EAAMC,EAAKC,EAChBC,EAAO,EAEX,OAAO,WACL1C,EAAME,KACNqC,EAAO7B,UACP,IAAIiC,EAAQ,IAAIC,KAASF,EAIzB,OAHKD,IACCE,GAASL,EAAMvB,IACd0B,EAAYI,WAAW9B,EAAMuB,EAAOK,IACpCH,GAGT,SAASzB,IACP0B,EAAY,EACZC,GAAQ,IAAIE,KACZJ,EAAMH,EAAK5B,MAAMT,EAAKuC,GACtBvC,EAAM,KACNuC,EAAO,OCUX,SAASO,KClCM,SAASC,EAAUC,UACzBC,WAAWD,IAAU,MCJxBE,wBAMQC,EAAGC,kBACRD,EAAIJ,EAAUI,QACdC,EAAIL,EAAUK,iDASPC,EAAGC,UACRD,EAAEF,IAAMG,EAAEH,GAAKE,EAAED,IAAME,EAAEF,WCpBfG,wBAWPJ,EAAGC,EAAGI,EAAGC,EAAGC,kBACjBA,GAAKA,OAGLC,KAAOR,OAGPS,IAAMR,OAGNS,MAAQL,OAGRM,OAASL,oDASEJ,EAAGC,UAEjBD,EAAEM,KAAOL,EAAEK,KAAOL,EAAEO,OAASP,EAAEK,KAAON,EAAEM,KAAON,EAAEQ,OACjDR,EAAEO,IAAMN,EAAEM,IAAMN,EAAEQ,QAAUR,EAAEM,IAAMP,EAAEO,IAAMP,EAAES,kBCpCrC,CACbC,KAAM,UACNC,aAAc,eACdC,QAAS,wBACTC,OAAQ,wBCDNR,EAAK,EAEHS,wBACQC,aACVV,GAAM,OACDA,GAAKA,OACLU,QAAUA,OAKVC,WAAY,OAQZC,UAAW,gDAIXD,WAAY,OACZD,QAAQG,UAAUC,OAAOC,EAAQP,aACjCE,QAAQG,UAAUG,IAAID,EAAQR,cAC9BG,QAAQO,gBAAgB,mDAIxBN,WAAY,OACZD,QAAQG,UAAUC,OAAOC,EAAQR,cACjCG,QAAQG,UAAUG,IAAID,EAAQP,aAC9BE,QAAQQ,aAAa,eAAe,uCAIpCC,WAAW,CAACJ,EAAQT,aAAcS,EAAQR,eAC1Ca,SAASX,EAAYY,IAAIC,cACzBC,MAAQd,EAAYe,MAAMjB,aAC1BkB,MAAQ,IAAIjC,qCAGRkC,cACTA,EAAQC,QAAQ,SAACC,GACfC,EAAKnB,QAAQG,UAAUG,IAAIY,2CAIjBF,cACZA,EAAQC,QAAQ,SAACC,GACfE,EAAKpB,QAAQG,UAAUC,OAAOc,sCAIzBG,cACPC,OAAOC,KAAKF,GAAKJ,QAAQ,SAACO,GACxBC,EAAKzB,QAAQ0B,MAAMF,GAAOH,EAAIG,4CAK3BG,cAAc,CACjBtB,EAAQP,OACRO,EAAQR,QACRQ,EAAQT,oBAGLI,QAAQO,gBAAgB,cACxBP,QAAU,cAInBD,EAAYY,IAAM,CAChBC,QAAS,CACPgB,SAAU,WACVpC,IAAK,EACLD,KAAM,EACNsC,WAAY,wBACG,aAEjBhC,QAAS,CACPiC,OAAQ,CACNC,QAAS,EACTF,WAAY,WAEdG,MAAO,CACLC,gBAAiB,KAGrBnC,OAAQ,CACNgC,OAAQ,CACNC,QAAS,GAEXC,MAAO,CACLH,WAAY,SACZI,gBAAiB,MAKvBlC,EAAYe,MAAQ,CAClBjB,QAAS,EACTC,OAAQ,MC1GV,IAAIlB,EAAQ,qBAEI,OAAVA,SACKA,MAGHoB,EAAUkC,SAASC,MAAQD,SAASE,gBACpCvG,EAAIqG,SAASG,cAAc,cACjCxG,EAAE6F,MAAMY,QAAU,gDAClBtC,EAAQuC,YAAY1G,GAEpB+C,EAAmD,SAA3C4D,OAAOC,iBAAiB5G,EAAG,MAAM4D,MAEzCO,EAAQ0C,YAAY7G,GAEb+C,GCFM,SAAS+D,EACtB3C,EAAS0B,OACTkB,yDAASJ,OAAOC,iBAAiBzC,EAAS,MAEtCpB,EAAQD,EAAUiE,EAAOlB,WAGxBmB,KAAgC,UAAVnB,EAKfmB,KAAgC,WAAVnB,IAChC9C,GAASD,EAAUiE,EAAOE,YACxBnE,EAAUiE,EAAOG,eACjBpE,EAAUiE,EAAOI,gBACjBrE,EAAUiE,EAAOK,oBARnBrE,GAASD,EAAUiE,EAAOM,aACxBvE,EAAUiE,EAAOO,cACjBxE,EAAUiE,EAAOQ,iBACjBzE,EAAUiE,EAAOS,kBAQdzE,ECXT,IAAM0E,EAAW,CAEfC,SAAS,EAGTC,GAAI,KAGJC,QAAS,KAGTC,WAAW,EAIXlC,IAAK,WAIQ,SAASmC,EAAOC,EAAKC,OAC5BC,EAAOxC,OAAOyC,OAAO,GAAIT,EAAUO,GACnCG,EAAWC,MAAMC,KAAKN,GACxBO,GAAS,SAERP,EAAI7G,OAIL+G,EAAKJ,UA1CX,SAAmBU,WACbC,EAAID,EAAMrH,OAEPsH,GAAG,CACRA,GAAK,MACCxH,EAAIyH,KAAKC,MAAMD,KAAKE,UAAYH,EAAI,IACpCI,EAAOL,EAAMvH,GACnBuH,EAAMvH,GAAKuH,EAAMC,GACjBD,EAAMC,GAAKI,SAGNL,EAgCEV,CAAUE,IAKI,mBAAZE,EAAKN,GACdI,EAAIc,KAAK,SAACzF,EAAGC,MAEPiF,SACK,MAGHQ,EAAOb,EAAKN,GAAGvE,EAAE6E,EAAKtC,MACtBoD,EAAOd,EAAKN,GAAGtE,EAAE4E,EAAKtC,kBAGfqD,IAATF,QAA+BE,IAATD,GACxBT,GAAS,EACF,GAGLQ,EAAOC,GAAiB,cAATD,GAAiC,aAATC,GACjC,EAGND,EAAOC,GAAiB,aAATD,GAAgC,cAATC,EACjC,EAGF,IAEwB,mBAAjBd,EAAKL,SACrBG,EAAIc,KAAKZ,EAAKL,SAIZU,EACKH,GAGLF,EAAKP,SACPK,EAAIL,UAGCK,IAhDE,GC9CX,IAAMkB,EAAc,GACdC,EAAY,gBACdC,EAAQ,EAOL,SAASC,EAAoB3F,WAC9BwF,EAAYxF,KACdwF,EAAYxF,GAAIU,QAAQkF,oBAAoBH,EAAWD,EAAYxF,GAAInD,UACvE2I,EAAYxF,GAAM,MACX,GAMJ,SAAS6F,EAAgBnF,EAASrE,OACjC2D,EAdCyF,GADPC,GAAS,GAgBH7I,EAAW,SAACiJ,GACZA,EAAIC,gBAAkBD,EAAIE,SAC5BL,EAAoB3F,GACpB3D,EAASyJ,YAIbpF,EAAQuF,iBAAiBR,EAAW5I,GAEpC2I,EAAYxF,GAAM,CAAEU,QAAAA,EAAS7D,SAAAA,GAEtBmD,EChCM,SAASkG,EAASpB,UACxBE,KAAKmB,IAAIpJ,MAAMiI,KAAMF,GCYvB,SAASsB,EAAcC,EAAWC,EAAaC,EAASC,OACzDC,EAAaJ,EAAYC,SAKzBtB,KAAK0B,IAAI1B,KAAK2B,MAAMF,GAAcA,GAAcD,IAElDC,EAAazB,KAAK2B,MAAMF,IAInBzB,KAAK4B,IAAI5B,KAAK6B,KAAKJ,GAAaF,GASlC,SAASO,EAAsBC,EAAWN,EAAYF,MAExC,IAAfE,SACKM,UAyBHC,EAAY,GAGTzJ,EAAI,EAAGA,GAAKgJ,EAAUE,EAAYlJ,IAEzCyJ,EAAUvK,KAAKyJ,EAASa,EAAU3J,MAAMG,EAAGA,EAAIkJ,YAG1CO,EAWF,SAASC,EAAeF,EAAWG,WCjFTpC,EDkFzBqC,GClFyBrC,EDkFFiC,ECjFtB/B,KAAK4B,IAAI7J,MAAMiI,KAAMF,IDkFnBvH,EAAI,EAAGC,EAAMuJ,EAAUtJ,OAAQF,EAAIC,EAAKD,OAC3CwJ,EAAUxJ,IAAM4J,EAAcD,GAAUH,EAAUxJ,IAAM4J,EAAcD,SACjE3J,SAIJ,EA0CF,SAAS6J,EAAqBC,EAAWC,OACxCC,EAAS,GAKfF,EAAU1F,QAAQ,SAAC6F,GACbD,EAAOC,EAAStH,KAElBqH,EAAOC,EAAStH,KAAKzD,KAAK+K,GAG1BD,EAAOC,EAAStH,KAAO,CAACsH,SAOxBC,EAAQ,GACNC,EAAO,GACPC,EAAe,UACrB3F,OAAOC,KAAKsF,GAAQ5F,QAAQ,SAACO,OACrBmF,EAAYE,EAAOrF,GACzBwF,EAAKjL,KAAK4K,OA6BJO,EA5BAC,EAAWR,EAAUA,EAAU5J,OAAS,GACxCqK,EAAMD,EAAS5H,KAAO4H,EAAS1H,MAC/B4H,EAAS/C,KAAK2B,OAAOW,EAAiBQ,GAAO,GAE/CE,EAAaX,EACbY,GAAU,KACVF,EAAS,EAAG,KACRG,EAAW,IACjBD,EAAUZ,EAAUc,MAAM,SAACC,OACnBC,EAAU,IAAIxI,EAAKuI,EAAEnI,KAAO8H,EAAQK,EAAElI,IAAKkI,EAAEjI,MAAOiI,EAAEhI,OAAQgI,EAAEpI,IAGhEsI,GAAab,EAAMc,KAAK,SAAAH,UAAKvI,EAAK2I,WAAWH,EAASD,YAE5DF,EAASzL,KAAK4L,GACPC,OAKPN,EAAaE,OAOZD,GAEgBZ,EAAUkB,KAAK,SAAAf,UAAYC,EAAMc,KAAK,SAACH,OAClDI,EAAa3I,EAAK2I,WAAWhB,EAAUY,UACzCI,IACFZ,EAAmBQ,GAEdI,MAIO,KACRC,EAAWd,EAAae,UAAU,SAAAC,UAASA,EAAMC,SAAShB,KAChED,EAAakB,OAAOJ,EAAU,EAAGf,EAAKe,IAI1ChB,EAAQA,EAAMqB,OAAOd,GACrBL,EAAalL,KAAKuL,KAOb,GAAGc,OAAO/L,MAAM,GAAI4K,GACxBvC,KAAK,SAACzF,EAAGC,UAAOD,EAAEK,GAAKJ,EAAEI,KACzB+I,IAAI,SAAAvB,UAAY,IAAIhI,EAAMgI,EAASvH,KAAMuH,EAAStH,OE5LvD,SAAS8I,EAAYvJ,UACZkF,MAAMC,KAAK,IAAIqE,IAAIxJ,IAI5B,IAAIO,EAAK,EAEHkJ,yBAQQxI,SAAS6D,yDAAU,yCAExBA,QAAUvC,OAAOyC,OAAO,GAAIyE,EAAQ3E,QAASA,GAI9C1C,EAAK0C,QAAQ4E,cACV5E,QAAQ6E,UAAYvH,EAAK0C,QAAQ4E,aAGnCE,SAAW,KACXC,MAAQJ,EAAQK,YAChBC,WAAaN,EAAQK,YACrBE,WAAY,IACZC,aAAc,IACdC,eAAgB,IAChBC,aAAe,KACfC,iBAAkB,IAClBC,OAAS,OAERzL,EAAKwD,EAAKkI,kBAAkBrJ,OAE7BrC,QACG,IAAI2L,UAAU,6DAGjBtJ,QAAUrC,IACV2B,GAAK,WAAaA,EACvBA,GAAM,IAEDiK,UACAN,eAAgB,gPAvCHO,8CA2CbvB,MAAQnM,KAAK2N,iBAEb5F,QAAQ6F,MAAQ5N,KAAKuN,kBAAkBvN,KAAK+H,QAAQ6F,YAGpD1J,QAAQG,UAAUG,IAAIkI,EAAQnI,QAAQV,WAGtCgK,WAAW7N,KAAKmM,YAGhB2B,UAAY9N,KAAK+N,qBACtBrH,OAAO+C,iBAAiB,SAAUzJ,KAAK8N,WAKX,aAAxB1H,SAAS4H,WAA2B,KAChCC,EAASjO,KAAKiO,OAAOC,KAAKlO,MAChC0G,OAAO+C,iBAAiB,OAAQ,SAAS0E,IACvCzH,OAAO0C,oBAAoB,OAAQ+E,GACnCF,UAKEG,EAAe1H,OAAOC,iBAAiB3G,KAAKkE,QAAS,MACrD4G,EAAiB4B,EAAQ2B,QAAQrO,KAAKkE,SAASP,WAGhD2K,gBAAgBF,QAIhBG,YAAYzD,QAGZ0D,OAAOxO,KAAK+H,QAAQ+E,MAAO9M,KAAK+H,QAAQ0G,kBAMxCvK,QAAQwK,iBACRC,mBAAmB3O,KAAKmM,YACxBjI,QAAQ0B,MAAMgJ,4BAAuB5O,KAAK+H,QAAQ8G,oBAAW7O,KAAK+H,QAAQ+G,yDASzEC,EAAiB/O,KAAKgP,cAAcd,KAAKlO,aACxCA,KAAK+H,QAAQkH,SAClBjP,KAAK+H,QAAQkH,SAASF,EAAgB/O,KAAK+H,QAAQmH,cACnDH,4CAScI,SAGM,iBAAXA,EACFnP,KAAKkE,QAAQkL,cAAcD,GAGzBA,GAAUA,EAAOpN,UAAgC,IAApBoN,EAAOpN,SACtCoN,EAGEA,GAAUA,EAAOE,OACnBF,EAAO,GAGT,6CAQOrI,GAEU,WAApBA,EAAOhB,gBACJ5B,QAAQ0B,MAAME,SAAW,YAIR,WAApBgB,EAAOwI,gBACJpL,QAAQ0B,MAAM0J,SAAW,gDAa1BC,yDAAWvP,KAAKgN,WAAYwC,yDAAaxP,KAAKmM,MAC9CsD,EAAMzP,KAAK0P,iBAAiBH,EAAUC,eAGvCG,qBAAqBF,QAGrBzC,WAAauC,EAIM,iBAAbA,SACJzC,MAAQyC,GAGRE,2CAUQF,EAAUpD,cACrByD,EAAU,GACRC,EAAS,UAGXN,IAAa7C,EAAQK,UACvB6C,EAAUzD,EAKVA,EAAMhH,QAAQ,SAAC2K,GACTxK,EAAKyK,gBAAgBR,EAAUO,EAAK5L,SACtC0L,EAAQ3P,KAAK6P,GAEbD,EAAO5P,KAAK6P,KAKX,CACLF,QAAAA,EACAC,OAAAA,2CAWYN,EAAUrL,MACA,mBAAbqL,SACFA,EAAS1O,KAAKqD,EAASA,EAASlE,UAInCgQ,EAAO9L,EAAQ+L,aAAa,QAAUvD,EAAQwD,sBAC9CzK,EAAOzF,KAAK+H,QAAQ6E,UACxBoD,EAAKG,MAAMnQ,KAAK+H,QAAQ6E,WACxBwD,KAAKC,MAAML,YAEJM,EAAaf,UACb9J,EAAK2G,SAASmD,UAGnBpH,MAAMoI,QAAQhB,GACZvP,KAAK+H,QAAQyI,aAAe9D,EAAQ+D,WAAWC,IAC1CnB,EAASxD,KAAKuE,GAEhBf,EAAS5D,MAAM2E,GAGjB7K,EAAK2G,SAASmD,uDAQAK,IAAAA,QAASC,IAAAA,OAC9BD,EAAQzK,QAAQ,SAAC2K,GACfA,EAAKa,SAGPd,EAAO1K,QAAQ,SAAC2K,GACdA,EAAKc,4CASEzE,GACTA,EAAMhH,QAAQ,SAAC2K,GACbA,EAAKe,+CASK1E,GACZA,EAAMhH,QAAQ,SAAC2K,GACbA,EAAKgB,4DASFC,aAAe/Q,KAAKgR,oBAAoB/P,kDAU5BkL,SACSnM,KAAK+H,QAAvB8G,IAAAA,MAAOC,IAAAA,OACTmC,EAAgBjR,KAAK+H,QAAQmJ,cAAgB,CAAC,aAAe,CAAC,MAAO,QAIrEC,EAAW3L,OAAOC,KAAKxB,EAAYY,IAAIb,OAAOgC,QAAQuG,IAAI,SAAA6E,UAAeA,EC5TtEC,QAAQ,WAAY,SAACC,EAAKC,oBAAWA,EAAGC,mBD6T3CC,EAAaR,EAAc3E,OAAO6E,GAAUO,OAElDvF,EAAMhH,QAAQ,SAAC2K,GACbA,EAAK5L,QAAQ0B,MAAM+L,mBAAqB9C,EAAQ,KAChDiB,EAAK5L,QAAQ0B,MAAMgM,yBAA2B9C,EAC9CgB,EAAK5L,QAAQ0B,MAAMiM,mBAAqBJ,0DAKnCtJ,MAAMC,KAAKpI,KAAKkE,QAAQ4N,UAC5BtD,OAAO,SAAA3M,UAAMN,EAAQM,EAAI8D,EAAKoC,QAAQgK,gBACtCxF,IAAI,SAAA1K,UAAM,IAAIoC,EAAYpC,4CAQhBsK,OACP2F,EAAW3J,MAAMC,KAAKpI,KAAKkE,QAAQ4N,iBAClCjK,EAAO7H,KAAKmM,MAAMG,OAAOH,GAAQ,CACtCzE,YAAGxD,UACM4N,EAASE,QAAQ9N,yDAMrBlE,KAAKmM,MAAMqC,OAAO,SAAAsB,UAAQA,EAAK3L,gEAI/BnE,KAAKmM,MAAMqC,OAAO,SAAAsB,UAASA,EAAK3L,mDAU1B2G,EAAgBmH,OACzBC,SAwBS,KApBXA,EADsC,mBAA7BlS,KAAK+H,QAAQ+B,YACf9J,KAAK+H,QAAQ+B,YAAYgB,GAGvB9K,KAAK+H,QAAQ6F,MACflB,EAAQ2B,QAAQrO,KAAK+H,QAAQ6F,OAAOjK,MAGlC3D,KAAK+H,QAAQ+B,YACf9J,KAAK+H,QAAQ+B,YAGX9J,KAAKmM,MAAMlL,OAAS,EACtByL,EAAQ2B,QAAQrO,KAAKmM,MAAM,GAAGjI,SAAS,GAAMP,MAI7CmH,KAKPoH,EAAOpH,GAGFoH,EAAOD,yCASDnH,SAE2B,mBAA7B9K,KAAK+H,QAAQoK,YACfnS,KAAK+H,QAAQoK,YAAYrH,GACvB9K,KAAK+H,QAAQ6F,MACf/G,EAAe7G,KAAK+H,QAAQ6F,MAAO,cAEnC5N,KAAK+H,QAAQoK,sDAWZrH,yDAAiB4B,EAAQ2B,QAAQrO,KAAKkE,SAASP,MACnDyO,EAASpS,KAAKqS,eAAevH,GAC7BhB,EAAc9J,KAAKsS,eAAexH,EAAgBsH,GACpDG,GAAqBzH,EAAiBsH,GAAUtI,EAGhDtB,KAAK0B,IAAI1B,KAAK2B,MAAMoI,GAAqBA,GACzCvS,KAAK+H,QAAQyK,kBAEfD,EAAoB/J,KAAK2B,MAAMoI,SAG5BE,KAAOjK,KAAKmB,IAAInB,KAAKC,MAAM8J,GAAoB,QAC/CzH,eAAiBA,OACjB4H,SAAW5I,mDAOX5F,QAAQ0B,MAAMhC,OAAS5D,KAAK2S,oBAAsB,wDAShDjJ,EAAS1J,KAAKuK,qDAQLqI,UACTpK,KAAK4B,IAAIwI,EAAQ5S,KAAK+H,QAAQ8K,cAAe7S,KAAK+H,QAAQ+K,oDAQzDlT,OAAMe,yDAAO,GACjBX,KAAKkN,cAITvM,EAAKoS,QAAU/S,UACVU,KAAKd,EAAMe,6CAQZI,EAAIf,KAAKyS,cACRlI,UAAY,GACVxJ,GACLA,GAAK,OACAwJ,UAAUtK,KAAK,mCAShBkM,cACA6G,EAAgBhT,KAAKiT,kBAAkB9G,GAEzCjD,EAAQ,EACZiD,EAAMhH,QAAQ,SAAC2K,EAAM/O,YACVlB,IACPiQ,EAAKlL,SAASX,EAAYY,IAAId,QAAQmC,UAKpClD,EAAMkQ,OAAOpD,EAAK7K,MAAO+N,EAAcjS,MAAQ+O,EAAK1L,gBACtD0L,EAAKlL,SAASX,EAAYY,IAAId,QAAQiC,aACtCnG,IAIFiQ,EAAK7K,MAAQ+N,EAAcjS,GAC3B+O,EAAK/K,MAAQd,EAAYe,MAAMjB,QAC/B+L,EAAK1L,UAAW,MAIV0C,EAASqM,EAAKC,uBAAuBtD,EAAM7L,EAAYY,IAAId,QAAQiC,QACzEc,EAAOX,gBAAkBgN,EAAKE,kBAAkBnK,GAAS,KAEzDiK,EAAK7F,OAAOrN,KAAK,CACf6P,KAAAA,EACAhJ,OAAAA,EACAjH,SAAAA,IAGFqJ,GAAS,8CAWKiD,iBAGZnM,KAAK+H,QAAQuL,WAAY,KACrBC,EAAYpH,EAAMI,IAAI,SAACuD,EAAM/O,OAC3ByS,EAAW9G,EAAQ2B,QAAQyB,EAAK5L,SAAS,GACzCe,EAAQwO,EAAKC,iBAAiBF,UAC7B,IAAInQ,EAAK4B,EAAMhC,EAAGgC,EAAM/B,EAAGsQ,EAAS7P,MAAO6P,EAAS5P,OAAQ7C,YAG9Df,KAAK2T,wBAAwBJ,EAAWvT,KAAK8K,uBAK/CqB,EAAMI,IAAI,SAAAuD,UAAQ2D,EAAKC,iBAAiBhH,EAAQ2B,QAAQyB,EAAK5L,SAAS,+CAS9DsP,UF/cZ,oBACLA,IAAAA,SAAUjJ,IAAAA,UAAWqJ,IAAAA,SAAUC,IAAAA,MAAO7J,IAAAA,UAAWU,IAAAA,OAE3CoJ,EAAOlK,EAAc4J,EAAS7P,MAAOiQ,EAAUC,EAAO7J,GACtD+J,EAAOzJ,EAAsBC,EAAWuJ,EAAMD,GAC9CG,EAAmBvJ,EAAesJ,EAAMrJ,GAGxCzF,EAAQ,IAAIjC,EAAM4Q,EAAWI,EAAkBD,EAAKC,IAKpDC,EAAYF,EAAKC,GAAoBR,EAAS5P,OAC3C7C,EAAI,EAAGA,EAAI+S,EAAM/S,IACxBwJ,EAAUyJ,EAAmBjT,GAAKkT,SAG7BhP,EE8bEiP,CAAgB,CACrBV,SAAAA,EACAjJ,UAAWvK,KAAKuK,UAChBqJ,SAAU5T,KAAK0S,SACfmB,MAAO7T,KAAKyS,KACZzI,UAAWhK,KAAK+H,QAAQyK,gBACxB9H,OAAQ1K,KAAK+H,QAAQ2C,yDAWDG,EAAWC,UAC1BF,EAAqBC,EAAWC,gDAQjC0E,yDAAaxP,KAAKmU,qBACpBjL,EAAQ,EACZsG,EAAWrK,QAAQ,SAAC2K,YACTjQ,IACPiQ,EAAKlL,SAASX,EAAYY,IAAIb,OAAOkC,UASnC4J,EAAK1L,gBACP0L,EAAKlL,SAASX,EAAYY,IAAIb,OAAOgC,aACrCnG,IAIFiQ,EAAK/K,MAAQd,EAAYe,MAAMhB,OAC/B8L,EAAK1L,UAAW,MAEV0C,EAASsN,EAAKhB,uBAAuBtD,EAAM7L,EAAYY,IAAIb,OAAOgC,QACxEc,EAAOX,gBAAkBiO,EAAKf,kBAAkBnK,GAAS,KAEzDkL,EAAK9G,OAAOrN,KAAK,CACf6P,KAAAA,EACAhJ,OAAAA,EACAjH,SAAAA,IAGFqJ,GAAS,4CAUNlJ,KAAKiN,YAAajN,KAAKkN,kBAIvBmH,wDAWgBvE,EAAMwE,OAErBxN,EAAStB,OAAOyC,OAAO,GAAIqM,MAE7BtU,KAAK+H,QAAQmJ,cAAe,KACxBjO,EAAIjD,KAAK+H,QAAQwM,gBAAkB/L,KAAK2B,MAAM2F,EAAK7K,MAAMhC,GAAK6M,EAAK7K,MAAMhC,EACzEC,EAAIlD,KAAK+H,QAAQwM,gBAAkB/L,KAAK2B,MAAM2F,EAAK7K,MAAM/B,GAAK4M,EAAK7K,MAAM/B,EAC/E4D,EAAO0N,8BAAyBvR,iBAAQC,uBAAc4M,EAAK/K,gBAE3D+B,EAAOrD,KAAOqM,EAAK7K,MAAMhC,EAAI,KAC7B6D,EAAOpD,IAAMoM,EAAK7K,MAAM/B,EAAI,YAGvB4D,8CAUW5C,EAASuQ,EAAcC,OACnClR,EAAK6F,EAAgBnF,EAAS,SAACoF,GACnCmL,IACAC,EAAK,KAAMpL,UAGR8D,aAAanN,KAAKuD,kDASFwE,qBACd,SAAC0M,GACN1M,EAAK8H,KAAKlL,SAASoD,EAAKlB,QACxB6N,EAAKC,oBAAoB5M,EAAK8H,KAAK5L,QAAS8D,EAAKnI,SAAU6U,4CAUzD1U,KAAKqN,sBACFwH,sBAGDC,EAAW9U,KAAK+H,QAAQ8G,MAAQ,EAChCkG,EAAW/U,KAAKsN,OAAOrM,OAAS,EAElC8T,GAAYD,GAAY9U,KAAKmN,mBAC1B6H,kBAAkBhV,KAAKsN,QACnByH,QACJE,kBAAkBjV,KAAKsN,aACvB4H,UAAUxI,EAAQyI,UAAUC,cAM5BF,UAAUxI,EAAQyI,UAAUC,aAI9B9H,OAAOrM,OAAS,4CAOL+H,mBAEXqE,iBAAkB,EbztBV,SAAkBgI,EAAKC,EAASzV,GAC1CA,IACoB,mBAAZyV,GACTzV,EAAWyV,EACXA,EAAU,MAEVzV,EAAW+C,GAIf,IAAI2S,EAAUF,GAAOA,EAAIpU,OACzB,IAAKsU,EAAS,OAAO1V,EAAS,KAAM,IAEpC,IAAI2V,GAAW,EACXC,EAAU,IAAItN,MAAMoN,GAQxB,SAASG,EAAU3U,GACjB,OAAO,SAAU4U,EAAKC,GACpB,IAAIJ,EAAJ,CAEA,GAAIG,EAGF,OAFA9V,EAAS8V,EAAKF,QACdD,GAAW,GAIbC,EAAQ1U,GAAK6U,IAENL,GAAS1V,EAAS,KAAM4V,KAlBnCJ,EAAIlQ,QAAQmQ,EAAU,SAAUpV,EAAIa,GAClCb,EAAGW,KAAKyU,EAASI,EAAU3U,KACzB,SAAUb,EAAIa,GAChBb,EAAGwV,EAAU3U,Ma2sBb8U,CAFkB7M,EAAYuD,IAAI,SAAAhH,UAAOuQ,EAAKC,uBAAuBxQ,KAEjDvF,KAAKgW,kBAAkB9H,KAAKlO,sDAK3CoN,aAAajI,QAAQgE,QAGrBiE,aAAanM,OAAS,OAGtBoM,iBAAkB,4CAQP4I,MACZA,EAAQhV,OAAQ,KACZiV,EAAWD,EAAQ1J,IAAI,SAAAhH,UAAOA,EAAIuK,KAAK5L,UAE7CwI,EAAQyJ,iBAAiBD,EAAU,WACjCD,EAAQ9Q,QAAQ,SAACI,GACfA,EAAIuK,KAAKlL,SAASW,EAAIuB,QACtBvB,EAAI1F,iEAOLuN,aAAanM,OAAS,OACtBoM,iBAAkB,OAClB6H,UAAUxI,EAAQyI,UAAUC,uCAS5B7F,EAAU6G,GACVpW,KAAKiN,cAILsC,GAAaA,GAAgC,IAApBA,EAAStO,UACrCsO,EAAW7C,EAAQK,gBAGhBsJ,QAAQ9G,QAGR+G,eAGAC,wBAGA3N,KAAKwN,uCAOPI,yDAAcxW,KAAK6M,YACjB7M,KAAKiN,gBAILwJ,iBAECtK,EAAQtE,EAAO7H,KAAKgR,oBAAqBwF,QAE1CE,QAAQvK,QAIRwK,qBAGAC,yBAEA/J,SAAW2J,wCAOXK,0DACD7W,KAAKiN,YACF4J,QAEEtI,mBAIF3F,8CAUFyL,QAAO,+BAQVyC,cACI3K,EAAQK,EAAYsK,GAAUvK,IAAI,SAAA1K,UAAM,IAAIoC,EAAYpC,UAGzDgM,WAAW1B,QAGXsK,iBAGCM,EAAclP,EADH7H,KAAKgX,eAAe7K,GACAnM,KAAK6M,UACpCoK,EAAoBjX,KAAKqW,QAAQrW,KAAKgN,WAAY+J,GAElDG,EAAY,SAAApH,UAAQ3D,EAAMC,SAAS0D,IACnCqH,EAAmB,SAACrH,GACxBA,EAAK/K,MAAQd,EAAYe,MAAMhB,OAC/B8L,EAAK1L,UAAW,EAChB0L,EAAKlL,SAASX,EAAYY,IAAIb,OAAOgC,QACrC8J,EAAKlL,SAASX,EAAYY,IAAIb,OAAOkC,QAKjC8M,EAAgBhT,KAAKiT,kBAAkBgE,EAAkBrH,SAC/DqH,EAAkBrH,QAAQzK,QAAQ,SAAC2K,EAAM/O,GACnCmW,EAAUpH,KACZA,EAAK7K,MAAQ+N,EAAcjS,GAC3BoW,EAAiBrH,GACjBA,EAAKlL,SAASwS,EAAKhE,uBAAuBtD,EAAM,QAIpDmH,EAAkBpH,OAAO1K,QAAQ,SAAC2K,GAC5BoH,EAAUpH,IACZqH,EAAiBrH,UAKhB5L,QAAQwK,iBAGRC,mBAAmBxC,QAGnBA,MAAQnM,KAAKgX,eAAe7K,QAG5BqC,OAAOxO,KAAKgN,mDAOZC,WAAY,uCAOZoK,kEACApK,WAAY,EACboK,QACGhD,wCAUF6B,iBACAA,EAASjV,YAIRuO,EAAahD,EAAY0J,GAEzBoB,EAAW9H,EACdjD,IAAI,SAAArI,UAAWqT,EAAKC,iBAAiBtT,KACrCsK,OAAO,SAAAsB,WAAUA,SAcfH,qBAAqB,CACxBC,QAAS,GACTC,OAAQyH,SAGLhB,QAAQgB,QAER1O,YAIAuD,MAAQnM,KAAKmM,MAAMqC,OAAO,SAAAsB,UAASwH,EAASlL,SAAS0D,UACrDyG,wBAEApW,KAAKuM,EAAQyI,UAAUC,OA1BP,WACnBmC,EAAKE,cAAcH,GAGnB9H,EAAWrK,QAAQ,SAACjB,GAClBA,EAAQjC,WAAW2E,YAAY1C,KAGjCqT,EAAKrC,UAAUxI,EAAQyI,UAAUuC,QAAS,CAAElI,WAAAA,gDA0B/BtL,UACRlE,KAAKmM,MAAMwL,KAAK,SAAA7H,UAAQA,EAAK5L,UAAYA,yDAS3CuT,cAAczX,KAAKmM,YACnBgB,eAAgB,OAGhBhB,MAAQnM,KAAK2N,iBAGbE,WAAW7N,KAAKmM,YAEhBhM,KAAKuM,EAAQyI,UAAUC,OAAQ,WAElCwC,EAAKjJ,mBAAmBiJ,EAAKzL,OAC7ByL,EAAKzK,eAAgB,SAIlBqB,OAAOxO,KAAKgN,mDAOZ6H,kBACLnO,OAAO0C,oBAAoB,SAAUpJ,KAAK8N,gBAGrC5J,QAAQG,UAAUC,OAAO,gBACzBJ,QAAQO,gBAAgB,cAGxBgT,cAAczX,KAAKmM,YAEnBA,MAAMlL,OAAS,OACfmM,aAAanM,OAAS,OAGtB8G,QAAQ6F,MAAQ,UAChB1J,QAAU,UAIVgJ,aAAc,OACdD,WAAY,oCAyBJ/I,OAAS2T,0DAEhB/Q,EAASJ,OAAOC,iBAAiBzC,EAAS,MAC5CP,EAAQkD,EAAe3C,EAAS,QAAS4C,GACzClD,EAASiD,EAAe3C,EAAS,SAAU4C,GAE3C+Q,IAKFlU,GAJmBkD,EAAe3C,EAAS,aAAc4C,GACrCD,EAAe3C,EAAS,cAAe4C,GAI3DlD,GAHkBiD,EAAe3C,EAAS,YAAa4C,GAClCD,EAAe3C,EAAS,eAAgB4C,UAKxD,CACLnD,MAAAA,EACAC,OAAAA,4CAWoBsS,EAAUrW,OAI1Bc,EAAOuV,EAAS3J,IAAI,SAACrI,OACjB0B,EAAU1B,EAAV0B,MACFkS,EAAWlS,EAAM+L,mBACjBoG,EAAQnS,EAAMO,uBAGpBP,EAAM+L,mBATK,MAUX/L,EAAMO,gBAVK,MAYJ,CACL2R,SAAAA,EACAC,MAAAA,KAIJlY,IAGAqW,EAAS,GAAGxH,YAGZwH,EAAS/Q,QAAQ,SAACjB,EAASnD,GACzBmD,EAAQ0B,MAAM+L,mBAAqBhR,EAAKI,GAAG+W,SAC3C5T,EAAQ0B,MAAMO,gBAAkBxF,EAAKI,GAAGgX,wBAK9CrL,EAAQzI,YAAcA,EAEtByI,EAAQK,UAAY,MACpBL,EAAQwD,qBAAuB,SAG/BxD,EAAQyI,UAAY,CAClBC,OAAQ,iBACRsC,QAAS,mBAIXhL,EAAQnI,QAAUA,EAGlBmI,EAAQ+D,WAAa,CACnBC,IAAK,MACLsH,IAAK,OAIPtL,EAAQ3E,QAAU,CAEhB+E,MAAOJ,EAAQK,UAGf8B,MAAO,IAGPC,OAAQ,iCAGRiD,aAAc,IAIdnE,MAAO,KAIPuE,YAAa,EAIbrI,YAAa,EAIb8C,UAAW,KAIXlC,OAAQ,EAIR8H,gBAAiB,IAIjB/D,YAAa,KAIbQ,SAAAA,EAGAC,aAAc,IAGd2D,cAAe,GAGfC,iBAAkB,IAGlB5B,eAAe,EAKfV,WAAY9D,EAAQ+D,WAAWC,IAG/B4C,YAAY,EAIZiB,iBAAiB,GAGnB7H,EAAQ1J,MAAQA,EAChB0J,EAAQrJ,KAAOA,EAGfqJ,EAAQuL,SAAWpQ,EACnB6E,EAAQwL,gBAAkBtO,EAC1B8C,EAAQyL,wBAA0B7N,EAClCoC,EAAQ0L,iBAAmB3N,EAC3BiC,EAAQ2L,uBAAyBzN"} \ No newline at end of file diff --git a/docs/_includes/changelog.html b/docs/_includes/changelog.html index 07cbab9..b5a30cd 100644 --- a/docs/_includes/changelog.html +++ b/docs/_includes/changelog.html @@ -1,6 +1,7 @@

Changelog

For a more detailed changelog, visit the latest releases on GitHub.

    +
  • v5.3.0 12/01/18 - Change `index.d.ts` to use `export default Shuffle` (#214). Upgrade dev dependencies.
  • v5.2.0 8/19/18 - Lazily test whether the browser's getComputedStyle includes padding. This allows the bundled file to be imported in node for server side rendering.
  • v5.1.2 3/26/18 - Fix misspelled delimiter option. Both "delimiter" and "delimeter" will continue to work for v5.
  • v5.1.1 3/2/18 - Fix new item animation when there is an active filter.
  • diff --git a/docs/css/shuffle-styles.css b/docs/css/shuffle-styles.css index b1b560d..052654a 100644 --- a/docs/css/shuffle-styles.css +++ b/docs/css/shuffle-styles.css @@ -1 +1 @@ -.picture-item{height:220px;margin-left:0;margin-top:24px}.picture-item img{display:block;width:100%}@supports ((-o-object-fit:cover) or (object-fit:cover)){.picture-item img{-o-object-fit:cover;height:100%;max-width:none;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{background:#ecf0f1;height:100%;overflow:hidden;position:relative}img.picture-item__blur{display:none}.picture-item__details{align-items:baseline;display:flex;justify-content:space-between;padding:1em;width:100%}.picture-item__description{margin:0;padding:0 2em 1em 1em;width:100%}.picture-item__title{flex-shrink:0;margin-right:4px}.picture-item__tags{flex-shrink:1;margin:0;text-align:right}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{background-color:rgba(0,0,0,.6);bottom:0;color:#fff;left:0;overflow:hidden;position:absolute;width:100%}.picture-item--overlay .picture-item__description{display:none}@supports ((-webkit-filter:blur(1px)) or (filter:blur(1px))) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{-webkit-clip-path:inset(170px 0 0 0);-webkit-filter:blur(7px);clip-path:inset(170px 0 0 0);display:block;filter:blur(7px);left:0;position:absolute;top:0;z-index:1}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{overflow:hidden;position:relative}.my-sizer-element{opacity:0;position:absolute;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{-webkit-transform:translateY(220px);opacity:0;transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{-webkit-transform:translate(0);opacity:1;transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-bottom:1.25em;padding-right:.875em}.picture-item--h2{height:auto}} \ No newline at end of file +.picture-item{height:220px;margin-top:24px;margin-left:0}.picture-item img{display:block;width:100%}@supports ((-o-object-fit:cover) or (object-fit:cover)){.picture-item img{max-width:none;height:100%;-o-object-fit:cover;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{position:relative;height:100%;overflow:hidden;background:#ecf0f1}img.picture-item__blur{display:none}.picture-item__details{display:flex;align-items:baseline;justify-content:space-between;width:100%;padding:1em}.picture-item__description{width:100%;padding:0 2em 1em 1em;margin:0}.picture-item__title{flex-shrink:0;margin-right:4px}.picture-item__tags{flex-shrink:1;text-align:right;margin:0}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{position:absolute;bottom:0;left:0;width:100%;background-color:rgba(0,0,0,.6);color:#fff;overflow:hidden}.picture-item--overlay .picture-item__description{display:none}@supports ((-webkit-filter:blur(1px)) or (filter:blur(1px))) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{position:absolute;z-index:1;top:0;left:0;display:block;-webkit-filter:blur(7px);filter:blur(7px);-webkit-clip-path:inset(170px 0 0 0);clip-path:inset(170px 0 0 0)}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{position:relative;overflow:hidden}.my-sizer-element{position:absolute;opacity:0;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{opacity:0;-webkit-transform:translateY(220px);transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{opacity:1;-webkit-transform:translate(0);transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-right:.875em;padding-bottom:1.25em}.picture-item--h2{height:auto}} \ No newline at end of file diff --git a/docs/css/style.css b/docs/css/style.css index b2ffb84..d4cb713 100644 --- a/docs/css/style.css +++ b/docs/css/style.css @@ -1 +1 @@ -@charset "UTF-8";*,:after,:before{box-sizing:border-box}main{overflow:hidden}pre.max-height{max-height:30em}img,picture{display:block}img{height:auto;max-width:100%}figure,ul ul{margin:0}ul ul{list-style-type:circle;padding-left:1.25em}li{line-height:1.4}li+li{margin-top:4px}nav>a{display:block;margin:5px 0}#demos{margin-top:1em}body{color:#5d6d77;font-family:Open Sans,Helvetica Neue,Helvetica,sans-serif}a{text-decoration:none}a,a:visited{color:#3498db}a:hover{text-decoration:underline}a:active{color:#2ecc71}h1,h2,h3,h4,h5,h6{color:#34495e;font-weight:700}h1{font-size:10vw;font-weight:400;line-height:1}h1,h2{margin:3vw 0}h2{font-size:7vw;position:relative}h3{font-size:6vw;margin:2vw 0}h4{font-size:1.25em}p{line-height:1.4;margin:1em 0}.intro-text{font-size:1.125em;margin:.7em 0}@media screen and (min-width:768px){h1{font-size:3.5em;margin:.5em 0 .25em}h2{font-size:2.5em;margin:.45em 0}h3{font-size:1.5em;margin:.8em 0 .5em}h1>a,h2>a,h3>a{display:none}h1:hover>a,h2:hover>a,h3:hover>a{background:url(../img/link.svg) no-repeat;display:inline-block;height:50px;overflow:hidden;position:absolute;text-indent:-999em;top:0;width:50px}.intro-text{font-size:1.25em}}.unstyled{list-style-type:none;margin:0;padding:0}.type--underline{text-decoration:underline}code:not([class*=language]){background-color:rgba(27,31,35,.05);border-radius:3px;color:#2c3e50;font-family:Menlo,Consolas,Liberation Mono,Courier,monospace;font-size:85%;margin:0;padding:.2em 0}code:not([class*=language]):after,code:not([class*=language]):before{content:"\00a0";letter-spacing:-.2em}.container{padding-left:3.5%;padding-right:3.5%}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.row{margin-left:auto;margin-right:auto}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.row .row{margin-left:-8px;margin-right:-8px}.row--centered{display:flex;flex-wrap:wrap;justify-content:center}.aspect{height:0;overflow:hidden;padding-bottom:100%;position:relative;width:100%}.aspect--16x9{padding-bottom:56.25%}.aspect--9x16{padding-bottom:177.77778%}.aspect--4x3{padding-bottom:75%}.aspect--3x4{padding-bottom:133.33333%}.aspect--3x2{padding-bottom:66.66667%}.aspect--3x1{padding-bottom:33.33333%}.aspect--2x3{padding-bottom:150%}.aspect--2x1{padding-bottom:50%}.aspect--1x2{padding-bottom:200%}.aspect--1x1{padding-bottom:100%}.aspect--none{height:auto;overflow:visible;padding-bottom:0}.aspect--none>.aspect__inner{position:static}.aspect>div,.aspect__inner{bottom:0;left:0;position:absolute;right:0;top:0}.col-1\@lg,.col-1\@md,.col-1\@sm,.col-1\@xs,.col-2\@lg,.col-2\@md,.col-2\@sm,.col-2\@xs,.col-3\@lg,.col-3\@md,.col-3\@sm,.col-3\@xs,.col-4\@lg,.col-4\@md,.col-4\@sm,.col-4\@xs,.col-5\@lg,.col-5\@md,.col-5\@sm,.col-5\@xs,.col-6\@lg,.col-6\@md,.col-6\@sm,.col-6\@xs,.col-7\@lg,.col-7\@md,.col-7\@sm,.col-7\@xs,.col-8\@lg,.col-8\@md,.col-8\@sm,.col-8\@xs,.col-9\@lg,.col-9\@md,.col-9\@sm,.col-9\@xs,.col-10\@lg,.col-10\@md,.col-10\@sm,.col-10\@xs,.col-11\@lg,.col-11\@md,.col-11\@sm,.col-11\@xs,.col-12\@lg,.col-12\@md,.col-12\@sm,.col-12\@xs{box-sizing:border-box;min-height:1px;padding-left:8px;padding-right:8px;position:relative}.col-1\@xs,.col-2\@xs,.col-3\@xs,.col-4\@xs,.col-5\@xs,.col-6\@xs,.col-7\@xs,.col-8\@xs,.col-9\@xs,.col-10\@xs,.col-11\@xs,.col-12\@xs{float:left}.aspect--16x9\@xs{padding-bottom:56.25%}.aspect--9x16\@xs{padding-bottom:177.77778%}.aspect--4x3\@xs{padding-bottom:75%}.aspect--3x4\@xs{padding-bottom:133.33333%}.aspect--3x2\@xs{padding-bottom:66.66667%}.aspect--3x1\@xs{padding-bottom:33.33333%}.aspect--2x3\@xs{padding-bottom:150%}.aspect--2x1\@xs{padding-bottom:50%}.aspect--1x2\@xs{padding-bottom:200%}.aspect--1x1\@xs{padding-bottom:100%}.aspect--none\@xs{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@xs>.aspect__inner{position:static}.col-1\@xs{width:16.66667%}.col-2\@xs{width:33.33333%}.col-3\@xs{width:50%}.col-4\@xs{width:66.66667%}.col-5\@xs{width:83.33333%}.col-6\@xs{width:100%}.col-pull-0\@xs{right:auto}.col-pull-1\@xs{right:16.66667%}.col-pull-2\@xs{right:33.33333%}.col-pull-3\@xs{right:50%}.col-pull-4\@xs{right:66.66667%}.col-pull-5\@xs{right:83.33333%}.col-pull-6\@xs{right:100%}.col-push-0\@xs{left:auto}.col-push-1\@xs{left:16.66667%}.col-push-2\@xs{left:33.33333%}.col-push-3\@xs{left:50%}.col-push-4\@xs{left:66.66667%}.col-push-5\@xs{left:83.33333%}.col-push-6\@xs{left:100%}.col-offset-0\@xs{margin-left:0}.col-offset-1\@xs{margin-left:16.66667%}.col-offset-2\@xs{margin-left:33.33333%}.col-offset-3\@xs{margin-left:50%}.col-offset-4\@xs{margin-left:66.66667%}.col-offset-5\@xs{margin-left:83.33333%}.col-offset-6\@xs{margin-left:100%}@media screen and (min-width:768px){.col-1\@sm,.col-2\@sm,.col-3\@sm,.col-4\@sm,.col-5\@sm,.col-6\@sm,.col-7\@sm,.col-8\@sm,.col-9\@sm,.col-10\@sm,.col-11\@sm,.col-12\@sm{float:left}.aspect--16x9\@sm{padding-bottom:56.25%}.aspect--9x16\@sm{padding-bottom:177.77778%}.aspect--4x3\@sm{padding-bottom:75%}.aspect--3x4\@sm{padding-bottom:133.33333%}.aspect--3x2\@sm{padding-bottom:66.66667%}.aspect--3x1\@sm{padding-bottom:33.33333%}.aspect--2x3\@sm{padding-bottom:150%}.aspect--2x1\@sm{padding-bottom:50%}.aspect--1x2\@sm{padding-bottom:200%}.aspect--1x1\@sm{padding-bottom:100%}.aspect--none\@sm{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@sm>.aspect__inner{position:static}.col-1\@sm{width:8.33333%}.col-2\@sm{width:16.66667%}.col-3\@sm{width:25%}.col-4\@sm{width:33.33333%}.col-5\@sm{width:41.66667%}.col-6\@sm{width:50%}.col-7\@sm{width:58.33333%}.col-8\@sm{width:66.66667%}.col-9\@sm{width:75%}.col-10\@sm{width:83.33333%}.col-11\@sm{width:91.66667%}.col-12\@sm{width:100%}.col-pull-0\@sm{right:auto}.col-pull-1\@sm{right:8.33333%}.col-pull-2\@sm{right:16.66667%}.col-pull-3\@sm{right:25%}.col-pull-4\@sm{right:33.33333%}.col-pull-5\@sm{right:41.66667%}.col-pull-6\@sm{right:50%}.col-pull-7\@sm{right:58.33333%}.col-pull-8\@sm{right:66.66667%}.col-pull-9\@sm{right:75%}.col-pull-10\@sm{right:83.33333%}.col-pull-11\@sm{right:91.66667%}.col-pull-12\@sm{right:100%}.col-push-0\@sm{left:auto}.col-push-1\@sm{left:8.33333%}.col-push-2\@sm{left:16.66667%}.col-push-3\@sm{left:25%}.col-push-4\@sm{left:33.33333%}.col-push-5\@sm{left:41.66667%}.col-push-6\@sm{left:50%}.col-push-7\@sm{left:58.33333%}.col-push-8\@sm{left:66.66667%}.col-push-9\@sm{left:75%}.col-push-10\@sm{left:83.33333%}.col-push-11\@sm{left:91.66667%}.col-push-12\@sm{left:100%}.col-offset-0\@sm{margin-left:0}.col-offset-1\@sm{margin-left:8.33333%}.col-offset-2\@sm{margin-left:16.66667%}.col-offset-3\@sm{margin-left:25%}.col-offset-4\@sm{margin-left:33.33333%}.col-offset-5\@sm{margin-left:41.66667%}.col-offset-6\@sm{margin-left:50%}.col-offset-7\@sm{margin-left:58.33333%}.col-offset-8\@sm{margin-left:66.66667%}.col-offset-9\@sm{margin-left:75%}.col-offset-10\@sm{margin-left:83.33333%}.col-offset-11\@sm{margin-left:91.66667%}.col-offset-12\@sm{margin-left:100%}.container{padding-left:7%;padding-right:7%}.row{max-width:1200px}}@media screen and (min-width:1024px){.col-1\@md,.col-2\@md,.col-3\@md,.col-4\@md,.col-5\@md,.col-6\@md,.col-7\@md,.col-8\@md,.col-9\@md,.col-10\@md,.col-11\@md,.col-12\@md{float:left}.aspect--16x9\@md{padding-bottom:56.25%}.aspect--9x16\@md{padding-bottom:177.77778%}.aspect--4x3\@md{padding-bottom:75%}.aspect--3x4\@md{padding-bottom:133.33333%}.aspect--3x2\@md{padding-bottom:66.66667%}.aspect--3x1\@md{padding-bottom:33.33333%}.aspect--2x3\@md{padding-bottom:150%}.aspect--2x1\@md{padding-bottom:50%}.aspect--1x2\@md{padding-bottom:200%}.aspect--1x1\@md{padding-bottom:100%}.aspect--none\@md{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@md>.aspect__inner{position:static}.col-1\@md{width:8.33333%}.col-2\@md{width:16.66667%}.col-3\@md{width:25%}.col-4\@md{width:33.33333%}.col-5\@md{width:41.66667%}.col-6\@md{width:50%}.col-7\@md{width:58.33333%}.col-8\@md{width:66.66667%}.col-9\@md{width:75%}.col-10\@md{width:83.33333%}.col-11\@md{width:91.66667%}.col-12\@md{width:100%}.col-pull-0\@md{right:auto}.col-pull-1\@md{right:8.33333%}.col-pull-2\@md{right:16.66667%}.col-pull-3\@md{right:25%}.col-pull-4\@md{right:33.33333%}.col-pull-5\@md{right:41.66667%}.col-pull-6\@md{right:50%}.col-pull-7\@md{right:58.33333%}.col-pull-8\@md{right:66.66667%}.col-pull-9\@md{right:75%}.col-pull-10\@md{right:83.33333%}.col-pull-11\@md{right:91.66667%}.col-pull-12\@md{right:100%}.col-push-0\@md{left:auto}.col-push-1\@md{left:8.33333%}.col-push-2\@md{left:16.66667%}.col-push-3\@md{left:25%}.col-push-4\@md{left:33.33333%}.col-push-5\@md{left:41.66667%}.col-push-6\@md{left:50%}.col-push-7\@md{left:58.33333%}.col-push-8\@md{left:66.66667%}.col-push-9\@md{left:75%}.col-push-10\@md{left:83.33333%}.col-push-11\@md{left:91.66667%}.col-push-12\@md{left:100%}.col-offset-0\@md{margin-left:0}.col-offset-1\@md{margin-left:8.33333%}.col-offset-2\@md{margin-left:16.66667%}.col-offset-3\@md{margin-left:25%}.col-offset-4\@md{margin-left:33.33333%}.col-offset-5\@md{margin-left:41.66667%}.col-offset-6\@md{margin-left:50%}.col-offset-7\@md{margin-left:58.33333%}.col-offset-8\@md{margin-left:66.66667%}.col-offset-9\@md{margin-left:75%}.col-offset-10\@md{margin-left:83.33333%}.col-offset-11\@md{margin-left:91.66667%}.col-offset-12\@md{margin-left:100%}}.code-block{margin:.5em calc(-3.5vw - 8px);overflow:visible;position:relative}.code-block pre{margin:0;min-height:56px;padding:1em calc(3.5vw + 8px);position:relative;z-index:1}@media screen and (min-width:768px){.code-block{margin-left:calc(-7vw - 8px);margin-right:calc(-7vw - 8px)}.code-block pre{padding-left:calc(7vw + 8px);padding-right:calc(7vw + 8px);position:relative;z-index:1}}@media (min-width:1395px){.code-block{margin-left:calc(-50vw + 592px);margin-right:calc(-50vw + 592px)}.code-block pre{padding-left:calc(50vw - 592px);padding-right:calc(50vw - 592px)}}.textfield{-webkit-appearance:none;border:2px solid #95a5a6;border-radius:4px;box-sizing:border-box;color:#34495e;font-size:1rem;padding:.5em;transition:.15s;width:100%}.textfield::-webkit-input-placeholder{color:#95a5a6;transition:.15s}.textfield:-ms-input-placeholder{color:#95a5a6;transition:.15s}.textfield::-ms-input-placeholder{color:#95a5a6;transition:.15s}.textfield::placeholder{color:#95a5a6;transition:.15s}.textfield:hover{border-color:#5d6d77;color:#5d6d77;outline-width:0}.textfield:hover::-webkit-input-placeholder{color:#5d6d77}.textfield:hover:-ms-input-placeholder{color:#5d6d77}.textfield:hover::-ms-input-placeholder{color:#5d6d77}.textfield:hover::placeholder{color:#5d6d77}.textfield:focus{border-color:#34495e;outline-width:0}.textfield:focus::-webkit-input-placeholder{color:#34495e}.textfield:focus:-ms-input-placeholder{color:#34495e}.textfield:focus::-ms-input-placeholder{color:#34495e}.textfield:focus::placeholder{color:#34495e}.textfield--large{font-size:1.125em}.text-center{text-align:center}.ib{display:inline-block}@media screen and (max-width:767px){.hidden\@xs{display:none}}@media screen and (min-width:768px){.visible\@xs{display:none}}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.clearfix,.clearfix:after{clear:both;content:" ";display:table}.pull-left{float:left}.pull-right{float:right}.full-width{width:100%}.full-height{height:100%}.hide-text{background-color:transparent;border:0;color:transparent;font:0/0 a;text-shadow:none}.table-center-wrap{display:table;table-layout:fixed}.table-center{display:table-cell;vertical-align:middle}.btn-group:after,.btn-group:before{content:" ";display:table}.btn-group:after{clear:both}.btn-group .btn{border-radius:0;float:left}.btn-group .btn:first-child{border-radius:3px 0 0 3px}.btn-group .btn:not(:first-child){margin-left:-1px}.btn-group .btn:last-child{border-radius:0 3px 3px 0}.btn-group label.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn{-webkit-appearance:none;background-color:rgba(52,73,94,0);border:1px solid #34495e;border-radius:3px;color:#34495e;cursor:pointer;display:inline-block;font-size:1rem;padding:.75em .8em;text-align:center;transition:.2s ease-out}@media (-moz-touch-enabled:0),(pointer:fine){.btn:hover{background-color:#34495e;color:#fff;text-decoration:none}}.btn:focus{box-shadow:0 0 0 2px rgba(52,73,94,.4);outline-width:0}.btn.active,.btn:active{background-color:#34495e;box-shadow:inset 0 1px 2px rgba(0,0,0,.3);color:#fff}.btn:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,73,94,.4)}.btn:disabled{background-color:rgba(52,73,94,0);color:#34495e;cursor:not-allowed;opacity:.7}.btn--warning{background-color:rgba(230,126,34,0);border-color:#e67e22;color:#e67e22}@media (-moz-touch-enabled:0),(pointer:fine){.btn--warning:hover{background-color:#e67e22}}.btn--warning:focus{box-shadow:0 0 0 2px rgba(230,126,34,.4)}.btn--warning.active,.btn--warning:active{background-color:#e67e22}.btn--warning:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(230,126,34,.4)}.btn--warning:disabled{background-color:rgba(230,126,34,0);color:#e67e22}.btn--primary{background-color:rgba(52,152,219,0);border-color:#3498db;color:#3498db}@media (-moz-touch-enabled:0),(pointer:fine){.btn--primary:hover{background-color:#3498db}}.btn--primary:focus{box-shadow:0 0 0 2px rgba(52,152,219,.4)}.btn--primary.active,.btn--primary:active{background-color:#3498db}.btn--primary:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,152,219,.4)}.btn--primary:disabled{background-color:rgba(52,152,219,0);color:#3498db}.btn--danger{background-color:rgba(231,76,60,0);border-color:#e74c3c;color:#e74c3c}@media (-moz-touch-enabled:0),(pointer:fine){.btn--danger:hover{background-color:#e74c3c}}.btn--danger:focus{box-shadow:0 0 0 2px rgba(231,76,60,.4)}.btn--danger.active,.btn--danger:active{background-color:#e74c3c}.btn--danger:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(231,76,60,.4)}.btn--danger:disabled{background-color:rgba(231,76,60,0);color:#e74c3c}.btn--go{background-color:rgba(46,204,113,0);border-color:#2ecc71;color:#2ecc71}@media (-moz-touch-enabled:0),(pointer:fine){.btn--go:hover{background-color:#2ecc71}}.btn--go:focus{box-shadow:0 0 0 2px rgba(46,204,113,.4)}.btn--go.active,.btn--go:active{background-color:#2ecc71}.btn--go:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(46,204,113,.4)}.btn--go:disabled{background-color:rgba(46,204,113,0);color:#2ecc71}@media screen and (max-width:767px){.btn{font-size:.875rem}}.filter-group .btn{position:relative}.filter-group .btn.active:after,.filter-group .btn.active:before{content:"";height:20px;left:50%;margin-left:-10px;margin-top:-10px;opacity:0;position:absolute;top:50%;transition:.2s;width:20px}.filter-group .btn:before{background-color:#2c3e50;border-radius:50%}.filter-group .btn:after{background-image:url(../img/check.svg);background-position:50%;background-repeat:no-repeat;background-size:60%}.filter-group .btn.active:after,.filter-group .btn.active:before{opacity:1}.demo-list .figure-wrap{position:relative;z-index:1}.demo-list .figure-wrap,.demo-list .figure-wrap img{-webkit-transform:translateZ(0);transform:translateZ(0);transition:.1s ease}.demo-list:hover .figure-wrap{-webkit-transform:scaleX(1);transform:scaleX(1)}.demo-list:hover .figure-wrap img{-webkit-filter:grayscale(1);filter:grayscale(1)}.demo-list:hover .figure-wrap:hover{-webkit-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1);z-index:2}.demo-list:hover .figure-wrap:hover img{-webkit-filter:none;filter:none}.demo-list .figure-wrap:nth-child(4n+1){margin-left:0}.demo-list .figure-wrap>a{display:block}.demo-list .figure-wrap figcaption{height:2em;margin-bottom:1em;margin-top:.5em}.demo-link-container:before{color:#2ecc71;content:"âžœ";margin-right:5px}span.demo-link-container:before{margin-left:5px}@media screen and (max-width:47.9375em){.demo-list+.demo-list{margin-top:1em}.figure-wrap:nth-child(odd){margin-left:0}.figure-wrap:nth-child(n+3){margin-top:1em}}.site-nav{background:#ecf0f1;border-bottom:1px solid #e1e5e6;margin-bottom:28px;padding:10px 0}.site-nav__content{display:flex;justify-content:space-between}.site-nav__logo{font-size:20px}.site-nav__logo,.site-nav__logo:visited{color:#34495e}.site-nav__logo:hover,.site-nav__logo:visited:hover{text-decoration:none}.site-nav__links,.site-nav__logo{align-items:center;display:flex}.site-nav__logo svg{display:block;height:24px;margin-right:4px;width:24px}.site-nav__logo rect{transition:.18s cubic-bezier(.4,0,.2,1)}.site-nav__link{position:relative;z-index:3}.site-nav__link:not(:last-of-type){margin-right:8px}.site-nav__dropdown{-webkit-transform:translateY(10px);background-color:#fff;box-shadow:0 7px 10px -1px rgba(0,0,0,.12);max-height:100vh;opacity:0;position:absolute;right:0;top:40px;transform:translateY(10px);transition:.3s cubic-bezier(.165,.84,.44,1);visibility:hidden;z-index:2}.site-nav__dropdown:before{border-bottom:8px solid #fff;border-left:9px solid transparent;border-right:9px solid transparent;content:"";display:block;position:absolute;right:32px;top:-8px}.site-nav__dropdown li+li{margin-top:8px}.site-nav__dropdown a{color:#5d6d77;display:block}.site-nav__dropdown a:hover{background-color:#ecf0f1;color:#5d6d77;text-decoration:none}.site-nav__dropdown figure{align-items:center;display:flex}.site-nav__dropdown picture{flex-shrink:0;height:75px;width:100px}.site-nav__dropdown figcaption{padding-left:8px;padding-right:8px}.site-nav__dropdown--simple-links a{padding:8px 16px}.site-nav__dropdown--simple-links li+li{margin-top:0}.site-nav__link-toggle{padding:6px 8px}.site-nav__link-toggle:after{border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid;content:"";display:inline-block;margin-left:4px;margin-top:-1px;transition:-webkit-transform .18s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1);vertical-align:middle}.site-nav__link--dropdown-active .site-nav__link-toggle:after{-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.site-nav__link--dropdown-active .site-nav__dropdown{-webkit-transform:translateY(0);opacity:1;transform:translateY(0);visibility:visible}@media (-moz-touch-enabled:0),(pointer:fine){.site-nav__logo:hover rect:first-of-type{-webkit-transform:translate(20px,10px);transform:translate(20px,10px);transition-delay:0ms}.site-nav__logo:hover rect:nth-of-type(2){-webkit-transform:translateY(20px);transform:translateY(20px);transition-delay:10ms}.site-nav__logo:hover rect:nth-of-type(3){-webkit-transform:translate(-20px,6px);transform:translate(-20px,6px);transition-delay:20ms}.site-nav__logo:hover rect:nth-of-type(4){-webkit-transform:translate(10px,-10px);transform:translate(10px,-10px);transition-delay:30ms}.site-nav__logo:hover rect:nth-of-type(5){-webkit-transform:translate(-10px,10px);transform:translate(-10px,10px);transition-delay:40ms}.site-nav__logo:hover rect:nth-of-type(6){-webkit-transform:translate(-20px,-14px);transform:translate(-20px,-14px);transition-delay:50ms}.site-nav__logo:hover rect:nth-of-type(7){-webkit-transform:translateY(-20px);transform:translateY(-20px);transition-delay:60ms}.site-nav__link-toggle:hover{border-color:#34495e}}@media screen and (max-width:767px){body.site-nav--open{padding-top:51px}body.site-nav--open .site-nav{left:0;position:fixed;top:0;width:100%;z-index:4}.site-nav__dropdown{-webkit-overflow-scrolling:touch;left:0;overflow:auto;padding:8px calc(3.5vw + 8px);position:fixed;right:0;top:51px;width:100vw}}@media screen and (min-width:768px){.site-nav{padding:16px 0}.site-nav__logo{font-size:24px}.site-nav__logo svg{height:32px;width:32px}.site-nav__link:not(:last-child){margin-right:16px}.site-nav__link--dropdown:not(:last-child){margin-right:12px}.site-nav__dropdown{box-shadow:0 0 10px rgba(0,0,0,.12);max-height:none!important;padding:16px;right:-100px}.site-nav__dropdown:before{right:132px}.site-nav__dropdown ul{-webkit-column-count:2;-webkit-column-gap:16px;column-count:2;column-gap:16px}.site-nav__dropdown li{-webkit-column-break-inside:avoid;break-inside:avoid;page-break-inside:avoid}.site-nav__dropdown figcaption{white-space:nowrap}@supports ((-webkit-filter:drop-shadow(0 0 5px rgba(0,0,0,0.12))) or (filter:drop-shadow(0 0 5px rgba(0,0,0,0.12)))){.site-nav__dropdown{-webkit-filter:drop-shadow(0 0 5px rgba(0,0,0,.12));box-shadow:none;filter:drop-shadow(0 0 5px rgba(0,0,0,.12))}}.site-nav__link-img{height:24px;width:24px}.site-nav__dropdown--simple-links{padding:0;right:0}.site-nav__dropdown--simple-links:before{right:24px}.site-nav__dropdown--simple-links a{width:200px}}@media screen and (min-width:1024px){.site-nav__dropdown{right:0}.site-nav__dropdown:before{right:32px}.site-nav__dropdown--simple-links:before{right:24px}}.site-footer{background-color:#34495e;margin-top:2em;padding:1em 0}.site-footer p{color:#ecf0f1}.site-footer a{color:#fff;text-decoration:underline}.site-footer a:hover{color:#3498db}.has-code-block .code-block pre{margin-bottom:0}.has-code-block+.site-footer{margin-top:0}@media screen and (min-width:768px){.site-footer__credit{text-align:right}}.filter-label{color:#95a5a6;display:block;margin-bottom:4px;margin-top:0;padding:0}.filters-group{border:0;margin:0 0 4px;padding:0}@media screen and (min-width:768px){.filters-group-wrap{display:flex;justify-content:space-between}}.compound-filter-options{margin-bottom:40px;margin-top:20px}.filter-group--compound button{background-color:currentColor;height:40px;padding:0;width:40px}.filter-group--compound label{cursor:pointer}.filter-group--compound .ib+.ib{margin-left:8px}.shape-shuffle-container{overflow:hidden;position:relative}.shape{margin-left:0;margin-top:10px;position:relative}.shape .shape__space{background-color:#000;border:0 solid transparent;height:100%;width:100%}.shape--blue .shape__space{background-color:#3498db;border-bottom-color:#3498db}.shape--red .shape__space{background-color:#e74c3c;border-bottom-color:#e74c3c}.shape--orange .shape__space{background-color:#f39c12;border-bottom-color:#f39c12}.shape--green .shape__space{background-color:#2ecc71;border-bottom-color:#2ecc71}.shape--circle .shape__space{border-radius:50%}.shape--diamond .shape__space{-webkit-transform:rotate(45deg) scale(.70711);transform:rotate(45deg) scale(.70711)}.shape--triangle .shape__space{background-color:transparent;border-width:0 66px 114px;height:0;margin:auto;padding-top:9px;width:0}@media (min-width:425px){.shape--triangle .shape__space{border-width:0 90px 156px;height:0;padding-top:12px;width:0}}@media (min-width:600px){.shape--triangle .shape__space{border-width:0 131px 227px;height:0;padding-top:17.5px;width:0}}@media (min-width:768px){.shape--triangle .shape__space{border-width:0 74px 128px;height:0;padding-top:10px;width:0}}@media (min-width:1024px){.shape--triangle .shape__space{border-width:0 102px 177px;height:0;padding-top:13.5px;width:0}}@media (min-width:1200px){.shape--triangle .shape__space{border-width:0 135px 234px;height:0;padding-top:18px;width:0}}@media (min-width:1392px){.shape--triangle .shape__space{border-width:0 142px 246px;height:0;padding-top:19px;width:0}}.search-section{margin-bottom:1em;margin-top:1em}.question{float:none;margin:2em 0;overflow:hidden;transition:.2s ease-out}.question--collapsed{border-width:0;height:0!important;margin:0}.question--collapsed+.question{margin-top:0}.question--unanswered{border-top:2px solid #2ecc71;padding-top:1.25em}.question__title{margin-top:0}.question__answer{margin-bottom:0;padding-bottom:1px} \ No newline at end of file +@charset "UTF-8";*,:after,:before{box-sizing:border-box}main{overflow:hidden}pre.max-height{max-height:30em}img,picture{display:block}img{max-width:100%;height:auto}figure,ul ul{margin:0}ul ul{padding-left:1.25em;list-style-type:circle}li{line-height:1.4}li+li{margin-top:4px}nav>a{display:block;margin:5px 0}#demos{margin-top:1em}body{font-family:Open Sans,Helvetica Neue,Helvetica,sans-serif;color:#5d6d77}a{text-decoration:none}a,a:visited{color:#3498db}a:hover{text-decoration:underline}a:active{color:#2ecc71}h1,h2,h3,h4,h5,h6{color:#34495e;font-weight:700}h1{font-size:10vw;font-weight:400;line-height:1}h1,h2{margin:3vw 0}h2{position:relative;font-size:7vw}h3{font-size:6vw;margin:2vw 0}h4{font-size:1.25em}p{margin:1em 0;line-height:1.4}.intro-text{margin:.7em 0;font-size:1.125em}@media screen and (min-width:768px){h1{margin:.5em 0 .25em;font-size:3.5em}h2{margin:.45em 0;font-size:2.5em}h3{margin:.8em 0 .5em;font-size:1.5em}h1>a,h2>a,h3>a{display:none}h1:hover>a,h2:hover>a,h3:hover>a{position:absolute;display:inline-block;top:0;height:50px;width:50px;background:url(../img/link.svg) no-repeat;overflow:hidden;text-indent:-999em}.intro-text{font-size:1.25em}}.unstyled{list-style-type:none;padding:0;margin:0}.type--underline{text-decoration:underline}code:not([class*=language]){padding:.2em 0;margin:0;font-size:85%;color:#2c3e50;background-color:rgba(27,31,35,.05);border-radius:3px;font-family:Menlo,Consolas,Liberation Mono,Courier,monospace}code:not([class*=language]):after,code:not([class*=language]):before{content:"\00a0";letter-spacing:-.2em}.container{padding-left:3.5%;padding-right:3.5%}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.row{margin-left:auto;margin-right:auto}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.row .row{margin-left:-8px;margin-right:-8px}.row--centered{display:flex;flex-wrap:wrap;justify-content:center}.aspect{position:relative;width:100%;height:0;overflow:hidden;padding-bottom:100%}.aspect--16x9{padding-bottom:56.25%}.aspect--9x16{padding-bottom:177.77778%}.aspect--4x3{padding-bottom:75%}.aspect--3x4{padding-bottom:133.33333%}.aspect--3x2{padding-bottom:66.66667%}.aspect--3x1{padding-bottom:33.33333%}.aspect--2x3{padding-bottom:150%}.aspect--2x1{padding-bottom:50%}.aspect--1x2{padding-bottom:200%}.aspect--1x1{padding-bottom:100%}.aspect--none{height:auto;padding-bottom:0;overflow:visible}.aspect--none>.aspect__inner{position:static}.aspect>div,.aspect__inner{position:absolute;top:0;left:0;right:0;bottom:0}.col-1\@lg,.col-1\@md,.col-1\@sm,.col-1\@xs,.col-2\@lg,.col-2\@md,.col-2\@sm,.col-2\@xs,.col-3\@lg,.col-3\@md,.col-3\@sm,.col-3\@xs,.col-4\@lg,.col-4\@md,.col-4\@sm,.col-4\@xs,.col-5\@lg,.col-5\@md,.col-5\@sm,.col-5\@xs,.col-6\@lg,.col-6\@md,.col-6\@sm,.col-6\@xs,.col-7\@lg,.col-7\@md,.col-7\@sm,.col-7\@xs,.col-8\@lg,.col-8\@md,.col-8\@sm,.col-8\@xs,.col-9\@lg,.col-9\@md,.col-9\@sm,.col-9\@xs,.col-10\@lg,.col-10\@md,.col-10\@sm,.col-10\@xs,.col-11\@lg,.col-11\@md,.col-11\@sm,.col-11\@xs,.col-12\@lg,.col-12\@md,.col-12\@sm,.col-12\@xs{position:relative;box-sizing:border-box;min-height:1px;padding-left:8px;padding-right:8px}.col-1\@xs,.col-2\@xs,.col-3\@xs,.col-4\@xs,.col-5\@xs,.col-6\@xs,.col-7\@xs,.col-8\@xs,.col-9\@xs,.col-10\@xs,.col-11\@xs,.col-12\@xs{float:left}.aspect--16x9\@xs{padding-bottom:56.25%}.aspect--9x16\@xs{padding-bottom:177.77778%}.aspect--4x3\@xs{padding-bottom:75%}.aspect--3x4\@xs{padding-bottom:133.33333%}.aspect--3x2\@xs{padding-bottom:66.66667%}.aspect--3x1\@xs{padding-bottom:33.33333%}.aspect--2x3\@xs{padding-bottom:150%}.aspect--2x1\@xs{padding-bottom:50%}.aspect--1x2\@xs{padding-bottom:200%}.aspect--1x1\@xs{padding-bottom:100%}.aspect--none\@xs{height:auto;padding-bottom:0;overflow:visible}.aspect--none\@xs>.aspect__inner{position:static}.col-1\@xs{width:16.66667%}.col-2\@xs{width:33.33333%}.col-3\@xs{width:50%}.col-4\@xs{width:66.66667%}.col-5\@xs{width:83.33333%}.col-6\@xs{width:100%}.col-pull-0\@xs{right:auto}.col-pull-1\@xs{right:16.66667%}.col-pull-2\@xs{right:33.33333%}.col-pull-3\@xs{right:50%}.col-pull-4\@xs{right:66.66667%}.col-pull-5\@xs{right:83.33333%}.col-pull-6\@xs{right:100%}.col-push-0\@xs{left:auto}.col-push-1\@xs{left:16.66667%}.col-push-2\@xs{left:33.33333%}.col-push-3\@xs{left:50%}.col-push-4\@xs{left:66.66667%}.col-push-5\@xs{left:83.33333%}.col-push-6\@xs{left:100%}.col-offset-0\@xs{margin-left:0}.col-offset-1\@xs{margin-left:16.66667%}.col-offset-2\@xs{margin-left:33.33333%}.col-offset-3\@xs{margin-left:50%}.col-offset-4\@xs{margin-left:66.66667%}.col-offset-5\@xs{margin-left:83.33333%}.col-offset-6\@xs{margin-left:100%}@media screen and (min-width:768px){.col-1\@sm,.col-2\@sm,.col-3\@sm,.col-4\@sm,.col-5\@sm,.col-6\@sm,.col-7\@sm,.col-8\@sm,.col-9\@sm,.col-10\@sm,.col-11\@sm,.col-12\@sm{float:left}.aspect--16x9\@sm{padding-bottom:56.25%}.aspect--9x16\@sm{padding-bottom:177.77778%}.aspect--4x3\@sm{padding-bottom:75%}.aspect--3x4\@sm{padding-bottom:133.33333%}.aspect--3x2\@sm{padding-bottom:66.66667%}.aspect--3x1\@sm{padding-bottom:33.33333%}.aspect--2x3\@sm{padding-bottom:150%}.aspect--2x1\@sm{padding-bottom:50%}.aspect--1x2\@sm{padding-bottom:200%}.aspect--1x1\@sm{padding-bottom:100%}.aspect--none\@sm{height:auto;padding-bottom:0;overflow:visible}.aspect--none\@sm>.aspect__inner{position:static}.col-1\@sm{width:8.33333%}.col-2\@sm{width:16.66667%}.col-3\@sm{width:25%}.col-4\@sm{width:33.33333%}.col-5\@sm{width:41.66667%}.col-6\@sm{width:50%}.col-7\@sm{width:58.33333%}.col-8\@sm{width:66.66667%}.col-9\@sm{width:75%}.col-10\@sm{width:83.33333%}.col-11\@sm{width:91.66667%}.col-12\@sm{width:100%}.col-pull-0\@sm{right:auto}.col-pull-1\@sm{right:8.33333%}.col-pull-2\@sm{right:16.66667%}.col-pull-3\@sm{right:25%}.col-pull-4\@sm{right:33.33333%}.col-pull-5\@sm{right:41.66667%}.col-pull-6\@sm{right:50%}.col-pull-7\@sm{right:58.33333%}.col-pull-8\@sm{right:66.66667%}.col-pull-9\@sm{right:75%}.col-pull-10\@sm{right:83.33333%}.col-pull-11\@sm{right:91.66667%}.col-pull-12\@sm{right:100%}.col-push-0\@sm{left:auto}.col-push-1\@sm{left:8.33333%}.col-push-2\@sm{left:16.66667%}.col-push-3\@sm{left:25%}.col-push-4\@sm{left:33.33333%}.col-push-5\@sm{left:41.66667%}.col-push-6\@sm{left:50%}.col-push-7\@sm{left:58.33333%}.col-push-8\@sm{left:66.66667%}.col-push-9\@sm{left:75%}.col-push-10\@sm{left:83.33333%}.col-push-11\@sm{left:91.66667%}.col-push-12\@sm{left:100%}.col-offset-0\@sm{margin-left:0}.col-offset-1\@sm{margin-left:8.33333%}.col-offset-2\@sm{margin-left:16.66667%}.col-offset-3\@sm{margin-left:25%}.col-offset-4\@sm{margin-left:33.33333%}.col-offset-5\@sm{margin-left:41.66667%}.col-offset-6\@sm{margin-left:50%}.col-offset-7\@sm{margin-left:58.33333%}.col-offset-8\@sm{margin-left:66.66667%}.col-offset-9\@sm{margin-left:75%}.col-offset-10\@sm{margin-left:83.33333%}.col-offset-11\@sm{margin-left:91.66667%}.col-offset-12\@sm{margin-left:100%}.container{padding-left:7%;padding-right:7%}.row{max-width:1200px}}@media screen and (min-width:1024px){.col-1\@md,.col-2\@md,.col-3\@md,.col-4\@md,.col-5\@md,.col-6\@md,.col-7\@md,.col-8\@md,.col-9\@md,.col-10\@md,.col-11\@md,.col-12\@md{float:left}.aspect--16x9\@md{padding-bottom:56.25%}.aspect--9x16\@md{padding-bottom:177.77778%}.aspect--4x3\@md{padding-bottom:75%}.aspect--3x4\@md{padding-bottom:133.33333%}.aspect--3x2\@md{padding-bottom:66.66667%}.aspect--3x1\@md{padding-bottom:33.33333%}.aspect--2x3\@md{padding-bottom:150%}.aspect--2x1\@md{padding-bottom:50%}.aspect--1x2\@md{padding-bottom:200%}.aspect--1x1\@md{padding-bottom:100%}.aspect--none\@md{height:auto;padding-bottom:0;overflow:visible}.aspect--none\@md>.aspect__inner{position:static}.col-1\@md{width:8.33333%}.col-2\@md{width:16.66667%}.col-3\@md{width:25%}.col-4\@md{width:33.33333%}.col-5\@md{width:41.66667%}.col-6\@md{width:50%}.col-7\@md{width:58.33333%}.col-8\@md{width:66.66667%}.col-9\@md{width:75%}.col-10\@md{width:83.33333%}.col-11\@md{width:91.66667%}.col-12\@md{width:100%}.col-pull-0\@md{right:auto}.col-pull-1\@md{right:8.33333%}.col-pull-2\@md{right:16.66667%}.col-pull-3\@md{right:25%}.col-pull-4\@md{right:33.33333%}.col-pull-5\@md{right:41.66667%}.col-pull-6\@md{right:50%}.col-pull-7\@md{right:58.33333%}.col-pull-8\@md{right:66.66667%}.col-pull-9\@md{right:75%}.col-pull-10\@md{right:83.33333%}.col-pull-11\@md{right:91.66667%}.col-pull-12\@md{right:100%}.col-push-0\@md{left:auto}.col-push-1\@md{left:8.33333%}.col-push-2\@md{left:16.66667%}.col-push-3\@md{left:25%}.col-push-4\@md{left:33.33333%}.col-push-5\@md{left:41.66667%}.col-push-6\@md{left:50%}.col-push-7\@md{left:58.33333%}.col-push-8\@md{left:66.66667%}.col-push-9\@md{left:75%}.col-push-10\@md{left:83.33333%}.col-push-11\@md{left:91.66667%}.col-push-12\@md{left:100%}.col-offset-0\@md{margin-left:0}.col-offset-1\@md{margin-left:8.33333%}.col-offset-2\@md{margin-left:16.66667%}.col-offset-3\@md{margin-left:25%}.col-offset-4\@md{margin-left:33.33333%}.col-offset-5\@md{margin-left:41.66667%}.col-offset-6\@md{margin-left:50%}.col-offset-7\@md{margin-left:58.33333%}.col-offset-8\@md{margin-left:66.66667%}.col-offset-9\@md{margin-left:75%}.col-offset-10\@md{margin-left:83.33333%}.col-offset-11\@md{margin-left:91.66667%}.col-offset-12\@md{margin-left:100%}}.code-block{position:relative;overflow:visible;margin:.5em calc(-3.5vw - 8px)}.code-block pre{position:relative;z-index:1;min-height:56px;padding:1em calc(3.5vw + 8px);margin:0}@media screen and (min-width:768px){.code-block{margin-left:calc(-7vw - 8px);margin-right:calc(-7vw - 8px)}.code-block pre{position:relative;z-index:1;padding-left:calc(7vw + 8px);padding-right:calc(7vw + 8px)}}@media (min-width:1395px){.code-block{margin-left:calc((100vw - 1200px)/-2 - 8px);margin-right:calc((100vw - 1200px)/-2 - 8px)}.code-block pre{padding-left:calc((100vw - 1200px)/2 + 8px);padding-right:calc((100vw - 1200px)/2 + 8px)}}.textfield{-webkit-appearance:none;box-sizing:border-box;width:100%;border:2px solid #95a5a6;border-radius:4px;padding:.5em;font-size:1rem;color:#34495e;transition:.15s}.textfield::-webkit-input-placeholder{color:#95a5a6;transition:.15s}.textfield:-ms-input-placeholder{color:#95a5a6;transition:.15s}.textfield::-ms-input-placeholder{color:#95a5a6;transition:.15s}.textfield::placeholder{color:#95a5a6;transition:.15s}.textfield:hover{outline-width:0;color:#5d6d77;border-color:#5d6d77}.textfield:hover::-webkit-input-placeholder{color:#5d6d77}.textfield:hover:-ms-input-placeholder{color:#5d6d77}.textfield:hover::-ms-input-placeholder{color:#5d6d77}.textfield:hover::placeholder{color:#5d6d77}.textfield:focus{outline-width:0;border-color:#34495e}.textfield:focus::-webkit-input-placeholder{color:#34495e}.textfield:focus:-ms-input-placeholder{color:#34495e}.textfield:focus::-ms-input-placeholder{color:#34495e}.textfield:focus::placeholder{color:#34495e}.textfield--large{font-size:1.125em}.text-center{text-align:center}.ib{display:inline-block}@media screen and (max-width:767px){.hidden\@xs{display:none}}@media screen and (min-width:768px){.visible\@xs{display:none}}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.clearfix,.clearfix:after{content:" ";display:table;clear:both}.pull-left{float:left}.pull-right{float:right}.full-width{width:100%}.full-height{height:100%}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.table-center-wrap{display:table;table-layout:fixed}.table-center{display:table-cell;vertical-align:middle}.btn-group:after,.btn-group:before{content:" ";display:table}.btn-group:after{clear:both}.btn-group .btn{float:left;border-radius:0}.btn-group .btn:first-child{border-radius:3px 0 0 3px}.btn-group .btn:not(:first-child){margin-left:-1px}.btn-group .btn:last-child{border-radius:0 3px 3px 0}.btn-group label.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn{display:inline-block;padding:.75em .8em;text-align:center;border-radius:3px;border:1px solid #34495e;color:#34495e;font-size:1rem;background-color:rgba(52,73,94,0);transition:.2s ease-out;cursor:pointer;-webkit-appearance:none}@media (-moz-touch-enabled:0),(pointer:fine){.btn:hover{color:#fff;text-decoration:none;background-color:#34495e}}.btn:focus{outline-width:0;box-shadow:0 0 0 2px rgba(52,73,94,.4)}.btn.active,.btn:active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3);color:#fff;background-color:#34495e}.btn:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,73,94,.4)}.btn:disabled{cursor:not-allowed;opacity:.7;color:#34495e;background-color:rgba(52,73,94,0)}.btn--warning{color:#e67e22;border-color:#e67e22;background-color:rgba(230,126,34,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--warning:hover{background-color:#e67e22}}.btn--warning:focus{box-shadow:0 0 0 2px rgba(230,126,34,.4)}.btn--warning.active,.btn--warning:active{background-color:#e67e22}.btn--warning:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(230,126,34,.4)}.btn--warning:disabled{color:#e67e22;background-color:rgba(230,126,34,0)}.btn--primary{color:#3498db;border-color:#3498db;background-color:rgba(52,152,219,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--primary:hover{background-color:#3498db}}.btn--primary:focus{box-shadow:0 0 0 2px rgba(52,152,219,.4)}.btn--primary.active,.btn--primary:active{background-color:#3498db}.btn--primary:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,152,219,.4)}.btn--primary:disabled{color:#3498db;background-color:rgba(52,152,219,0)}.btn--danger{color:#e74c3c;border-color:#e74c3c;background-color:rgba(231,76,60,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--danger:hover{background-color:#e74c3c}}.btn--danger:focus{box-shadow:0 0 0 2px rgba(231,76,60,.4)}.btn--danger.active,.btn--danger:active{background-color:#e74c3c}.btn--danger:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(231,76,60,.4)}.btn--danger:disabled{color:#e74c3c;background-color:rgba(231,76,60,0)}.btn--go{color:#2ecc71;border-color:#2ecc71;background-color:rgba(46,204,113,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--go:hover{background-color:#2ecc71}}.btn--go:focus{box-shadow:0 0 0 2px rgba(46,204,113,.4)}.btn--go.active,.btn--go:active{background-color:#2ecc71}.btn--go:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(46,204,113,.4)}.btn--go:disabled{color:#2ecc71;background-color:rgba(46,204,113,0)}@media screen and (max-width:767px){.btn{font-size:.875rem}}.filter-group .btn{position:relative}.filter-group .btn.active:after,.filter-group .btn.active:before{content:"";position:absolute;top:50%;left:50%;width:20px;height:20px;margin-left:-10px;margin-top:-10px;opacity:0;transition:.2s}.filter-group .btn:before{background-color:#2c3e50;border-radius:50%}.filter-group .btn:after{background-size:60%;background-position:50%;background-repeat:no-repeat;background-image:url(../img/check.svg)}.filter-group .btn.active:after,.filter-group .btn.active:before{opacity:1}.demo-list .figure-wrap{position:relative;z-index:1}.demo-list .figure-wrap,.demo-list .figure-wrap img{-webkit-transform:translateZ(0);transform:translateZ(0);transition:.1s ease}.demo-list:hover .figure-wrap{-webkit-transform:scaleX(1);transform:scaleX(1)}.demo-list:hover .figure-wrap img{-webkit-filter:grayscale(1);filter:grayscale(1)}.demo-list:hover .figure-wrap:hover{z-index:2;-webkit-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1)}.demo-list:hover .figure-wrap:hover img{-webkit-filter:none;filter:none}.demo-list .figure-wrap:nth-child(4n+1){margin-left:0}.demo-list .figure-wrap>a{display:block}.demo-list .figure-wrap figcaption{height:2em;margin-top:.5em;margin-bottom:1em}.demo-link-container:before{content:"âžœ";color:#2ecc71;margin-right:5px}span.demo-link-container:before{margin-left:5px}@media screen and (max-width:47.9375em){.demo-list+.demo-list{margin-top:1em}.figure-wrap:nth-child(odd){margin-left:0}.figure-wrap:nth-child(n+3){margin-top:1em}}.site-nav{padding:10px 0;border-bottom:1px solid #e1e5e6;margin-bottom:28px;background:#ecf0f1}.site-nav__content{display:flex;justify-content:space-between}.site-nav__logo{font-size:20px}.site-nav__logo,.site-nav__logo:visited{color:#34495e}.site-nav__logo:hover,.site-nav__logo:visited:hover{text-decoration:none}.site-nav__links,.site-nav__logo{display:flex;align-items:center}.site-nav__logo svg{display:block;width:24px;height:24px;margin-right:4px}.site-nav__logo rect{transition:.18s cubic-bezier(.4,0,.2,1)}.site-nav__link{position:relative;z-index:3}.site-nav__link:not(:last-of-type){margin-right:8px}.site-nav__dropdown{position:absolute;z-index:2;top:40px;right:0;opacity:0;visibility:hidden;max-height:100vh;transition:.3s cubic-bezier(.165,.84,.44,1);background-color:#fff;-webkit-transform:translateY(10px);transform:translateY(10px);box-shadow:0 7px 10px -1px rgba(0,0,0,.12)}.site-nav__dropdown:before{content:"";position:absolute;top:-8px;right:32px;display:block;border-bottom:8px solid #fff;border-left:9px solid transparent;border-right:9px solid transparent}.site-nav__dropdown li+li{margin-top:8px}.site-nav__dropdown a{display:block;color:#5d6d77}.site-nav__dropdown a:hover{background-color:#ecf0f1;text-decoration:none;color:#5d6d77}.site-nav__dropdown figure{display:flex;align-items:center}.site-nav__dropdown picture{flex-shrink:0;width:100px;height:75px}.site-nav__dropdown figcaption{padding-left:8px;padding-right:8px}.site-nav__dropdown--simple-links a{padding:8px 16px}.site-nav__dropdown--simple-links li+li{margin-top:0}.site-nav__link-toggle{padding:6px 8px}.site-nav__link-toggle:after{content:"";display:inline-block;vertical-align:middle;margin-top:-1px;margin-left:4px;border-top:6px solid;border-left:5px solid transparent;border-right:5px solid transparent;transition:-webkit-transform .18s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.site-nav__link--dropdown-active .site-nav__link-toggle:after{-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.site-nav__link--dropdown-active .site-nav__dropdown{visibility:visible;opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}@media (-moz-touch-enabled:0),(pointer:fine){.site-nav__logo:hover rect:first-of-type{-webkit-transform:translate(20px,10px);transform:translate(20px,10px);transition-delay:0ms}.site-nav__logo:hover rect:nth-of-type(2){-webkit-transform:translateY(20px);transform:translateY(20px);transition-delay:10ms}.site-nav__logo:hover rect:nth-of-type(3){-webkit-transform:translate(-20px,6px);transform:translate(-20px,6px);transition-delay:20ms}.site-nav__logo:hover rect:nth-of-type(4){-webkit-transform:translate(10px,-10px);transform:translate(10px,-10px);transition-delay:30ms}.site-nav__logo:hover rect:nth-of-type(5){-webkit-transform:translate(-10px,10px);transform:translate(-10px,10px);transition-delay:40ms}.site-nav__logo:hover rect:nth-of-type(6){-webkit-transform:translate(-20px,-14px);transform:translate(-20px,-14px);transition-delay:50ms}.site-nav__logo:hover rect:nth-of-type(7){-webkit-transform:translateY(-20px);transform:translateY(-20px);transition-delay:60ms}.site-nav__link-toggle:hover{border-color:#34495e}}@media screen and (max-width:767px){body.site-nav--open{padding-top:51px}body.site-nav--open .site-nav{position:fixed;z-index:4;top:0;left:0;width:100%}.site-nav__dropdown{position:fixed;left:0;right:0;top:51px;width:100vw;padding:8px calc(3.5vw + 8px);overflow:auto;-webkit-overflow-scrolling:touch}}@media screen and (min-width:768px){.site-nav{padding:16px 0}.site-nav__logo{font-size:24px}.site-nav__logo svg{width:32px;height:32px}.site-nav__link:not(:last-child){margin-right:16px}.site-nav__link--dropdown:not(:last-child){margin-right:12px}.site-nav__dropdown{max-height:none!important;right:-100px;padding:16px;box-shadow:0 0 10px rgba(0,0,0,.12)}.site-nav__dropdown:before{right:132px}.site-nav__dropdown ul{-webkit-column-count:2;column-count:2;-webkit-column-gap:16px;column-gap:16px}.site-nav__dropdown li{-webkit-column-break-inside:avoid;page-break-inside:avoid;break-inside:avoid}.site-nav__dropdown figcaption{white-space:nowrap}@supports ((-webkit-filter:drop-shadow(0 0 5px rgba(0,0,0,0.12))) or (filter:drop-shadow(0 0 5px rgba(0,0,0,0.12)))){.site-nav__dropdown{box-shadow:none;-webkit-filter:drop-shadow(0 0 5px rgba(0,0,0,.12));filter:drop-shadow(0 0 5px rgba(0,0,0,.12))}}.site-nav__link-img{width:24px;height:24px}.site-nav__dropdown--simple-links{right:0;padding:0}.site-nav__dropdown--simple-links:before{right:24px}.site-nav__dropdown--simple-links a{width:200px}}@media screen and (min-width:1024px){.site-nav__dropdown{right:0}.site-nav__dropdown:before{right:32px}.site-nav__dropdown--simple-links:before{right:24px}}.site-footer{margin-top:2em;padding:1em 0;background-color:#34495e}.site-footer p{color:#ecf0f1}.site-footer a{color:#fff;text-decoration:underline}.site-footer a:hover{color:#3498db}.has-code-block .code-block pre{margin-bottom:0}.has-code-block+.site-footer{margin-top:0}@media screen and (min-width:768px){.site-footer__credit{text-align:right}}.filter-label{display:block;padding:0;margin-top:0;margin-bottom:4px;color:#95a5a6}.filters-group{padding:0;margin:0 0 4px;border:0}@media screen and (min-width:768px){.filters-group-wrap{display:flex;justify-content:space-between}}.compound-filter-options{margin-top:20px;margin-bottom:40px}.filter-group--compound button{width:40px;height:40px;padding:0;background-color:currentColor}.filter-group--compound label{cursor:pointer}.filter-group--compound .ib+.ib{margin-left:8px}.shape-shuffle-container{position:relative;overflow:hidden}.shape{position:relative;margin-left:0;margin-top:10px}.shape .shape__space{width:100%;height:100%;background-color:#000;border:0 solid transparent}.shape--blue .shape__space{background-color:#3498db;border-bottom-color:#3498db}.shape--red .shape__space{background-color:#e74c3c;border-bottom-color:#e74c3c}.shape--orange .shape__space{background-color:#f39c12;border-bottom-color:#f39c12}.shape--green .shape__space{background-color:#2ecc71;border-bottom-color:#2ecc71}.shape--circle .shape__space{border-radius:50%}.shape--diamond .shape__space{-webkit-transform:rotate(45deg) scale(.70711);transform:rotate(45deg) scale(.70711)}.shape--triangle .shape__space{padding-top:9px;height:0;width:0;border-width:0 66px 114px;background-color:transparent;margin:auto}@media (min-width:425px){.shape--triangle .shape__space{padding-top:12px;height:0;width:0;border-width:0 90px 156px}}@media (min-width:600px){.shape--triangle .shape__space{padding-top:17.5px;height:0;width:0;border-width:0 131px 227px}}@media (min-width:768px){.shape--triangle .shape__space{padding-top:10px;height:0;width:0;border-width:0 74px 128px}}@media (min-width:1024px){.shape--triangle .shape__space{padding-top:13.5px;height:0;width:0;border-width:0 102px 177px}}@media (min-width:1200px){.shape--triangle .shape__space{padding-top:18px;height:0;width:0;border-width:0 135px 234px}}@media (min-width:1392px){.shape--triangle .shape__space{padding-top:19px;height:0;width:0;border-width:0 142px 246px}}.search-section{margin-top:1em;margin-bottom:1em}.question{float:none;margin:2em 0;overflow:hidden;transition:.2s ease-out}.question--collapsed{height:0!important;margin:0;border-width:0}.question--collapsed+.question{margin-top:0}.question--unanswered{padding-top:1.25em;border-top:2px solid #2ecc71}.question__title{margin-top:0}.question__answer{padding-bottom:1px;margin-bottom:0} \ No newline at end of file diff --git a/docs/dist/shuffle.js b/docs/dist/shuffle.js index ec12132..40d3ae5 100644 --- a/docs/dist/shuffle.js +++ b/docs/dist/shuffle.js @@ -4,6 +4,75 @@ (global.Shuffle = factory()); }(this, (function () { 'use strict'; + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); + if (superClass) _setPrototypeOf(subClass, superClass); + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + function _possibleConstructorReturn(self, call) { + if (call && (typeof call === "object" || typeof call === "function")) { + return call; + } + + return _assertThisInitialized(self); + } + function E () { // Keep this empty so it's easier to inherit from // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) @@ -182,67 +251,20 @@ return parseFloat(value) || 0; } - var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - }; - - var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); - - var inherits = function (subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true - } - }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - }; - - var possibleConstructorReturn = function (self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return call && (typeof call === "object" || typeof call === "function") ? call : self; - }; - - var Point = function () { + var Point = + /*#__PURE__*/ + function () { /** * Represents a coordinate pair. * @param {number} [x=0] X. * @param {number} [y=0] Y. */ function Point(x, y) { - classCallCheck(this, Point); + _classCallCheck(this, Point); this.x = getNumber(x); this.y = getNumber(y); } - /** * Whether two points are equal. * @param {Point} a Point A. @@ -251,16 +273,19 @@ */ - createClass(Point, null, [{ - key: 'equals', + _createClass(Point, null, [{ + key: "equals", value: function equals(a, b) { return a.x === b.x && a.y === b.y; } }]); + return Point; }(); - var Rect = function () { + var Rect = + /*#__PURE__*/ + function () { /** * Class for representing rectangular regions. * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js @@ -272,23 +297,22 @@ * @constructor */ function Rect(x, y, w, h, id) { - classCallCheck(this, Rect); + _classCallCheck(this, Rect); this.id = id; - /** @type {number} */ - this.left = x; + this.left = x; /** @type {number} */ - this.top = y; + this.top = y; /** @type {number} */ - this.width = w; + this.width = w; /** @type {number} */ + this.height = h; } - /** * Returns whether two rectangles intersect. * @param {Rect} a A Rectangle. @@ -297,12 +321,13 @@ */ - createClass(Rect, null, [{ + _createClass(Rect, null, [{ key: "intersects", value: function intersects(a, b) { return a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height; } }]); + return Rect; }(); @@ -313,32 +338,34 @@ HIDDEN: 'shuffle-item--hidden' }; - var id = 0; + var id$1 = 0; - var ShuffleItem = function () { + var ShuffleItem = + /*#__PURE__*/ + function () { function ShuffleItem(element) { - classCallCheck(this, ShuffleItem); + _classCallCheck(this, ShuffleItem); - id += 1; - this.id = id; + id$1 += 1; + this.id = id$1; this.element = element; - /** * Used to separate items for layout and shrink. */ - this.isVisible = true; + this.isVisible = true; /** * Used to determine if a transition will happen. By the time the _layout * and _shrink methods get the ShuffleItem instances, the `isVisible` value * has already been changed by the separation methods, so this property is * needed to know if the item was visible/hidden before the shrink/layout. */ + this.isHidden = false; } - createClass(ShuffleItem, [{ - key: 'show', + _createClass(ShuffleItem, [{ + key: "show", value: function show() { this.isVisible = true; this.element.classList.remove(Classes.HIDDEN); @@ -346,7 +373,7 @@ this.element.removeAttribute('aria-hidden'); } }, { - key: 'hide', + key: "hide", value: function hide() { this.isVisible = false; this.element.classList.remove(Classes.VISIBLE); @@ -354,7 +381,7 @@ this.element.setAttribute('aria-hidden', true); } }, { - key: 'init', + key: "init", value: function init() { this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]); this.applyCss(ShuffleItem.Css.INITIAL); @@ -362,7 +389,7 @@ this.point = new Point(); } }, { - key: 'addClasses', + key: "addClasses", value: function addClasses(classes) { var _this = this; @@ -371,7 +398,7 @@ }); } }, { - key: 'removeClasses', + key: "removeClasses", value: function removeClasses(classes) { var _this2 = this; @@ -380,7 +407,7 @@ }); } }, { - key: 'applyCss', + key: "applyCss", value: function applyCss(obj) { var _this3 = this; @@ -389,14 +416,14 @@ }); } }, { - key: 'dispose', + key: "dispose", value: function dispose() { this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); - this.element.removeAttribute('style'); this.element = null; } }]); + return ShuffleItem; }(); @@ -427,7 +454,6 @@ } } }; - ShuffleItem.Scale = { VISIBLE: 1, HIDDEN: 0.001 @@ -443,11 +469,8 @@ var e = document.createElement('div'); e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;'; element.appendChild(e); - value = window.getComputedStyle(e, null).width === '10px'; - element.removeChild(e); - return value; }); @@ -461,12 +484,11 @@ * will return 'auto' when the element doesn't have margins instead of * the computed style. */ + function getNumberStyle(element, style) { var styles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window.getComputedStyle(element, null); + var value = getNumber(styles[style]); // Support IE<=11 and W3C spec. - var value = getNumber(styles[style]); - - // Support IE<=11 and W3C spec. if (!testComputedSize() && style === 'width') { value += getNumber(styles.paddingLeft) + getNumber(styles.paddingRight) + getNumber(styles.borderLeftWidth) + getNumber(styles.borderRightWidth); } else if (!testComputedSize() && style === 'height') { @@ -497,27 +519,22 @@ return array; } - var defaults$1 = { + var defaults = { // Use array.reverse() to reverse the results reverse: false, - // Sorting function by: null, - // Custom sort function compare: null, - // If true, this will skip the sorting and return a randomized order in the array randomize: false, - // Determines which property of each item in the array is passed to the // sorting method. key: 'element' - }; + }; // You can return `undefined` from the `by` function to revert to DOM order. - // You can return `undefined` from the `by` function to revert to DOM order. function sorter(arr, options) { - var opts = Object.assign({}, defaults$1, options); + var opts = Object.assign({}, defaults, options); var original = Array.from(arr); var revert = false; @@ -527,10 +544,10 @@ if (opts.randomize) { return randomize(arr); - } - - // Sort the elements by the opts.by function. + } // Sort the elements by the opts.by function. // If we don't have opts.by, default to DOM order + + if (typeof opts.by === 'function') { arr.sort(function (a, b) { // Exit early if we already know we want to revert @@ -539,9 +556,8 @@ } var valA = opts.by(a[opts.key]); - var valB = opts.by(b[opts.key]); + var valB = opts.by(b[opts.key]); // If both values are undefined, use the DOM order - // If both values are undefined, use the DOM order if (valA === undefined && valB === undefined) { revert = true; return 0; @@ -559,9 +575,9 @@ }); } else if (typeof opts.compare === 'function') { arr.sort(opts.compare); - } + } // Revert to the original array if necessary + - // Revert to the original array if necessary if (revert) { return original; } @@ -591,9 +607,9 @@ return false; } - function onTransitionEnd(element, callback) { var id = uniqueId(); + var listener = function listener(evt) { if (evt.currentTarget === evt.target) { cancelTransitionEnd(id); @@ -602,9 +618,10 @@ }; element.addEventListener(eventName, listener); - - transitions[id] = { element: element, listener: listener }; - + transitions[id] = { + element: element, + listener: listener + }; return id; } @@ -624,34 +641,32 @@ * @param {number} threshold A buffer value for the size of the column to fit. * @return {number} */ - function getColumnSpan(itemWidth, columnWidth, columns, threshold) { - var columnSpan = itemWidth / columnWidth; - // If the difference between the rounded column span number and the + function getColumnSpan(itemWidth, columnWidth, columns, threshold) { + var columnSpan = itemWidth / columnWidth; // If the difference between the rounded column span number and the // calculated column span number is really small, round the number to // make it fit. + if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) { // e.g. columnSpan = 4.0089945390298745 columnSpan = Math.round(columnSpan); - } + } // Ensure the column span is not more than the amount of columns in the whole layout. + - // Ensure the column span is not more than the amount of columns in the whole layout. return Math.min(Math.ceil(columnSpan), columns); } - /** * Retrieves the column set to use for placement. * @param {number} columnSpan The number of columns this current item spans. * @param {number} columns The total columns in the grid. * @return {Array.} An array of numbers represeting the column set. */ + function getAvailablePositions(positions, columnSpan, columns) { // The item spans only one column. if (columnSpan === 1) { return positions; - } - - // The item spans more than one column, figure out how many different + } // The item spans more than one column, figure out how many different // places it could fit horizontally. // The group count is the number of places within the positions this block // could fit, ignoring the current positions of items. @@ -673,9 +688,10 @@ // // Another example where the second column's item extends past the first: // [10, 20, 10, 0] => [20, 20, 10] => 10 - var available = []; - // For how many possible positions for this item there are. + + var available = []; // For how many possible positions for this item there are. + for (var i = 0; i <= columns - columnSpan; i++) { // Find the bigger value for each place it could fit. available.push(arrayMax(positions.slice(i, i + columnSpan))); @@ -683,7 +699,6 @@ return available; } - /** * Find index of short column, the first from the left where this item will go. * @@ -692,8 +707,10 @@ * is a percentage of the width. * @return {number} Index of the short column. */ + function getShortColumn(positions, buffer) { var minPosition = arrayMin(positions); + for (var i = 0, len = positions.length; i < len; i++) { if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) { return i; @@ -702,7 +719,6 @@ return 0; } - /** * Determine the location of the next item, based on its size. * @param {Object} itemSize Object with width and height. @@ -713,6 +729,7 @@ * @param {number} buffer Vertical buffer for the height of items. * @return {Point} */ + function getItemPosition(_ref) { var itemSize = _ref.itemSize, positions = _ref.positions, @@ -720,25 +737,22 @@ total = _ref.total, threshold = _ref.threshold, buffer = _ref.buffer; - var span = getColumnSpan(itemSize.width, gridSize, total, threshold); var setY = getAvailablePositions(positions, span, total); - var shortColumnIndex = getShortColumn(setY, buffer); + var shortColumnIndex = getShortColumn(setY, buffer); // Position the item - // Position the item - var point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); - - // Update the columns array with the new values for each column. + var point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); // Update the columns array with the new values for each column. // e.g. before the update the columns could be [250, 0, 0, 0] for an item // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0]. + var setHeight = setY[shortColumnIndex] + itemSize.height; + for (var i = 0; i < span; i++) { positions[shortColumnIndex + i] = setHeight; } return point; } - /** * This method attempts to center items. This method could potentially be slow * with a large number of items because it must place items, then check every @@ -747,12 +761,12 @@ * @param {number} containerWidth Width of the containing element. * @return {Array.} */ - function getCenteredPositions(itemRects, containerWidth) { - var rowMap = {}; - // Populate rows by their offset because items could jump between rows like: + function getCenteredPositions(itemRects, containerWidth) { + var rowMap = {}; // Populate rows by their offset because items could jump between rows like: // a c // bbb + itemRects.forEach(function (itemRect) { if (rowMap[itemRect.top]) { // Push the point to the last row array. @@ -761,11 +775,10 @@ // Start of a new row. rowMap[itemRect.top] = [itemRect]; } - }); - - // For each row, find the end of the last item, then calculate + }); // For each row, find the end of the last item, then calculate // the remaining space by dividing it by 2. Then add that // offset to the x position of each point. + var rects = []; var rows = []; var centeredRows = []; @@ -775,45 +788,43 @@ var lastItem = itemRects[itemRects.length - 1]; var end = lastItem.left + lastItem.width; var offset = Math.round((containerWidth - end) / 2); - var finalRects = itemRects; var canMove = false; + if (offset > 0) { var newRects = []; canMove = itemRects.every(function (r) { - var newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); + var newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); // Check all current rects to make sure none overlap. - // Check all current rects to make sure none overlap. var noOverlap = !rects.some(function (r) { return Rect.intersects(newRect, r); }); - newRects.push(newRect); return noOverlap; - }); + }); // If none of the rectangles overlapped, the whole group can be centered. - // If none of the rectangles overlapped, the whole group can be centered. if (canMove) { finalRects = newRects; } - } - - // If the items are not going to be offset, ensure that the original + } // If the items are not going to be offset, ensure that the original // placement for this row will not overlap previous rows (row-spanning // elements could be in the way). + + if (!canMove) { - var intersectingRect = void 0; + var intersectingRect; var hasOverlap = itemRects.some(function (itemRect) { return rects.some(function (r) { var intersects = Rect.intersects(itemRect, r); + if (intersects) { intersectingRect = r; } + return intersects; }); - }); + }); // If there is any overlap, replace the overlapping row with the original. - // If there is any overlap, replace the overlapping row with the original. if (hasOverlap) { var rowIndex = centeredRows.findIndex(function (items) { return items.includes(intersectingRect); @@ -824,12 +835,11 @@ rects = rects.concat(finalRects); centeredRows.push(finalRects); - }); - - // Reduce array of arrays to a single array of points. + }); // Reduce array of arrays to a single array of points. // https://stackoverflow.com/a/10865042/373422 // Then reset sort back to how the items were passed to this method. // Remove the wrapper object with index, map to a Point. + return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread .sort(function (a, b) { return a.id - b.id; @@ -846,19 +856,21 @@ */ function hyphenate(str) { return str.replace(/([A-Z])/g, function (str, m1) { - return "-" + m1.toLowerCase(); + return "-".concat(m1.toLowerCase()); }); } function arrayUnique(x) { return Array.from(new Set(x)); - } + } // Used for unique instance variables - // Used for unique instance variables - var id$1 = 0; - var Shuffle = function (_TinyEmitter) { - inherits(Shuffle, _TinyEmitter); + var id$2 = 0; + + var Shuffle = + /*#__PURE__*/ + function (_TinyEmitter) { + _inherits(Shuffle, _TinyEmitter); /** * Categorize, sort, and filter a responsive grid of items. @@ -868,15 +880,16 @@ * @constructor */ function Shuffle(element) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - classCallCheck(this, Shuffle); + var _this; - var _this = possibleConstructorReturn(this, (Shuffle.__proto__ || Object.getPrototypeOf(Shuffle)).call(this)); + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - _this.options = Object.assign({}, Shuffle.options, options); + _classCallCheck(this, Shuffle); - // Allow misspelling of delimiter since that's how it used to be. + _this = _possibleConstructorReturn(this, _getPrototypeOf(Shuffle).call(this)); + _this.options = Object.assign({}, Shuffle.options, options); // Allow misspelling of delimiter since that's how it used to be. // Remove in v6. + if (_this.options.delimeter) { _this.options.delimiter = _this.options.delimeter; } @@ -898,65 +911,60 @@ } _this.element = el; - _this.id = 'shuffle_' + id$1; - id$1 += 1; + _this.id = 'shuffle_' + id$2; + id$2 += 1; _this._init(); + _this.isInitialized = true; return _this; } - createClass(Shuffle, [{ - key: '_init', + _createClass(Shuffle, [{ + key: "_init", value: function _init() { this.items = this._getItems(); + this.options.sizer = this._getElementOption(this.options.sizer); // Add class and invalidate styles - this.options.sizer = this._getElementOption(this.options.sizer); + this.element.classList.add(Shuffle.Classes.BASE); // Set initial css for each item - // Add class and invalidate styles - this.element.classList.add(Shuffle.Classes.BASE); + this._initItems(this.items); // Bind resize events - // Set initial css for each item - this._initItems(this.items); - // Bind resize events this._onResize = this._getResizeFunction(); - window.addEventListener('resize', this._onResize); - - // If the page has not already emitted the `load` event, call layout on load. + window.addEventListener('resize', this._onResize); // If the page has not already emitted the `load` event, call layout on load. // This avoids layout issues caused by images and fonts loading after the // instance has been initialized. + if (document.readyState !== 'complete') { var layout = this.layout.bind(this); window.addEventListener('load', function onLoad() { window.removeEventListener('load', onLoad); layout(); }); - } + } // Get container css all in one request. Causes reflow - // Get container css all in one request. Causes reflow - var containerCss = window.getComputedStyle(this.element, null); - var containerWidth = Shuffle.getSize(this.element).width; - // Add styles to the container if it doesn't have them. - this._validateStyles(containerCss); + var containerCss = window.getComputedStyle(this.element, null); + var containerWidth = Shuffle.getSize(this.element).width; // Add styles to the container if it doesn't have them. - // We already got the container's width above, no need to cause another + this._validateStyles(containerCss); // We already got the container's width above, no need to cause another // reflow getting it again... Calculate the number of columns there will be - this._setColumns(containerWidth); - // Kick off! - this.filter(this.options.group, this.options.initialSort); - // The shuffle items haven't had transitions set on them yet so the user + this._setColumns(containerWidth); // Kick off! + + + this.filter(this.options.group, this.options.initialSort); // The shuffle items haven't had transitions set on them yet so the user // doesn't see the first layout. Set them now that the first layout is done. // First, however, a synchronous layout must be caused for the previous // styles to be applied without transitions. + this.element.offsetWidth; // eslint-disable-line no-unused-expressions + this.setItemTransitions(this.items); - this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing; + this.element.style.transition = "height ".concat(this.options.speed, "ms ").concat(this.options.easing); } - /** * Returns a throttled and proxied function for the resize handler. * @return {function} @@ -964,12 +972,12 @@ */ }, { - key: '_getResizeFunction', + key: "_getResizeFunction", value: function _getResizeFunction() { var resizeFunction = this._handleResize.bind(this); + return this.options.throttle ? this.options.throttle(resizeFunction, this.options.throttleTime) : resizeFunction; } - /** * Retrieve an element from an option. * @param {string|jQuery|Element} option The option to check. @@ -978,25 +986,20 @@ */ }, { - key: '_getElementOption', + key: "_getElementOption", value: function _getElementOption(option) { // If column width is a string, treat is as a selector and search for the // sizer element within the outermost container if (typeof option === 'string') { - return this.element.querySelector(option); - - // Check for an element + return this.element.querySelector(option); // Check for an element } else if (option && option.nodeType && option.nodeType === 1) { - return option; - - // Check for jQuery object + return option; // Check for jQuery object } else if (option && option.jquery) { return option[0]; } return null; } - /** * Ensures the shuffle container has the css styles it needs applied to it. * @param {Object} styles Key value pairs for position and overflow. @@ -1004,19 +1007,18 @@ */ }, { - key: '_validateStyles', + key: "_validateStyles", value: function _validateStyles(styles) { // Position cannot be static. if (styles.position === 'static') { this.element.style.position = 'relative'; - } + } // Overflow has to be hidden. + - // Overflow has to be hidden. if (styles.overflow !== 'hidden') { this.element.style.overflow = 'hidden'; } } - /** * Filter the elements by a category. * @param {string|string[]|function(Element):boolean} [category] Category to @@ -1028,28 +1030,26 @@ */ }, { - key: '_filter', + key: "_filter", value: function _filter() { var category = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastFilter; var collection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.items; - var set$$1 = this._getFilteredSets(category, collection); + var set = this._getFilteredSets(category, collection); // Individually add/remove hidden/visible classes - // Individually add/remove hidden/visible classes - this._toggleFilterClasses(set$$1); - // Save the last filter in case elements are appended. - this.lastFilter = category; + this._toggleFilterClasses(set); // Save the last filter in case elements are appended. - // This is saved mainly because providing a filter function (like searching) + + this.lastFilter = category; // This is saved mainly because providing a filter function (like searching) // will overwrite the `lastFilter` property every time its called. + if (typeof category === 'string') { this.group = category; } - return set$$1; + return set; } - /** * Returns an object containing the visible and hidden elements. * @param {string|string[]|function(Element):boolean} category Category or function to filter by. @@ -1059,18 +1059,15 @@ */ }, { - key: '_getFilteredSets', + key: "_getFilteredSets", value: function _getFilteredSets(category, items) { var _this2 = this; var visible = []; - var hidden = []; + var hidden = []; // category === 'all', add visible class to everything - // category === 'all', add visible class to everything if (category === Shuffle.ALL_ITEMS) { - visible = items; - - // Loop through each item and use provided function to determine + visible = items; // Loop through each item and use provided function to determine // whether to hide it or not. } else { items.forEach(function (item) { @@ -1087,7 +1084,6 @@ hidden: hidden }; } - /** * Test an item to see if it passes a category. * @param {string|string[]|function():boolean} category Category or function to filter by. @@ -1097,13 +1093,13 @@ */ }, { - key: '_doesPassFilter', + key: "_doesPassFilter", value: function _doesPassFilter(category, element) { if (typeof category === 'function') { return category.call(element, element, this); - } + } // Check each element's data-groups attribute against the given category. + - // Check each element's data-groups attribute against the given category. var attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); var keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); @@ -1115,12 +1111,12 @@ if (this.options.filterMode === Shuffle.FilterMode.ANY) { return category.some(testCategory); } + return category.every(testCategory); } return keys.includes(category); } - /** * Toggles the visible and hidden class names. * @param {{visible, hidden}} Object with visible and hidden arrays. @@ -1128,20 +1124,17 @@ */ }, { - key: '_toggleFilterClasses', + key: "_toggleFilterClasses", value: function _toggleFilterClasses(_ref) { var visible = _ref.visible, hidden = _ref.hidden; - visible.forEach(function (item) { item.show(); }); - hidden.forEach(function (item) { item.hide(); }); } - /** * Set the initial css for each item * @param {ShuffleItem[]} items Set to initialize. @@ -1149,13 +1142,12 @@ */ }, { - key: '_initItems', + key: "_initItems", value: function _initItems(items) { items.forEach(function (item) { item.init(); }); } - /** * Remove element reference and styles. * @param {ShuffleItem[]} items Set to dispose. @@ -1163,24 +1155,22 @@ */ }, { - key: '_disposeItems', + key: "_disposeItems", value: function _disposeItems(items) { items.forEach(function (item) { item.dispose(); }); } - /** * Updates the visible item count. * @private */ }, { - key: '_updateItemCount', + key: "_updateItemCount", value: function _updateItemCount() { this.visibleItems = this._getFilteredItems().length; } - /** * Sets css transform transition on a group of elements. This is not executed * at the same time as `item.init` so that transitions don't occur upon @@ -1190,21 +1180,18 @@ */ }, { - key: 'setItemTransitions', + key: "setItemTransitions", value: function setItemTransitions(items) { - var _options = this.options, - speed = _options.speed, - easing = _options.easing; - - var positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; - - // Allow users to transtion other properties if they exist in the `before` + var _this$options = this.options, + speed = _this$options.speed, + easing = _this$options.easing; + var positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; // Allow users to transtion other properties if they exist in the `before` // css mapping of the shuffle item. + var cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(function (k) { return hyphenate(k); }); var properties = positionProps.concat(cssProps).join(); - items.forEach(function (item) { item.element.style.transitionDuration = speed + 'ms'; item.element.style.transitionTimingFunction = easing; @@ -1212,7 +1199,7 @@ }); } }, { - key: '_getItems', + key: "_getItems", value: function _getItems() { var _this3 = this; @@ -1222,7 +1209,6 @@ return new ShuffleItem(el); }); } - /** * Combine the current items array with a new one and sort it by DOM order. * @param {ShuffleItem[]} items Items to track. @@ -1230,7 +1216,7 @@ */ }, { - key: '_mergeNewItems', + key: "_mergeNewItems", value: function _mergeNewItems(items) { var children = Array.from(this.element.children); return sorter(this.items.concat(items), { @@ -1240,20 +1226,19 @@ }); } }, { - key: '_getFilteredItems', + key: "_getFilteredItems", value: function _getFilteredItems() { return this.items.filter(function (item) { return item.isVisible; }); } }, { - key: '_getConcealedItems', + key: "_getConcealedItems", value: function _getConcealedItems() { return this.items.filter(function (item) { return !item.isVisible; }); } - /** * Returns the column size, based on column width and sizer options. * @param {number} containerWidth Size of the parent container. @@ -1263,39 +1248,29 @@ */ }, { - key: '_getColumnSize', + key: "_getColumnSize", value: function _getColumnSize(containerWidth, gutterSize) { - var size = void 0; + var size; // If the columnWidth property is a function, then the grid is fluid - // If the columnWidth property is a function, then the grid is fluid if (typeof this.options.columnWidth === 'function') { - size = this.options.columnWidth(containerWidth); - - // columnWidth option isn't a function, are they using a sizing element? + size = this.options.columnWidth(containerWidth); // columnWidth option isn't a function, are they using a sizing element? } else if (this.options.sizer) { - size = Shuffle.getSize(this.options.sizer).width; - - // if not, how about the explicitly set option? + size = Shuffle.getSize(this.options.sizer).width; // if not, how about the explicitly set option? } else if (this.options.columnWidth) { - size = this.options.columnWidth; - - // or use the size of the first item + size = this.options.columnWidth; // or use the size of the first item } else if (this.items.length > 0) { - size = Shuffle.getSize(this.items[0].element, true).width; - - // if there's no items, use size of container + size = Shuffle.getSize(this.items[0].element, true).width; // if there's no items, use size of container } else { size = containerWidth; - } + } // Don't let them set a column width of zero. + - // Don't let them set a column width of zero. if (size === 0) { size = containerWidth; } return size + gutterSize; } - /** * Returns the gutter size, based on gutter width and sizer options. * @param {number} containerWidth Size of the parent container. @@ -1304,9 +1279,10 @@ */ }, { - key: '_getGutterSize', + key: "_getGutterSize", value: function _getGutterSize(containerWidth) { - var size = void 0; + var size; + if (typeof this.options.gutterWidth === 'function') { size = this.options.gutterWidth(containerWidth); } else if (this.options.sizer) { @@ -1317,7 +1293,6 @@ return size; } - /** * Calculate the number of columns to be used. Gets css if using sizer element. * @param {number} [containerWidth] Optionally specify a container width if @@ -1325,15 +1300,16 @@ */ }, { - key: '_setColumns', + key: "_setColumns", value: function _setColumns() { var containerWidth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Shuffle.getSize(this.element).width; var gutter = this._getGutterSize(containerWidth); + var columnWidth = this._getColumnSize(containerWidth, gutter); - var calculatedColumns = (containerWidth + gutter) / columnWidth; - // Widths given from getStyles are not precise enough... + var calculatedColumns = (containerWidth + gutter) / columnWidth; // Widths given from getStyles are not precise enough... + if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) < this.options.columnThreshold) { // e.g. calculatedColumns = 11.998876 calculatedColumns = Math.round(calculatedColumns); @@ -1343,17 +1319,15 @@ this.containerWidth = containerWidth; this.colWidth = columnWidth; } - /** * Adjust the height of the grid */ }, { - key: '_setContainerSize', + key: "_setContainerSize", value: function _setContainerSize() { this.element.style.height = this._getContainerSize() + 'px'; } - /** * Based on the column heights, it returns the biggest one. * @return {number} @@ -1361,11 +1335,10 @@ */ }, { - key: '_getContainerSize', + key: "_getContainerSize", value: function _getContainerSize() { return arrayMax(this.positions); } - /** * Get the clamped stagger amount. * @param {number} index Index of the item to be staggered. @@ -1373,11 +1346,10 @@ */ }, { - key: '_getStaggerAmount', + key: "_getStaggerAmount", value: function _getStaggerAmount(index) { return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax); } - /** * Emit an event from this instance. * @param {string} name Event name. @@ -1385,7 +1357,7 @@ */ }, { - key: '_dispatch', + key: "_dispatch", value: function _dispatch(name) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -1396,23 +1368,22 @@ data.shuffle = this; this.emit(name, data); } - /** * Zeros out the y columns array, which is used to determine item placement. * @private */ }, { - key: '_resetCols', + key: "_resetCols", value: function _resetCols() { var i = this.cols; this.positions = []; + while (i) { i -= 1; this.positions.push(0); } } - /** * Loops through each item that should be shown and calculates the x, y position. * @param {ShuffleItem[]} items Array of items that will be shown/layed @@ -1420,7 +1391,7 @@ */ }, { - key: '_layout', + key: "_layout", value: function _layout(items) { var _this4 = this; @@ -1430,10 +1401,10 @@ items.forEach(function (item, i) { function callback() { item.applyCss(ShuffleItem.Css.VISIBLE.after); - } - - // If the item will not change its position, do not add it to the render + } // If the item will not change its position, do not add it to the render // queue. Transitions don't fire when setting a property to the same value. + + if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) { item.applyCss(ShuffleItem.Css.VISIBLE.before); callback(); @@ -1442,11 +1413,11 @@ item.point = itemPositions[i]; item.scale = ShuffleItem.Scale.VISIBLE; - item.isHidden = false; - - // Clone the object so that the `before` object isn't modified when the + item.isHidden = false; // Clone the object so that the `before` object isn't modified when the // transition delay is added. + var styles = _this4.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before); + styles.transitionDelay = _this4._getStaggerAmount(count) + 'ms'; _this4._queue.push({ @@ -1458,7 +1429,6 @@ count += 1; }); } - /** * Return an array of Point instances representing the future positions of * each item. @@ -1468,7 +1438,7 @@ */ }, { - key: '_getNextPositions', + key: "_getNextPositions", value: function _getNextPositions(items) { var _this5 = this; @@ -1477,20 +1447,20 @@ if (this.options.isCentered) { var itemsData = items.map(function (item, i) { var itemSize = Shuffle.getSize(item.element, true); + var point = _this5._getItemPosition(itemSize); + return new Rect(point.x, point.y, itemSize.width, itemSize.height, i); }); - return this.getTransformedPositions(itemsData, this.containerWidth); - } - - // If no transforms are going to happen, simply return an array of the + } // If no transforms are going to happen, simply return an array of the // future points of each item. + + return items.map(function (item) { return _this5._getItemPosition(Shuffle.getSize(item.element, true)); }); } - /** * Determine the location of the next item, based on its size. * @param {{width: number, height: number}} itemSize Object with width and height. @@ -1499,7 +1469,7 @@ */ }, { - key: '_getItemPosition', + key: "_getItemPosition", value: function _getItemPosition(itemSize) { return getItemPosition({ itemSize: itemSize, @@ -1510,7 +1480,6 @@ buffer: this.options.buffer }); } - /** * Mutate positions before they're applied. * @param {Rect[]} itemRects Item data objects. @@ -1520,11 +1489,10 @@ */ }, { - key: 'getTransformedPositions', + key: "getTransformedPositions", value: function getTransformedPositions(itemRects, containerWidth) { return getCenteredPositions(itemRects, containerWidth); } - /** * Hides the elements that don't match our filter. * @param {ShuffleItem[]} collection Collection to shrink. @@ -1532,24 +1500,23 @@ */ }, { - key: '_shrink', + key: "_shrink", value: function _shrink() { var _this6 = this; var collection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._getConcealedItems(); - var count = 0; collection.forEach(function (item) { function callback() { item.applyCss(ShuffleItem.Css.HIDDEN.after); - } - - // Continuing would add a transitionend event listener to the element, but + } // Continuing would add a transitionend event listener to the element, but // that listener would not execute because the transform and opacity would // stay the same. // The callback is executed here because it is not guaranteed to be called // after the transitionend event because the transitionend could be // canceled if another animation starts. + + if (item.isHidden) { item.applyCss(ShuffleItem.Css.HIDDEN.before); callback(); @@ -1560,6 +1527,7 @@ item.isHidden = true; var styles = _this6.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before); + styles.transitionDelay = _this6._getStaggerAmount(count) + 'ms'; _this6._queue.push({ @@ -1571,14 +1539,13 @@ count += 1; }); } - /** * Resize handler. * @private */ }, { - key: '_handleResize', + key: "_handleResize", value: function _handleResize() { // If shuffle is disabled, destroyed, don't do anything if (!this.isEnabled || this.isDestroyed) { @@ -1587,7 +1554,6 @@ this.update(); } - /** * Returns styles which will be applied to the an item for a transition. * @param {ShuffleItem} item Item to get styles for. Should have updated @@ -1598,7 +1564,7 @@ */ }, { - key: 'getStylesForTransition', + key: "getStylesForTransition", value: function getStylesForTransition(item, styleObject) { // Clone the object to avoid mutating the original. var styles = Object.assign({}, styleObject); @@ -1606,7 +1572,7 @@ if (this.options.useTransforms) { var x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x; var y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y; - styles.transform = 'translate(' + x + 'px, ' + y + 'px) scale(' + item.scale + ')'; + styles.transform = "translate(".concat(x, "px, ").concat(y, "px) scale(").concat(item.scale, ")"); } else { styles.left = item.point.x + 'px'; styles.top = item.point.y + 'px'; @@ -1614,7 +1580,6 @@ return styles; } - /** * Listen for the transition end on an element and execute the itemCallback * when it finishes. @@ -1624,7 +1589,7 @@ */ }, { - key: '_whenTransitionDone', + key: "_whenTransitionDone", value: function _whenTransitionDone(element, itemCallback, done) { var id = onTransitionEnd(element, function (evt) { itemCallback(); @@ -1633,7 +1598,6 @@ this._transitions.push(id); } - /** * Return a function which will set CSS styles and call the `done` function * when (if) the transition finishes. @@ -1642,16 +1606,16 @@ */ }, { - key: '_getTransitionFunction', + key: "_getTransitionFunction", value: function _getTransitionFunction(opts) { var _this7 = this; return function (done) { opts.item.applyCss(opts.styles); + _this7._whenTransitionDone(opts.item.element, opts.callback, done); }; } - /** * Execute the styles gathered in the style queue. This applies styles to elements, * triggering transitions. @@ -1659,7 +1623,7 @@ */ }, { - key: '_processQueue', + key: "_processQueue", value: function _processQueue() { if (this.isTransitioning) { this._cancelMovement(); @@ -1672,52 +1636,47 @@ this._startTransitions(this._queue); } else if (hasQueue) { this._styleImmediately(this._queue); - this._dispatch(Shuffle.EventType.LAYOUT); - // A call to layout happened, but none of the newly visible items will + this._dispatch(Shuffle.EventType.LAYOUT); // A call to layout happened, but none of the newly visible items will // change position or the transition duration is zero, which will not trigger // the transitionend event. + } else { this._dispatch(Shuffle.EventType.LAYOUT); - } + } // Remove everything in the style queue + - // Remove everything in the style queue this._queue.length = 0; } - /** * Wait for each transition to finish, the emit the layout event. * @param {Object[]} transitions Array of transition objects. */ }, { - key: '_startTransitions', + key: "_startTransitions", value: function _startTransitions(transitions) { var _this8 = this; // Set flag that shuffle is currently in motion. - this.isTransitioning = true; + this.isTransitioning = true; // Create an array of functions to be called. - // Create an array of functions to be called. var callbacks = transitions.map(function (obj) { return _this8._getTransitionFunction(obj); }); - arrayParallel(callbacks, this._movementFinished.bind(this)); } }, { - key: '_cancelMovement', + key: "_cancelMovement", value: function _cancelMovement() { // Remove the transition end event for each listener. - this._transitions.forEach(cancelTransitionEnd); + this._transitions.forEach(cancelTransitionEnd); // Reset the array. - // Reset the array. - this._transitions.length = 0; - // Show it's no longer active. + this._transitions.length = 0; // Show it's no longer active. + this.isTransitioning = false; } - /** * Apply styles without a transition. * @param {Object[]} objects Array of transition objects. @@ -1725,7 +1684,7 @@ */ }, { - key: '_styleImmediately', + key: "_styleImmediately", value: function _styleImmediately(objects) { if (objects.length) { var elements = objects.map(function (obj) { @@ -1741,13 +1700,13 @@ } } }, { - key: '_movementFinished', + key: "_movementFinished", value: function _movementFinished() { this._transitions.length = 0; this.isTransitioning = false; + this._dispatch(Shuffle.EventType.LAYOUT); } - /** * The magic. This is what makes the plugin 'shuffle' * @param {string|string[]|function(Element):boolean} [category] Category to filter by. @@ -1756,7 +1715,7 @@ */ }, { - key: 'filter', + key: "filter", value: function filter(category, sortObj) { if (!this.isEnabled) { return; @@ -1766,25 +1725,24 @@ category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign } - this._filter(category); + this._filter(category); // Shrink each hidden item - // Shrink each hidden item - this._shrink(); - // How many visible elements? - this._updateItemCount(); + this._shrink(); // How many visible elements? + + + this._updateItemCount(); // Update transforms on visible elements so they will animate to their new positions. + - // Update transforms on visible elements so they will animate to their new positions. this.sort(sortObj); } - /** * Gets the visible elements, sorts them, and passes them to layout. * @param {Object} [sortOptions] The options object to pass to `sorter`. */ }, { - key: 'sort', + key: "sort", value: function sort() { var sortOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastSort; @@ -1796,25 +1754,24 @@ var items = sorter(this._getFilteredItems(), sortOptions); - this._layout(items); - - // `_layout` always happens after `_shrink`, so it's safe to process the style + this._layout(items); // `_layout` always happens after `_shrink`, so it's safe to process the style // queue here with styles from the shrink method. - this._processQueue(); - // Adjust the height of the container. + + this._processQueue(); // Adjust the height of the container. + + this._setContainerSize(); this.lastSort = sortOptions; } - /** * Reposition everything. * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated. */ }, { - key: 'update', + key: "update", value: function update() { var isOnlyLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; @@ -1822,13 +1779,12 @@ if (!isOnlyLayout) { // Get updated colCount this._setColumns(); - } + } // Layout items + - // Layout items this.sort(); } } - /** * Use this instead of `update()` if you don't need the columns and gutters updated * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations @@ -1836,11 +1792,10 @@ */ }, { - key: 'layout', + key: "layout", value: function layout() { this.update(true); } - /** * New items have been appended to shuffle. Mix them in with the current * filter or sort status. @@ -1848,37 +1803,40 @@ */ }, { - key: 'add', + key: "add", value: function add(newItems) { var _this9 = this; var items = arrayUnique(newItems).map(function (el) { return new ShuffleItem(el); - }); + }); // Add classes and set initial positions. + + this._initItems(items); // Determine which items will go with the current filter. - // Add classes and set initial positions. - this._initItems(items); - // Determine which items will go with the current filter. this._resetCols(); var allItems = this._mergeNewItems(items); + var sortedItems = sorter(allItems, this.lastSort); + var allSortedItemsSet = this._filter(this.lastFilter, sortedItems); var isNewItem = function isNewItem(item) { return items.includes(item); }; + var applyHiddenState = function applyHiddenState(item) { item.scale = ShuffleItem.Scale.HIDDEN; item.isHidden = true; item.applyCss(ShuffleItem.Css.HIDDEN.before); item.applyCss(ShuffleItem.Css.HIDDEN.after); - }; - - // Layout all items again so that new items get positions. + }; // Layout all items again so that new items get positions. // Synchonously apply positions. + + var itemPositions = this._getNextPositions(allSortedItemsSet.visible); + allSortedItemsSet.visible.forEach(function (item, i) { if (isNewItem(item)) { item.point = itemPositions[i]; @@ -1886,52 +1844,45 @@ item.applyCss(_this9.getStylesForTransition(item, {})); } }); - allSortedItemsSet.hidden.forEach(function (item) { if (isNewItem(item)) { applyHiddenState(item); } - }); + }); // Cause layout so that the styles above are applied. - // Cause layout so that the styles above are applied. this.element.offsetWidth; // eslint-disable-line no-unused-expressions - // Add transition to each item. - this.setItemTransitions(items); - // Update the list of items. - this.items = this._mergeNewItems(items); + this.setItemTransitions(items); // Update the list of items. + + this.items = this._mergeNewItems(items); // Update layout/visibility of new and old items. - // Update layout/visibility of new and old items. this.filter(this.lastFilter); } - /** * Disables shuffle from updating dimensions and layout on resize */ }, { - key: 'disable', + key: "disable", value: function disable() { this.isEnabled = false; } - /** * Enables shuffle again * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters */ }, { - key: 'enable', + key: "enable", value: function enable() { var isUpdateLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - this.isEnabled = true; + if (isUpdateLayout) { this.update(); } } - /** * Remove 1 or more shuffle items. * @param {Element[]} elements An array containing one or more @@ -1940,7 +1891,7 @@ */ }, { - key: 'remove', + key: "remove", value: function remove(elements) { var _this10 = this; @@ -1949,7 +1900,6 @@ } var collection = arrayUnique(elements); - var oldItems = collection.map(function (element) { return _this10.getItemByElement(element); }).filter(function (item) { @@ -1957,17 +1907,19 @@ }); var handleLayout = function handleLayout() { - _this10._disposeItems(oldItems); + _this10._disposeItems(oldItems); // Remove the collection in the callback + - // Remove the collection in the callback collection.forEach(function (element) { element.parentNode.removeChild(element); }); - _this10._dispatch(Shuffle.EventType.REMOVED, { collection: collection }); - }; + _this10._dispatch(Shuffle.EventType.REMOVED, { + collection: collection + }); + }; // Hide collection first. + - // Hide collection first. this._toggleFilterClasses({ visible: [], hidden: oldItems @@ -1975,18 +1927,17 @@ this._shrink(oldItems); - this.sort(); - - // Update the list of items here because `remove` could be called again + this.sort(); // Update the list of items here because `remove` could be called again // with an item that is in the process of being removed. + this.items = this.items.filter(function (item) { return !oldItems.includes(item); }); + this._updateItemCount(); this.once(Shuffle.EventType.LAYOUT, handleLayout); } - /** * Retrieve a shuffle item by its element. * @param {Element} element Element to look for. @@ -1994,73 +1945,66 @@ */ }, { - key: 'getItemByElement', + key: "getItemByElement", value: function getItemByElement(element) { return this.items.find(function (item) { return item.element === element; }); } - /** * Dump the elements currently stored and reinitialize all child elements which * match the `itemSelector`. */ }, { - key: 'resetItems', + key: "resetItems", value: function resetItems() { var _this11 = this; // Remove refs to current items. this._disposeItems(this.items); - this.isInitialized = false; - // Find new items in the DOM. - this.items = this._getItems(); + this.isInitialized = false; // Find new items in the DOM. + + this.items = this._getItems(); // Set initial styles on the new items. - // Set initial styles on the new items. this._initItems(this.items); this.once(Shuffle.EventType.LAYOUT, function () { // Add transition to each item. _this11.setItemTransitions(_this11.items); + _this11.isInitialized = true; - }); + }); // Lay out all items. - // Lay out all items. this.filter(this.lastFilter); } - /** * Destroys shuffle, removes events, styles, and classes */ }, { - key: 'destroy', + key: "destroy", value: function destroy() { this._cancelMovement(); - window.removeEventListener('resize', this._onResize); - // Reset container styles + window.removeEventListener('resize', this._onResize); // Reset container styles + this.element.classList.remove('shuffle'); - this.element.removeAttribute('style'); + this.element.removeAttribute('style'); // Reset individual item styles - // Reset individual item styles this._disposeItems(this.items); this.items.length = 0; - this._transitions.length = 0; + this._transitions.length = 0; // Null DOM references - // Null DOM references this.options.sizer = null; - this.element = null; - - // Set a flag so if a debounced resize has been triggered, + this.element = null; // Set a flag so if a debounced resize has been triggered, // it can first check if it is actually isDestroyed and not doing anything + this.isDestroyed = true; this.isEnabled = false; } - /** * Returns the outer width of an element, optionally including its margins. * @@ -2085,10 +2029,9 @@ */ }], [{ - key: 'getSize', + key: "getSize", value: function getSize(element) { var includeMargins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - // Store the styles so that they can be used by others without asking for it again. var styles = window.getComputedStyle(element, null); var width = getNumberStyle(element, 'width', styles); @@ -2108,7 +2051,6 @@ height: height }; } - /** * Change a property or execute a function which will not have a transition * @param {Element[]} elements DOM elements that won't be transitioned. @@ -2118,137 +2060,110 @@ */ }, { - key: '_skipTransitions', + key: "_skipTransitions", value: function _skipTransitions(elements, callback) { - var zero = '0ms'; + var zero = '0ms'; // Save current duration and delay. - // Save current duration and delay. var data = elements.map(function (element) { var style = element.style; - var duration = style.transitionDuration; - var delay = style.transitionDelay; + var delay = style.transitionDelay; // Set the duration to zero so it happens immediately - // Set the duration to zero so it happens immediately style.transitionDuration = zero; style.transitionDelay = zero; - return { duration: duration, delay: delay }; }); + callback(); // Cause forced synchronous layout. - callback(); - - // Cause forced synchronous layout. elements[0].offsetWidth; // eslint-disable-line no-unused-expressions - // Put the duration back + elements.forEach(function (element, i) { element.style.transitionDuration = data[i].duration; element.style.transitionDelay = data[i].delay; }); } }]); + return Shuffle; }(tinyEmitter); Shuffle.ShuffleItem = ShuffleItem; - Shuffle.ALL_ITEMS = 'all'; Shuffle.FILTER_ATTRIBUTE_KEY = 'groups'; - /** @enum {string} */ + Shuffle.EventType = { LAYOUT: 'shuffle:layout', REMOVED: 'shuffle:removed' }; - /** @enum {string} */ - Shuffle.Classes = Classes; + Shuffle.Classes = Classes; /** @enum {string} */ + Shuffle.FilterMode = { ANY: 'any', ALL: 'all' - }; + }; // Overrideable options - // Overrideable options Shuffle.options = { // Initial filter group. group: Shuffle.ALL_ITEMS, - // Transition/animation speed (milliseconds). speed: 250, - // CSS easing function to use. easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)', - // e.g. '.picture-item'. itemSelector: '*', - // Element or selector string. Use an element to determine the size of columns // and gutters. sizer: null, - // A static number or function that tells the plugin how wide the gutters // between columns are (in pixels). gutterWidth: 0, - // A static number or function that returns a number which tells the plugin // how wide the columns are (in pixels). columnWidth: 0, - // If your group is not json, and is comma delimeted, you could set delimiter // to ','. delimiter: null, - // Useful for percentage based heights when they might not always be exactly // the same (in pixels). buffer: 0, - // Reading the width of elements isn't precise enough and can cause columns to // jump between values. columnThreshold: 0.01, - // Shuffle can be isInitialized with a sort object. It is the same object // given to the sort method. initialSort: null, - // By default, shuffle will throttle resize events. This can be changed or // removed. throttle: throttleit, - // How often shuffle can be called on resize (in milliseconds). throttleTime: 300, - // Transition delay offset for each item in milliseconds. staggerAmount: 15, - // Maximum stagger delay in milliseconds. staggerAmountMax: 150, - // Whether to use transforms or absolute positioning. useTransforms: true, - // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With "any", // the element passes the test if any of its groups are in the array. With "all", // the element only passes if all groups are in the array. filterMode: Shuffle.FilterMode.ANY, - // Attempt to center grid items in each row. isCentered: false, - // Whether to round pixel values used in translate(x, y). This usually avoids // blurriness. roundTransforms: true }; - Shuffle.Point = Point; - Shuffle.Rect = Rect; + Shuffle.Rect = Rect; // Expose for testing. Hack at your own risk. - // Expose for testing. Hack at your own risk. Shuffle.__sorter = sorter; Shuffle.__getColumnSpan = getColumnSpan; Shuffle.__getAvailablePositions = getAvailablePositions; diff --git a/docs/dist/shuffle.js.map b/docs/dist/shuffle.js.map index 067ee63..0358220 100644 --- a/docs/dist/shuffle.js.map +++ b/docs/dist/shuffle.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/hyphenate.js","../src/shuffle.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n"],"names":["getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","Object","keys","key","style","removeClasses","position","visibility","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","slice","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","data","shuffle","emit","itemPositions","_getNextPositions","equals","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","parallel","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","allItems","_mergeNewItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","once","find","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/hyphenate.js","../src/shuffle.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n"],"names":["getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","Object","keys","key","style","removeClasses","position","visibility","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","slice","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","data","shuffle","emit","itemPositions","_getNextPositions","equals","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","parallel","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","allItems","_mergeNewItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","once","find","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file diff --git a/docs/dist/shuffle.min.js b/docs/dist/shuffle.min.js index 1547d15..0e4d92b 100644 --- a/docs/dist/shuffle.min.js +++ b/docs/dist/shuffle.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Shuffle=e()}(this,function(){"use strict";function t(){}t.prototype={on:function(t,e,i){var n=this.e||(this.e={});return(n[t]||(n[t]=[])).push({fn:e,ctx:i}),this},once:function(t,e,i){var n=this;function s(){n.off(t,s),e.apply(i,arguments)}return s._=e,this.on(t,s,i)},emit:function(t){for(var e=[].slice.call(arguments,1),i=((this.e||(this.e={}))[t]||[]).slice(),n=0,s=i.length;n=e?l():o=setTimeout(l,e-t)),s};function l(){o=0,r=+new Date,s=t.apply(i,n),i=null,n=null}};function r(){}function l(t){return parseFloat(t)||0}var a=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},u=function(){function t(t,e){for(var i=0;i2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=l(i[e]);return y()||"width"!==e?y()||"height"!==e||(n+=l(i.paddingTop)+l(i.paddingBottom)+l(i.borderTopWidth)+l(i.borderBottomWidth)):n+=l(i.paddingLeft)+l(i.paddingRight)+l(i.borderLeftWidth)+l(i.borderRightWidth),n}var _={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function E(t,e){var i=Object.assign({},_,e),n=Array.from(t),s=!1;return t.length?i.randomize?function(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}(t):("function"==typeof i.by?t.sort(function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0}):"function"==typeof i.compare&&t.sort(i.compare),s?n:(i.reverse&&t.reverse(),t)):[]}var I={},b="transitionend",S=0;function T(t){return!!I[t]&&(I[t].element.removeEventListener(b,I[t].listener),I[t]=null,!0)}function k(t,e){var i=b+(S+=1),n=function(t){t.currentTarget===t.target&&(T(i),e(t))};return t.addEventListener(b,n),I[i]={element:t,listener:n},i}function w(t){return Math.max.apply(Math,t)}function C(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=n-e&&t[s]<=n+e)return s;return 0}function z(t,e){var i={};t.forEach(function(t){i[t.top]?i[t.top].push(t):i[t.top]=[t]});var n=[],s=[],o=[];return Object.keys(i).forEach(function(t){var r=i[t];s.push(r);var l=r[r.length-1],a=l.left+l.width,u=Math.round((e-a)/2),h=r,f=!1;if(u>0){var d=[];(f=r.every(function(t){var e=new c(t.left+u,t.top,t.width,t.height,t.id),i=!n.some(function(t){return c.intersects(e,t)});return d.push(e),i}))&&(h=d)}if(!f){var m=void 0;if(r.some(function(t){return n.some(function(e){var i=c.intersects(t,e);return i&&(m=e),i})})){var p=o.findIndex(function(t){return t.includes(m)});o.splice(p,1,s[p])}}n=n.concat(h),o.push(h)}),[].concat.apply([],o).sort(function(t,e){return t.id-e.id}).map(function(t){return new f(t.left,t.top)})}function M(t){return Array.from(new Set(t))}var A=0,F=function(t){function i(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};a(this,i);var n=h(this,(i.__proto__||Object.getPrototypeOf(i)).call(this));n.options=Object.assign({},i.options,e),n.options.delimeter&&(n.options.delimiter=n.options.delimeter),n.lastSort={},n.group=i.ALL_ITEMS,n.lastFilter=i.ALL_ITEMS,n.isEnabled=!0,n.isDestroyed=!1,n.isInitialized=!1,n._transitions=[],n.isTransitioning=!1,n._queue=[];var s=n._getElementOption(t);if(!s)throw new TypeError("Shuffle needs to be initialized with an element.");return n.element=s,n.id="shuffle_"+A,A+=1,n._init(),n.isInitialized=!0,n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(i,e),u(i,[{key:"_init",value:function(){if(this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(i.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){var t=this.layout.bind(this);window.addEventListener("load",function e(){window.removeEventListener("load",e),t()})}var e=window.getComputedStyle(this.element,null),n=i.getSize(this.element).width;this._validateStyles(e),this._setColumns(n),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition="height "+this.options.speed+"ms "+this.options.easing}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(t,e){var n=this,s=[],o=[];return t===i.ALL_ITEMS?s=e:e.forEach(function(e){n._doesPassFilter(t,e.element)?s.push(e):o.push(e)}),{visible:s,hidden:o}}},{key:"_doesPassFilter",value:function(t,e){if("function"==typeof t)return t.call(e,e,this);var n=e.getAttribute("data-"+i.FILTER_ATTRIBUTE_KEY),s=this.options.delimiter?n.split(this.options.delimiter):JSON.parse(n);function o(t){return s.includes(t)}return Array.isArray(t)?this.options.filterMode===i.FilterMode.ANY?t.some(o):t.every(o):s.includes(t)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach(function(t){t.show()}),i.forEach(function(t){t.hide()})}},{key:"_initItems",value:function(t){t.forEach(function(t){t.init()})}},{key:"_disposeItems",value:function(t){t.forEach(function(t){t.dispose()})}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"setItemTransitions",value:function(t){var e=this.options,i=e.speed,n=e.easing,s=this.options.useTransforms?["transform"]:["top","left"],o=Object.keys(p.Css.HIDDEN.before).map(function(t){return t.replace(/([A-Z])/g,function(t,e){return"-"+e.toLowerCase()})}),r=s.concat(o).join();t.forEach(function(t){t.element.style.transitionDuration=i+"ms",t.element.style.transitionTimingFunction=n,t.element.style.transitionProperty=r})}},{key:"_getItems",value:function(){var t=this;return Array.from(this.element.children).filter(function(e){return s(e,t.options.itemSelector)}).map(function(t){return new p(t)})}},{key:"_mergeNewItems",value:function(t){var e=Array.from(this.element.children);return E(this.items.concat(t),{by:function(t){return e.indexOf(t)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter(function(t){return t.isVisible})}},{key:"_getConcealedItems",value:function(){return this.items.filter(function(t){return!t.isVisible})}},{key:"_getColumnSize",value:function(t,e){var n=void 0;return 0===(n="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?i.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?i.getSize(this.items[0].element,!0).width:t)&&(n=t),n+e}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?g(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:i.getSize(this.element).width,e=this._getGutterSize(t),n=this._getColumnSize(t,e),s=(t+e)/n;Math.abs(Math.round(s)-s)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(t){var e=this,i=this._getNextPositions(t),n=0;t.forEach(function(t,s){function o(){t.applyCss(p.Css.VISIBLE.after)}if(f.equals(t.point,i[s])&&!t.isHidden)return t.applyCss(p.Css.VISIBLE.before),void o();t.point=i[s],t.scale=p.Scale.VISIBLE,t.isHidden=!1;var r=e.getStylesForTransition(t,p.Css.VISIBLE.before);r.transitionDelay=e._getStaggerAmount(n)+"ms",e._queue.push({item:t,styles:r,callback:o}),n+=1})}},{key:"_getNextPositions",value:function(t){var e=this;if(this.options.isCentered){var n=t.map(function(t,n){var s=i.getSize(t.element,!0),o=e._getItemPosition(s);return new c(o.x,o.y,s.width,s.height,n)});return this.getTransformedPositions(n,this.containerWidth)}return t.map(function(t){return e._getItemPosition(i.getSize(t.element,!0))})}},{key:"_getItemPosition",value:function(t){return function(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=C(e.width,n,s,o),a=L(i,l,s),u=D(a,r),h=new f(n*u,a[u]),c=a[u]+e.height,d=0;d0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach(function(e){function n(){e.applyCss(p.Css.HIDDEN.after)}if(e.isHidden)return e.applyCss(p.Css.HIDDEN.before),void n();e.scale=p.Scale.HIDDEN,e.isHidden=!0;var s=t.getStylesForTransition(e,p.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1})}},{key:"_handleResize",value:function(){this.isEnabled&&!this.isDestroyed&&this.update()}},{key:"getStylesForTransition",value:function(t,e){var i=Object.assign({},e);if(this.options.useTransforms){var n=this.options.roundTransforms?Math.round(t.point.x):t.point.x,s=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform="translate("+n+"px, "+s+"px) scale("+t.scale+")"}else i.left=t.point.x+"px",i.top=t.point.y+"px";return i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=k(t,function(t){e(),i(null,t)});this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(t.styles),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatch(i.EventType.LAYOUT)):this._dispatch(i.EventType.LAYOUT),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0,function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=r);var n=t&&t.length;if(!n)return i(null,[]);var s=!1,o=new Array(n);function l(t){return function(e,r){if(!s){if(e)return i(e,o),void(s=!0);o[t]=r,--n||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,l(i))}:function(t,e){t(l(e))})}(t.map(function(t){return e._getTransitionFunction(t)}),this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(T),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(t){if(t.length){var e=t.map(function(t){return t.item.element});i._skipTransitions(e,function(){t.forEach(function(t){t.item.applyCss(t.styles),t.callback()})})}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(i.EventType.LAYOUT)}},{key:"filter",value:function(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=i.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=E(this._getFilteredItems(),t);this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=this,i=M(t).map(function(t){return new p(t)});this._initItems(i),this._resetCols();var n=E(this._mergeNewItems(i),this.lastSort),s=this._filter(this.lastFilter,n),o=function(t){return i.includes(t)},r=function(t){t.scale=p.Scale.HIDDEN,t.isHidden=!0,t.applyCss(p.Css.HIDDEN.before),t.applyCss(p.Css.HIDDEN.after)},l=this._getNextPositions(s.visible);s.visible.forEach(function(t,i){o(t)&&(t.point=l[i],r(t),t.applyCss(e.getStylesForTransition(t,{})))}),s.hidden.forEach(function(t){o(t)&&r(t)}),this.element.offsetWidth,this.setItemTransitions(i),this.items=this._mergeNewItems(i),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}},{key:"remove",value:function(t){var e=this;if(t.length){var n=M(t),s=n.map(function(t){return e.getItemByElement(t)}).filter(function(t){return!!t});this._toggleFilterClasses({visible:[],hidden:s}),this._shrink(s),this.sort(),this.items=this.items.filter(function(t){return!s.includes(t)}),this._updateItemCount(),this.once(i.EventType.LAYOUT,function(){e._disposeItems(s),n.forEach(function(t){t.parentNode.removeChild(t)}),e._dispatch(i.EventType.REMOVED,{collection:n})})}}},{key:"getItemByElement",value:function(t){return this.items.find(function(e){return e.element===t})}},{key:"resetItems",value:function(){var t=this;this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(i.EventType.LAYOUT,function(){t.setItemTransitions(t.items),t.isInitialized=!0}),this.filter(this.lastFilter)}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(this.items),this.items.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}}],[{key:"getSize",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=window.getComputedStyle(t,null),n=g(t,"width",i),s=g(t,"height",i);e&&(n+=g(t,"marginLeft",i)+g(t,"marginRight",i),s+=g(t,"marginTop",i)+g(t,"marginBottom",i));return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map(function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}});e(),t[0].offsetWidth,t.forEach(function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay})}}]),i}();return F.ShuffleItem=p,F.ALL_ITEMS="all",F.FILTER_ATTRIBUTE_KEY="groups",F.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},F.Classes=d,F.FilterMode={ANY:"any",ALL:"all"},F.options={group:F.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimiter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:o,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:F.FilterMode.ANY,isCentered:!1,roundTransforms:!0},F.Point=f,F.Rect=c,F.__sorter=E,F.__getColumnSpan=C,F.__getAvailablePositions=L,F.__getShortColumn=D,F.__getCenteredPositions=z,F}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Shuffle=e()}(this,function(){"use strict";function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var i=0;i=e?l():o=setTimeout(l,e-t)),s};function l(){o=0,r=+new Date,s=t.apply(i,n),i=null,n=null}};function c(){}function d(t){return parseFloat(t)||0}var m=function(){function e(i,n){t(this,e),this.x=d(i),this.y=d(n)}return i(e,null,[{key:"equals",value:function(t,e){return t.x===e.x&&t.y===e.y}}]),e}(),p=function(){function e(i,n,s,o,r){t(this,e),this.id=r,this.left=i,this.top=n,this.width=s,this.height=o}return i(e,null,[{key:"intersects",value:function(t,e){return t.left2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=d(i[e]);return E()||"width"!==e?E()||"height"!==e||(n+=d(i.paddingTop)+d(i.paddingBottom)+d(i.borderTopWidth)+d(i.borderBottomWidth)):n+=d(i.paddingLeft)+d(i.paddingRight)+d(i.borderLeftWidth)+d(i.borderRightWidth),n}var b={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function S(t,e){var i=Object.assign({},b,e),n=Array.from(t),s=!1;return t.length?i.randomize?function(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}(t):("function"==typeof i.by?t.sort(function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0}):"function"==typeof i.compare&&t.sort(i.compare),s?n:(i.reverse&&t.reverse(),t)):[]}var T={},k="transitionend",w=0;function C(t){return!!T[t]&&(T[t].element.removeEventListener(k,T[t].listener),T[t]=null,!0)}function L(t,e){var i=k+(w+=1),n=function(t){t.currentTarget===t.target&&(C(i),e(t))};return t.addEventListener(k,n),T[i]={element:t,listener:n},i}function D(t){return Math.max.apply(Math,t)}function z(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=n-e&&t[s]<=n+e)return s;return 0}function F(t,e){var i={};t.forEach(function(t){i[t.top]?i[t.top].push(t):i[t.top]=[t]});var n=[],s=[],o=[];return Object.keys(i).forEach(function(t){var r=i[t];s.push(r);var l,a=r[r.length-1],u=a.left+a.width,h=Math.round((e-u)/2),f=r,c=!1;if(h>0){var d=[];(c=r.every(function(t){var e=new p(t.left+h,t.top,t.width,t.height,t.id),i=!n.some(function(t){return p.intersects(e,t)});return d.push(e),i}))&&(f=d)}if(!c&&r.some(function(t){return n.some(function(e){var i=p.intersects(t,e);return i&&(l=e),i})})){var m=o.findIndex(function(t){return t.includes(l)});o.splice(m,1,s[m])}n=n.concat(f),o.push(f)}),[].concat.apply([],o).sort(function(t,e){return t.id-e.id}).map(function(t){return new m(t.left,t.top)})}function x(t){return Array.from(new Set(t))}var O=0,N=function(e){function r(e){var i,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,r),(i=o(this,n(r).call(this))).options=Object.assign({},r.options,s),i.options.delimeter&&(i.options.delimiter=i.options.delimeter),i.lastSort={},i.group=r.ALL_ITEMS,i.lastFilter=r.ALL_ITEMS,i.isEnabled=!0,i.isDestroyed=!1,i.isInitialized=!1,i._transitions=[],i.isTransitioning=!1,i._queue=[];var l=i._getElementOption(e);if(!l)throw new TypeError("Shuffle needs to be initialized with an element.");return i.element=l,i.id="shuffle_"+O,O+=1,i._init(),i.isInitialized=!0,i}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&s(t,e)}(r,l),i(r,[{key:"_init",value:function(){if(this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(r.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){var t=this.layout.bind(this);window.addEventListener("load",function e(){window.removeEventListener("load",e),t()})}var e=window.getComputedStyle(this.element,null),i=r.getSize(this.element).width;this._validateStyles(e),this._setColumns(i),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition="height ".concat(this.options.speed,"ms ").concat(this.options.easing)}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(t,e){var i=this,n=[],s=[];return t===r.ALL_ITEMS?n=e:e.forEach(function(e){i._doesPassFilter(t,e.element)?n.push(e):s.push(e)}),{visible:n,hidden:s}}},{key:"_doesPassFilter",value:function(t,e){if("function"==typeof t)return t.call(e,e,this);var i=e.getAttribute("data-"+r.FILTER_ATTRIBUTE_KEY),n=this.options.delimiter?i.split(this.options.delimiter):JSON.parse(i);function s(t){return n.includes(t)}return Array.isArray(t)?this.options.filterMode===r.FilterMode.ANY?t.some(s):t.every(s):n.includes(t)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach(function(t){t.show()}),i.forEach(function(t){t.hide()})}},{key:"_initItems",value:function(t){t.forEach(function(t){t.init()})}},{key:"_disposeItems",value:function(t){t.forEach(function(t){t.dispose()})}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"setItemTransitions",value:function(t){var e=this.options,i=e.speed,n=e.easing,s=this.options.useTransforms?["transform"]:["top","left"],o=Object.keys(g.Css.HIDDEN.before).map(function(t){return t.replace(/([A-Z])/g,function(t,e){return"-".concat(e.toLowerCase())})}),r=s.concat(o).join();t.forEach(function(t){t.element.style.transitionDuration=i+"ms",t.element.style.transitionTimingFunction=n,t.element.style.transitionProperty=r})}},{key:"_getItems",value:function(){var t=this;return Array.from(this.element.children).filter(function(e){return h(e,t.options.itemSelector)}).map(function(t){return new g(t)})}},{key:"_mergeNewItems",value:function(t){var e=Array.from(this.element.children);return S(this.items.concat(t),{by:function(t){return e.indexOf(t)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter(function(t){return t.isVisible})}},{key:"_getConcealedItems",value:function(){return this.items.filter(function(t){return!t.isVisible})}},{key:"_getColumnSize",value:function(t,e){var i;return 0===(i="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?r.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?r.getSize(this.items[0].element,!0).width:t)&&(i=t),i+e}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?I(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:r.getSize(this.element).width,e=this._getGutterSize(t),i=this._getColumnSize(t,e),n=(t+e)/i;Math.abs(Math.round(n)-n)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(t){var e=this,i=this._getNextPositions(t),n=0;t.forEach(function(t,s){function o(){t.applyCss(g.Css.VISIBLE.after)}if(m.equals(t.point,i[s])&&!t.isHidden)return t.applyCss(g.Css.VISIBLE.before),void o();t.point=i[s],t.scale=g.Scale.VISIBLE,t.isHidden=!1;var r=e.getStylesForTransition(t,g.Css.VISIBLE.before);r.transitionDelay=e._getStaggerAmount(n)+"ms",e._queue.push({item:t,styles:r,callback:o}),n+=1})}},{key:"_getNextPositions",value:function(t){var e=this;if(this.options.isCentered){var i=t.map(function(t,i){var n=r.getSize(t.element,!0),s=e._getItemPosition(n);return new p(s.x,s.y,n.width,n.height,i)});return this.getTransformedPositions(i,this.containerWidth)}return t.map(function(t){return e._getItemPosition(r.getSize(t.element,!0))})}},{key:"_getItemPosition",value:function(t){return function(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=z(e.width,n,s,o),a=M(i,l,s),u=A(a,r),h=new m(n*u,a[u]),f=a[u]+e.height,c=0;c0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach(function(e){function n(){e.applyCss(g.Css.HIDDEN.after)}if(e.isHidden)return e.applyCss(g.Css.HIDDEN.before),void n();e.scale=g.Scale.HIDDEN,e.isHidden=!0;var s=t.getStylesForTransition(e,g.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1})}},{key:"_handleResize",value:function(){this.isEnabled&&!this.isDestroyed&&this.update()}},{key:"getStylesForTransition",value:function(t,e){var i=Object.assign({},e);if(this.options.useTransforms){var n=this.options.roundTransforms?Math.round(t.point.x):t.point.x,s=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform="translate(".concat(n,"px, ").concat(s,"px) scale(").concat(t.scale,")")}else i.left=t.point.x+"px",i.top=t.point.y+"px";return i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=L(t,function(t){e(),i(null,t)});this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(t.styles),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatch(r.EventType.LAYOUT)):this._dispatch(r.EventType.LAYOUT),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0,function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=c);var n=t&&t.length;if(!n)return i(null,[]);var s=!1,o=new Array(n);function r(t){return function(e,r){if(!s){if(e)return i(e,o),void(s=!0);o[t]=r,--n||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,r(i))}:function(t,e){t(r(e))})}(t.map(function(t){return e._getTransitionFunction(t)}),this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(C),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(t){if(t.length){var e=t.map(function(t){return t.item.element});r._skipTransitions(e,function(){t.forEach(function(t){t.item.applyCss(t.styles),t.callback()})})}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(r.EventType.LAYOUT)}},{key:"filter",value:function(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=r.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=S(this._getFilteredItems(),t);this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=this,i=x(t).map(function(t){return new g(t)});this._initItems(i),this._resetCols();var n=S(this._mergeNewItems(i),this.lastSort),s=this._filter(this.lastFilter,n),o=function(t){return i.includes(t)},r=function(t){t.scale=g.Scale.HIDDEN,t.isHidden=!0,t.applyCss(g.Css.HIDDEN.before),t.applyCss(g.Css.HIDDEN.after)},l=this._getNextPositions(s.visible);s.visible.forEach(function(t,i){o(t)&&(t.point=l[i],r(t),t.applyCss(e.getStylesForTransition(t,{})))}),s.hidden.forEach(function(t){o(t)&&r(t)}),this.element.offsetWidth,this.setItemTransitions(i),this.items=this._mergeNewItems(i),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}},{key:"remove",value:function(t){var e=this;if(t.length){var i=x(t),n=i.map(function(t){return e.getItemByElement(t)}).filter(function(t){return!!t});this._toggleFilterClasses({visible:[],hidden:n}),this._shrink(n),this.sort(),this.items=this.items.filter(function(t){return!n.includes(t)}),this._updateItemCount(),this.once(r.EventType.LAYOUT,function(){e._disposeItems(n),i.forEach(function(t){t.parentNode.removeChild(t)}),e._dispatch(r.EventType.REMOVED,{collection:i})})}}},{key:"getItemByElement",value:function(t){return this.items.find(function(e){return e.element===t})}},{key:"resetItems",value:function(){var t=this;this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(r.EventType.LAYOUT,function(){t.setItemTransitions(t.items),t.isInitialized=!0}),this.filter(this.lastFilter)}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(this.items),this.items.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}}],[{key:"getSize",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=window.getComputedStyle(t,null),n=I(t,"width",i),s=I(t,"height",i);e&&(n+=I(t,"marginLeft",i)+I(t,"marginRight",i),s+=I(t,"marginTop",i)+I(t,"marginBottom",i));return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map(function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}});e(),t[0].offsetWidth,t.forEach(function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay})}}]),r}();return N.ShuffleItem=g,N.ALL_ITEMS="all",N.FILTER_ATTRIBUTE_KEY="groups",N.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},N.Classes=v,N.FilterMode={ANY:"any",ALL:"all"},N.options={group:N.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimiter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:f,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:N.FilterMode.ANY,isCentered:!1,roundTransforms:!0},N.Point=m,N.Rect=p,N.__sorter=S,N.__getColumnSpan=z,N.__getAvailablePositions=M,N.__getShortColumn=A,N.__getCenteredPositions=F,N}); //# sourceMappingURL=shuffle.min.js.map diff --git a/docs/dist/shuffle.min.js.map b/docs/dist/shuffle.min.js.map index b2396b1..ff8bd84 100644 --- a/docs/dist/shuffle.min.js.map +++ b/docs/dist/shuffle.min.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.min.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/layout.js","../src/array-min.js","../src/shuffle.js","../src/hyphenate.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","proto","Element","vendor","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","el","selector","nodeType","nodes","parentNode","querySelectorAll","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","HIDDEN","add","VISIBLE","removeAttribute","setAttribute","addClasses","SHUFFLE_ITEM","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","keys","key","style","removeClasses","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","sorter","arr","options","opts","Object","assign","original","Array","from","revert","randomize","array","n","Math","floor","random","temp","by","sort","valA","valB","undefined","compare","reverse","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","_this","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","TinyEmitter","_getItems","sizer","BASE","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_this2","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","before","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","_this3","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","shuffle","itemPositions","_getNextPositions","after","equals","_this4","getStylesForTransition","transitionDelay","_getStaggerAmount","isCentered","itemsData","itemSize","_this5","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_getConcealedItems","_this6","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","_this8","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","sortedItems","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","_this9","isUpdateLayout","oldItems","_this10","getItemByElement","_disposeItems","REMOVED","find","_this11","includeMargins","duration","delay","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"mLAAA,SAASA,KAKTA,EAAEC,UAAY,CACZC,GAAI,SAAUC,EAAMC,EAAUC,GAC5B,IAAIC,EAAIC,KAAKD,IAAMC,KAAKD,EAAI,IAO5B,OALCA,EAAEH,KAAUG,EAAEH,GAAQ,KAAKK,KAAK,CAC/BC,GAAIL,EACJC,IAAKA,IAGAE,MAGTG,KAAM,SAAUP,EAAMC,EAAUC,GAC9B,IAAIM,EAAOJ,KACX,SAASK,IACPD,EAAKE,IAAIV,EAAMS,GACfR,EAASU,MAAMT,EAAKU,WAItB,OADAH,EAASI,EAAIZ,EACNG,KAAKL,GAAGC,EAAMS,EAAUP,IAGjCY,KAAM,SAAUd,GAMd,IALA,IAAIe,EAAO,GAAGC,MAAMC,KAAKL,UAAW,GAChCM,IAAWd,KAAKD,IAAMC,KAAKD,EAAI,KAAKH,IAAS,IAAIgB,QACjDG,EAAI,EACJC,EAAMF,EAAOG,OAETF,EAAIC,EAAKD,IACfD,EAAOC,GAAGb,GAAGK,MAAMO,EAAOC,GAAGjB,IAAKa,GAGpC,OAAOX,MAGTM,IAAK,SAAUV,EAAMC,GACnB,IAAIE,EAAIC,KAAKD,IAAMC,KAAKD,EAAI,IACxBmB,EAAOnB,EAAEH,GACTuB,EAAa,GAEjB,GAAID,GAAQrB,EACV,IAAK,IAAIkB,EAAI,EAAGC,EAAME,EAAKD,OAAQF,EAAIC,EAAKD,IACtCG,EAAKH,GAAGb,KAAOL,GAAYqB,EAAKH,GAAGb,GAAGO,IAAMZ,GAC9CsB,EAAWlB,KAAKiB,EAAKH,IAY3B,OAJCI,EAAiB,OACdpB,EAAEH,GAAQuB,SACHpB,EAAEH,GAENI,OAIX,MAAiBP,EC/Db2B,EAA2B,oBAAZC,QAA0BA,QAAQ3B,UAAY,GAC7D4B,EAASF,EAAMG,SACdH,EAAMI,iBACNJ,EAAMK,uBACNL,EAAMM,oBACNN,EAAMO,mBACNP,EAAMQ,mBAaX,SAAeC,EAAIC,GACjB,IAAKD,GAAsB,IAAhBA,EAAGE,SAAgB,OAAO,EACrC,GAAIT,EAAQ,OAAOA,EAAOT,KAAKgB,EAAIC,GAEnC,IADA,IAAIE,EAAQH,EAAGI,WAAWC,iBAAiBJ,GAClCf,EAAI,EAAGA,EAAIiB,EAAMf,OAAQF,IAChC,GAAIiB,EAAMjB,IAAMc,EAAI,OAAO,EAE7B,OAAO,GC5BT,MAUA,SAAmBM,EAAMC,GACvB,IAAItC,EAAKuC,EAAMC,EAAKC,EAChBC,EAAO,EAEX,OAAO,WACL1C,EAAME,KACNqC,EAAO7B,UACP,IAAIiC,EAAQ,IAAIC,KAASF,EAIzB,OAHKD,IACCE,GAASL,EAAMvB,IACd0B,EAAYI,WAAW9B,EAAMuB,EAAOK,IACpCH,GAGT,SAASzB,IACP0B,EAAY,EACZC,GAAQ,IAAIE,KACZJ,EAAMH,EAAK5B,MAAMT,EAAKuC,GACtBvC,EAAM,KACNuC,EAAO,OCUX,SAASO,KClCM,SAASC,EAAUC,UACzBC,WAAWD,IAAU,8fCJxBE,wBAMQC,EAAGC,kBACRD,EAAIJ,EAAUI,QACdC,EAAIL,EAAUK,iDASPC,EAAGC,UACRD,EAAEF,IAAMG,EAAEH,GAAKE,EAAED,IAAME,EAAEF,WCpBfG,wBAWPJ,EAAGC,EAAGI,EAAGC,EAAGC,kBACjBA,GAAKA,OAGLC,KAAOR,OAGPS,IAAMR,OAGNS,MAAQL,OAGRM,OAASL,oDASEJ,EAAGC,UAEjBD,EAAEM,KAAOL,EAAEK,KAAOL,EAAEO,OAASP,EAAEK,KAAON,EAAEM,KAAON,EAAEQ,OACjDR,EAAEO,IAAMN,EAAEM,IAAMN,EAAEQ,QAAUR,EAAEM,IAAMP,EAAEO,IAAMP,EAAES,kBCpCrC,MACP,uBACQ,uBACL,+BACD,wBCDNJ,EAAK,EAEHK,wBACQC,gBACJ,OACDN,GAAKA,OACLM,QAAUA,OAKVC,WAAY,OAQZC,UAAW,gDAIXD,WAAY,OACZD,QAAQG,UAAUC,OAAOC,EAAQC,aACjCN,QAAQG,UAAUI,IAAIF,EAAQG,cAC9BR,QAAQS,gBAAgB,mDAIxBR,WAAY,OACZD,QAAQG,UAAUC,OAAOC,EAAQG,cACjCR,QAAQG,UAAUI,IAAIF,EAAQC,aAC9BN,QAAQU,aAAa,eAAe,uCAIpCC,WAAW,CAACN,EAAQO,aAAcP,EAAQG,eAC1CK,SAASd,EAAYe,IAAIC,cACzBC,MAAQjB,EAAYkB,MAAMT,aAC1BU,MAAQ,IAAIhC,qCAGRiC,gBACDC,QAAQ,SAACC,KACVrB,QAAQG,UAAUI,IAAIc,2CAIjBF,gBACJC,QAAQ,SAACC,KACVrB,QAAQG,UAAUC,OAAOiB,sCAIzBC,qBACAC,KAAKD,GAAKF,QAAQ,SAACI,KACnBxB,QAAQyB,MAAMD,GAAOF,EAAIE,4CAK3BE,cAAc,CACjBrB,EAAQC,OACRD,EAAQG,QACRH,EAAQO,oBAGLZ,QAAQS,gBAAgB,cACxBT,QAAU,cAInBD,EAAYe,IAAM,SACP,UACG,eACL,OACC,aACM,wBACG,qBAER,QACC,SACG,aACG,iBAEP,iBACY,YAGb,QACE,SACG,SAEJ,YACO,yBACK,MAKvBf,EAAYkB,MAAQ,SACT,SACD,MC1GV,IAAIjC,EAAQ,qBAEI,OAAVA,SACKA,MAGHgB,EAAU2B,SAASC,MAAQD,SAASE,gBACpC5F,EAAI0F,SAASG,cAAc,gBAC/BL,MAAMM,QAAU,kDACVC,YAAY/F,KAE+B,SAA3CgG,OAAOC,iBAAiBjG,EAAG,MAAM4D,QAEjCsC,YAAYlG,GAEb+C,GCFM,SAASoD,EACtBpC,EAASyB,OACTY,yDAASJ,OAAOC,iBAAiBlC,EAAS,MAEtChB,EAAQD,EAAUsD,EAAOZ,WAGxBa,KAAgC,UAAVb,EAKfa,KAAgC,WAAVb,OACvB1C,EAAUsD,EAAOE,YACxBxD,EAAUsD,EAAOG,eACjBzD,EAAUsD,EAAOI,gBACjB1D,EAAUsD,EAAOK,uBARV3D,EAAUsD,EAAOM,aACxB5D,EAAUsD,EAAOO,cACjB7D,EAAUsD,EAAOQ,iBACjB9D,EAAUsD,EAAOS,kBAQd9D,ECXT,IAAM+D,EAAW,UAEN,KAGL,aAGK,gBAGE,MAIN,WAIQ,SAASC,EAAOC,EAAKC,OAC5BC,EAAOC,OAAOC,OAAO,GAAIN,EAAUG,GACnCI,EAAWC,MAAMC,KAAKP,GACxBQ,GAAS,SAERR,EAAI9F,OAILgG,EAAKO,UA1CX,SAAmBC,WACbC,EAAID,EAAMxG,OAEPyG,GAAG,IACH,MACC3G,EAAI4G,KAAKC,MAAMD,KAAKE,UAAYH,EAAI,IACpCI,EAAOL,EAAM1G,KACbA,GAAK0G,EAAMC,KACXA,GAAKI,SAGNL,EAgCED,CAAUT,IAKI,mBAAZE,EAAKc,KACVC,KAAK,SAAC7E,EAAGC,MAEPmE,SACK,MAGHU,EAAOhB,EAAKc,GAAG5E,EAAE8D,EAAK3B,MACtB4C,EAAOjB,EAAKc,GAAG3E,EAAE6D,EAAK3B,kBAGf6C,IAATF,QAA+BE,IAATD,MACf,EACF,GAGLD,EAAOC,GAAiB,cAATD,GAAiC,aAATC,GACjC,EAGND,EAAOC,GAAiB,aAATD,GAAgC,cAATC,EACjC,EAGF,IAEwB,mBAAjBjB,EAAKmB,WACjBJ,KAAKf,EAAKmB,SAIZb,EACKH,GAGLH,EAAKoB,WACHA,UAGCtB,IAhDE,GC9CX,IAAMuB,EAAc,GACdC,EAAY,gBACdC,EAAQ,EAOL,SAASC,EAAoBjF,WAC9B8E,EAAY9E,OACFA,GAAIM,QAAQ4E,oBAAoBH,EAAWD,EAAY9E,GAAInD,YAC3DmD,GAAM,MACX,GAMJ,SAASmF,EAAgB7E,EAASjE,OACjC2D,EAdC+E,MADE,GAgBHlI,EAAW,SAACuI,GACZA,EAAIC,gBAAkBD,EAAIE,WACRtF,KACXoF,cAILG,iBAAiBR,EAAWlI,KAExBmD,GAAM,CAAEM,UAASzD,YAEtBmD,EChCM,SAASwF,EAASvB,UACxBE,KAAKsB,IAAI1I,MAAMoH,KAAMF,GCYvB,SAASyB,EAAcC,EAAWC,EAAaC,EAASC,OACzDC,EAAaJ,EAAYC,SAKzBzB,KAAK6B,IAAI7B,KAAK8B,MAAMF,GAAcA,GAAcD,MAErC3B,KAAK8B,MAAMF,IAInB5B,KAAK+B,IAAI/B,KAAKgC,KAAKJ,GAAaF,GASlC,SAASO,EAAsBC,EAAWN,EAAYF,MAExC,IAAfE,SACKM,UAyBHC,EAAY,GAGT/I,EAAI,EAAGA,GAAKsI,EAAUE,EAAYxI,MAE/Bd,KAAK+I,EAASa,EAAUjJ,MAAMG,EAAGA,EAAIwI,YAG1CO,EAWF,SAASC,EAAeF,EAAWG,WCjFTvC,EDkFzBwC,GClFyBxC,EDkFFoC,ECjFtBlC,KAAK+B,IAAInJ,MAAMoH,KAAMF,IDkFnB1G,EAAI,EAAGC,EAAM6I,EAAU5I,OAAQF,EAAIC,EAAKD,OAC3C8I,EAAU9I,IAAMkJ,EAAcD,GAAUH,EAAU9I,IAAMkJ,EAAcD,SACjEjJ,SAIJ,EA0CF,SAASmJ,EAAqBC,EAAWC,OACxCC,EAAS,KAKLnF,QAAQ,SAACoF,GACbD,EAAOC,EAAS5G,OAEX4G,EAAS5G,KAAKzD,KAAKqK,KAGnBA,EAAS5G,KAAO,CAAC4G,SAOxBC,EAAQ,GACNC,EAAO,GACPC,EAAe,iBACdpF,KAAKgF,GAAQnF,QAAQ,SAACI,OACrB6E,EAAYE,EAAO/E,KACpBrF,KAAKkK,OACJO,EAAWP,EAAUA,EAAUlJ,OAAS,GACxC0J,EAAMD,EAASjH,KAAOiH,EAAS/G,MAC/BiH,EAASjD,KAAK8B,OAAOW,EAAiBO,GAAO,GAE/CE,EAAaV,EACbW,GAAU,KACVF,EAAS,EAAG,KACRG,EAAW,MACPZ,EAAUa,MAAM,SAACC,OACnBC,EAAU,IAAI7H,EAAK4H,EAAExH,KAAOmH,EAAQK,EAAEvH,IAAKuH,EAAEtH,MAAOsH,EAAErH,OAAQqH,EAAEzH,IAGhE2H,GAAaZ,EAAMa,KAAK,mBAAK/H,EAAKgI,WAAWH,EAASD,cAEnDhL,KAAKiL,GACPC,SAKMJ,OAOZD,EAAS,KACRQ,YACenB,EAAUiB,KAAK,mBAAYb,EAAMa,KAAK,SAACH,OAClDI,EAAahI,EAAKgI,WAAWf,EAAUW,UACzCI,MACiBJ,GAEdI,MAIO,KACRE,EAAWd,EAAae,UAAU,mBAASC,EAAMC,SAASJ,OACnDK,OAAOJ,EAAU,EAAGf,EAAKe,OAIlChB,EAAMqB,OAAOf,KACR5K,KAAK4K,KAOb,GAAGe,OAAOrL,MAAM,GAAIkK,GACxBzC,KAAK,SAAC7E,EAAGC,UAAOD,EAAEK,GAAKJ,EAAEI,KACzBqI,IAAI,mBAAY,IAAI7I,EAAMsH,EAAS7G,KAAM6G,EAAS5G,OE5LvD,SAASoI,EAAY7I,UACZoE,MAAMC,KAAK,IAAIyE,IAAI9I,IAI5B,IAAIO,EAAK,EAEHwI,yBAQQlI,OAASkD,yDAAU,gFAExBA,QAAUE,OAAOC,OAAO,GAAI6E,EAAQhF,QAASA,GAI9CiF,EAAKjF,QAAQkF,cACVlF,QAAQmF,UAAYF,EAAKjF,QAAQkF,aAGnCE,SAAW,KACXC,MAAQL,EAAQM,YAChBC,WAAaP,EAAQM,YACrBE,WAAY,IACZC,aAAc,IACdC,eAAgB,IAChBC,aAAe,KACfC,iBAAkB,IAClBC,OAAS,OAERhL,EAAKoK,EAAKa,kBAAkBhJ,OAE7BjC,QACG,IAAIkL,UAAU,6DAGjBjJ,QAAUjC,IACV2B,GAAK,WAAaA,KACjB,IAEDwJ,UACAN,eAAgB,uUAvCHO,8CA2CbxB,MAAQzL,KAAKkN,iBAEblG,QAAQmG,MAAQnN,KAAK8M,kBAAkB9M,KAAKgH,QAAQmG,YAGpDrJ,QAAQG,UAAUI,IAAI2H,EAAQ7H,QAAQiJ,WAGtCC,WAAWrN,KAAKyL,YAGhB6B,UAAYtN,KAAKuN,4BACfxE,iBAAiB,SAAU/I,KAAKsN,WAKX,aAAxB7H,SAAS+H,WAA2B,KAChCC,EAASzN,KAAKyN,OAAOC,KAAK1N,aACzB+I,iBAAiB,OAAQ,SAAS4E,WAChCjF,oBAAoB,OAAQiF,aAMjCC,EAAe7H,OAAOC,iBAAiBhG,KAAK8D,QAAS,MACrDsG,EAAiB4B,EAAQ6B,QAAQ7N,KAAK8D,SAASH,WAGhDmK,gBAAgBF,QAIhBG,YAAY3D,QAGZ4D,OAAOhO,KAAKgH,QAAQqF,MAAOrM,KAAKgH,QAAQiH,kBAMxCnK,QAAQoK,iBACRC,mBAAmBnO,KAAKyL,YACxB3H,QAAQyB,MAAM6I,qBAAuBpO,KAAKgH,QAAQqH,YAAWrO,KAAKgH,QAAQsH,wDASzEC,EAAiBvO,KAAKwO,cAAcd,KAAK1N,aACxCA,KAAKgH,QAAQyH,SAClBzO,KAAKgH,QAAQyH,SAASF,EAAgBvO,KAAKgH,QAAQ0H,cACnDH,4CAScI,SAGM,iBAAXA,EACF3O,KAAK8D,QAAQ8K,cAAcD,GAGzBA,GAAUA,EAAO5M,UAAgC,IAApB4M,EAAO5M,SACtC4M,EAGEA,GAAUA,EAAOE,OACnBF,EAAO,GAGT,6CAQOxI,GAEU,WAApBA,EAAO2I,gBACJhL,QAAQyB,MAAMuJ,SAAW,YAIR,WAApB3I,EAAO4I,gBACJjL,QAAQyB,MAAMwJ,SAAW,gDAa1BC,yDAAWhP,KAAKuM,WAAY0C,yDAAajP,KAAKyL,MAC9CyD,EAAMlP,KAAKmP,iBAAiBH,EAAUC,eAGvCG,qBAAqBF,QAGrB3C,WAAayC,EAIM,iBAAbA,SACJ3C,MAAQ2C,GAGRE,2CAUQF,EAAUvD,cACrB4D,EAAU,GACRC,EAAS,UAGXN,IAAahD,EAAQM,YACbb,IAKJvG,QAAQ,SAACqK,GACTC,EAAKC,gBAAgBT,EAAUO,EAAKzL,WAC9B7D,KAAKsP,KAENtP,KAAKsP,KAKX,6DAaOP,EAAUlL,MACA,mBAAbkL,SACFA,EAASnO,KAAKiD,EAASA,EAAS9D,UAInC0P,EAAO5L,EAAQ6L,aAAa,QAAU3D,EAAQ4D,sBAC9CvK,EAAOrF,KAAKgH,QAAQmF,UACxBuD,EAAKG,MAAM7P,KAAKgH,QAAQmF,WACxB2D,KAAKC,MAAML,YAEJM,EAAahB,UACb3J,EAAKqG,SAASsD,UAGnB3H,MAAM4I,QAAQjB,GACZhP,KAAKgH,QAAQkJ,aAAelE,EAAQmE,WAAWC,IAC1CpB,EAAS5D,KAAK4E,GAEhBhB,EAAShE,MAAMgF,GAGjB3K,EAAKqG,SAASsD,uDAQAK,IAAAA,QAASC,IAAAA,SACtBpK,QAAQ,SAACqK,KACVc,WAGAnL,QAAQ,SAACqK,KACTe,4CASE7E,KACHvG,QAAQ,SAACqK,KACRgB,+CASK9E,KACNvG,QAAQ,SAACqK,KACRiB,4DASFC,aAAezQ,KAAK0Q,oBAAoBzP,kDAU5BwK,SACSzL,KAAKgH,QAAvBqH,IAAAA,MAAOC,IAAAA,OACTqC,EAAgB3Q,KAAKgH,QAAQ4J,cAAgB,CAAC,aAAe,CAAC,MAAO,QAIrEC,EAAW3J,OAAO7B,KAAKxB,EAAYe,IAAIR,OAAO0M,QAAQjF,IAAI,mBAAekF,EC5TtEC,QAAQ,WAAY,SAACC,EAAKC,aAAWA,EAAGC,kBD6T3CC,EAAaT,EAAc/E,OAAOiF,GAAUQ,SAE5CnM,QAAQ,SAACqK,KACRzL,QAAQyB,MAAM+L,mBAAqBjD,EAAQ,OAC3CvK,QAAQyB,MAAMgM,yBAA2BjD,IACzCxK,QAAQyB,MAAMiM,mBAAqBJ,0DAKnC/J,MAAMC,KAAKtH,KAAK8D,QAAQ2N,UAC5BzD,OAAO,mBAAMzM,EAAQM,EAAI6P,EAAK1K,QAAQ2K,gBACtC9F,IAAI,mBAAM,IAAIhI,EAAYhC,4CAQhB4J,OACPgG,EAAWpK,MAAMC,KAAKtH,KAAK8D,QAAQ2N,iBAClC3K,EAAO9G,KAAKyL,MAAMG,OAAOH,GAAQ,aACnC3H,UACM2N,EAASG,QAAQ9N,yDAMrB9D,KAAKyL,MAAMuC,OAAO,mBAAQuB,EAAKxL,gEAI/B/D,KAAKyL,MAAMuC,OAAO,mBAASuB,EAAKxL,mDAU1BqG,EAAgByH,OACzBC,gBAwBS,OArB2B,mBAA7B9R,KAAKgH,QAAQoC,YACfpJ,KAAKgH,QAAQoC,YAAYgB,GAGvBpK,KAAKgH,QAAQmG,MACfnB,EAAQ6B,QAAQ7N,KAAKgH,QAAQmG,OAAOxJ,MAGlC3D,KAAKgH,QAAQoC,YACfpJ,KAAKgH,QAAQoC,YAGXpJ,KAAKyL,MAAMxK,OAAS,EACtB+K,EAAQ6B,QAAQ7N,KAAKyL,MAAM,GAAG3H,SAAS,GAAMH,MAI7CyG,OAKAA,GAGF0H,EAAOD,yCASDzH,SAE2B,mBAA7BpK,KAAKgH,QAAQ+K,YACf/R,KAAKgH,QAAQ+K,YAAY3H,GACvBpK,KAAKgH,QAAQmG,MACfjH,EAAelG,KAAKgH,QAAQmG,MAAO,cAEnCnN,KAAKgH,QAAQ+K,sDAWZ3H,yDAAiB4B,EAAQ6B,QAAQ7N,KAAK8D,SAASH,MACnDqO,EAAShS,KAAKiS,eAAe7H,GAC7BhB,EAAcpJ,KAAKkS,eAAe9H,EAAgB4H,GACpDG,GAAqB/H,EAAiB4H,GAAU5I,EAGhDzB,KAAK6B,IAAI7B,KAAK8B,MAAM0I,GAAqBA,GACzCnS,KAAKgH,QAAQoL,oBAEKzK,KAAK8B,MAAM0I,SAG5BE,KAAO1K,KAAKsB,IAAItB,KAAKC,MAAMuK,GAAoB,QAC/C/H,eAAiBA,OACjBkI,SAAWlJ,mDAOXtF,QAAQyB,MAAM3B,OAAS5D,KAAKuS,oBAAsB,wDAShDvJ,EAAShJ,KAAK6J,qDAQL2I,UACT7K,KAAK+B,IAAI8I,EAAQxS,KAAKgH,QAAQyL,cAAezS,KAAKgH,QAAQ0L,oDAQzD9S,OAAMe,yDAAO,GACjBX,KAAKyM,gBAIJkG,QAAU3S,UACVU,KAAKd,EAAMe,6CAQZI,EAAIf,KAAKqS,cACRxI,UAAY,GACV9I,MACA,OACA8I,UAAU5J,KAAK,mCAShBwL,cACAmH,EAAgB5S,KAAK6S,kBAAkBpH,GAEzCjD,EAAQ,IACNtD,QAAQ,SAACqK,EAAMxO,YACVlB,MACF8E,SAASd,EAAYe,IAAIN,QAAQwO,UAKpC9P,EAAM+P,OAAOxD,EAAKvK,MAAO4N,EAAc7R,MAAQwO,EAAKvL,kBACjDW,SAASd,EAAYe,IAAIN,QAAQwM,mBAKnC9L,MAAQ4N,EAAc7R,KACtB+D,MAAQjB,EAAYkB,MAAMT,UAC1BN,UAAW,MAIVmC,EAAS6M,EAAKC,uBAAuB1D,EAAM1L,EAAYe,IAAIN,QAAQwM,UAClEoC,gBAAkBF,EAAKG,kBAAkB3K,GAAS,OAEpDqE,OAAO5M,KAAK,iCAMR,8CAWKwL,iBAGZzL,KAAKgH,QAAQoM,WAAY,KACrBC,EAAY5H,EAAMI,IAAI,SAAC0D,EAAMxO,OAC3BuS,EAAWtH,EAAQ6B,QAAQ0B,EAAKzL,SAAS,GACzCkB,EAAQuO,EAAKC,iBAAiBF,UAC7B,IAAIjQ,EAAK2B,EAAM/B,EAAG+B,EAAM9B,EAAGoQ,EAAS3P,MAAO2P,EAAS1P,OAAQ7C,YAG9Df,KAAKyT,wBAAwBJ,EAAWrT,KAAKoK,uBAK/CqB,EAAMI,IAAI,mBAAQ0H,EAAKC,iBAAiBxH,EAAQ6B,QAAQ0B,EAAKzL,SAAS,+CAS9DwP,UF/cZ,oBACLA,IAAAA,SAAUzJ,IAAAA,UAAW6J,IAAAA,SAAUC,IAAAA,MAAOrK,IAAAA,UAAWU,IAAAA,OAE3C4J,EAAO1K,EAAcoK,EAAS3P,MAAO+P,EAAUC,EAAOrK,GACtDuK,EAAOjK,EAAsBC,EAAW+J,EAAMD,GAC9CG,EAAmB/J,EAAe8J,EAAM7J,GAGxChF,EAAQ,IAAIhC,EAAM0Q,EAAWI,EAAkBD,EAAKC,IAKpDC,EAAYF,EAAKC,GAAoBR,EAAS1P,OAC3C7C,EAAI,EAAGA,EAAI6S,EAAM7S,MACd+S,EAAmB/S,GAAKgT,SAG7B/O,EE8bEgP,CAAgB,sBAEVhU,KAAK6J,mBACN7J,KAAKsS,eACRtS,KAAKqS,eACDrS,KAAKgH,QAAQoL,uBAChBpS,KAAKgH,QAAQgD,yDAWDG,EAAWC,UAC1BF,EAAqBC,EAAWC,gDAQjC6E,yDAAajP,KAAKiU,qBACpBzL,EAAQ,IACDtD,QAAQ,SAACqK,YACT1P,MACF8E,SAASd,EAAYe,IAAIR,OAAO0O,UASnCvD,EAAKvL,kBACFW,SAASd,EAAYe,IAAIR,OAAO0M,mBAKlChM,MAAQjB,EAAYkB,MAAMX,SAC1BJ,UAAW,MAEVmC,EAAS+N,EAAKjB,uBAAuB1D,EAAM1L,EAAYe,IAAIR,OAAO0M,UACjEoC,gBAAkBgB,EAAKf,kBAAkB3K,GAAS,OAEpDqE,OAAO5M,KAAK,iCAMR,4CAUND,KAAKwM,YAAaxM,KAAKyM,kBAIvB0H,wDAWgB5E,EAAM6E,OAErBjO,EAASe,OAAOC,OAAO,GAAIiN,MAE7BpU,KAAKgH,QAAQ4J,cAAe,KACxB3N,EAAIjD,KAAKgH,QAAQqN,gBAAkB1M,KAAK8B,MAAM8F,EAAKvK,MAAM/B,GAAKsM,EAAKvK,MAAM/B,EACzEC,EAAIlD,KAAKgH,QAAQqN,gBAAkB1M,KAAK8B,MAAM8F,EAAKvK,MAAM9B,GAAKqM,EAAKvK,MAAM9B,IACxEoR,uBAAyBrR,SAAQC,eAAcqM,EAAKzK,iBAEpDrB,KAAO8L,EAAKvK,MAAM/B,EAAI,OACtBS,IAAM6L,EAAKvK,MAAM9B,EAAI,YAGvBiD,8CAUWrC,EAASyQ,EAAcC,OACnChR,EAAKmF,EAAgB7E,EAAS,SAAC8E,SAE9B,KAAMA,UAGR+D,aAAa1M,KAAKuD,kDASFyD,qBACd,SAACuN,KACDjF,KAAK5K,SAASsC,EAAKd,UACnBsO,oBAAoBxN,EAAKsI,KAAKzL,QAASmD,EAAKpH,SAAU2U,4CAUzDxU,KAAK4M,sBACF8H,sBAGDC,EAAW3U,KAAKgH,QAAQqH,MAAQ,EAChCuG,EAAW5U,KAAK6M,OAAO5L,OAAS,EAElC2T,GAAYD,GAAY3U,KAAK0M,mBAC1BmI,kBAAkB7U,KAAK6M,QACnB+H,QACJE,kBAAkB9U,KAAK6M,aACvBkI,UAAU/I,EAAQgJ,UAAUC,cAM5BF,UAAU/I,EAAQgJ,UAAUC,aAI9BpI,OAAO5L,OAAS,4CAOLqH,mBAEXsE,iBAAkB,EbztBV,SAAkBsI,EAAKC,EAAStV,GAC1CA,IACoB,mBAAZsV,GACTtV,EAAWsV,EACXA,EAAU,MAEVtV,EAAW+C,GAIf,IAAIwS,EAAUF,GAAOA,EAAIjU,OACzB,IAAKmU,EAAS,OAAOvV,EAAS,KAAM,IAEpC,IAAIwV,GAAW,EACXC,EAAU,IAAIjO,MAAM+N,GAQxB,SAASG,EAAUxU,GACjB,OAAO,SAAUyU,EAAKC,GACpB,IAAIJ,EAAJ,CAEA,GAAIG,EAGF,OAFA3V,EAAS2V,EAAKF,QACdD,GAAW,GAIbC,EAAQvU,GAAK0U,IAENL,GAASvV,EAAS,KAAMyV,KAlBnCJ,EAAIhQ,QAAQiQ,EAAU,SAAUjV,EAAIa,GAClCb,EAAGW,KAAKsU,EAASI,EAAUxU,KACzB,SAAUb,EAAIa,GAChBb,EAAGqV,EAAUxU,OaysBKuH,EAAYuD,IAAI,mBAAO6J,EAAKC,uBAAuBvQ,KAEjDpF,KAAK4V,kBAAkBlI,KAAK1N,sDAK3C2M,aAAazH,QAAQuD,QAGrBkE,aAAa1L,OAAS,OAGtB2L,iBAAkB,4CAQPiJ,MACZA,EAAQ5U,OAAQ,KACZ6U,EAAWD,EAAQhK,IAAI,mBAAOzG,EAAImK,KAAKzL,YAErCiS,iBAAiBD,EAAU,aACzB5Q,QAAQ,SAACE,KACXmK,KAAK5K,SAASS,EAAIe,UAClBtG,iEAOL8M,aAAa1L,OAAS,OACtB2L,iBAAkB,OAClBmI,UAAU/I,EAAQgJ,UAAUC,uCAS5BjG,EAAUgH,GACVhW,KAAKwM,cAILwC,GAAaA,GAAgC,IAApBA,EAAS/N,YAC1B+K,EAAQM,gBAGhB2J,QAAQjH,QAGRkH,eAGAC,wBAGAnO,KAAKgO,uCAOPI,yDAAcpW,KAAKoM,YACjBpM,KAAKwM,gBAIL6J,iBAEC5K,EAAQ3E,EAAO9G,KAAK0Q,oBAAqB0F,QAE1CE,QAAQ7K,QAIR8K,qBAGAC,yBAEApK,SAAWgK,wCAOXK,0DACDzW,KAAKwM,YACFiK,QAEE1I,mBAIF/F,8CAUFmM,QAAO,+BAQVuC,cACIjL,EAAQK,EAAY4K,GAAU7K,IAAI,mBAAM,IAAIhI,EAAYhC,UAGzDwL,WAAW5B,QAGX4K,iBAGCM,EAAc7P,EADH9G,KAAK4W,eAAenL,GACAzL,KAAKoM,UACpCyK,EAAoB7W,KAAKiW,QAAQjW,KAAKuM,WAAYoK,GAElDG,EAAY,mBAAQrL,EAAMC,SAAS6D,IACnCwH,EAAmB,SAACxH,KACnBzK,MAAQjB,EAAYkB,MAAMX,SAC1BJ,UAAW,IACXW,SAASd,EAAYe,IAAIR,OAAO0M,UAChCnM,SAASd,EAAYe,IAAIR,OAAO0O,QAKjCF,EAAgB5S,KAAK6S,kBAAkBgE,EAAkBxH,WAC7CA,QAAQnK,QAAQ,SAACqK,EAAMxO,GACnC+V,EAAUvH,OACPvK,MAAQ4N,EAAc7R,KACVwO,KACZ5K,SAASqS,EAAK/D,uBAAuB1D,EAAM,UAIlCD,OAAOpK,QAAQ,SAACqK,GAC5BuH,EAAUvH,MACKA,UAKhBzL,QAAQoK,iBAGRC,mBAAmB1C,QAGnBA,MAAQzL,KAAK4W,eAAenL,QAG5BuC,OAAOhO,KAAKuM,mDAOZC,WAAY,uCAOZyK,kEACAzK,WAAY,EACbyK,QACG9C,wCAUF2B,iBACAA,EAAS7U,YAIRgO,EAAanD,EAAYgK,GAEzBoB,EAAWjI,EACdpD,IAAI,mBAAWsL,EAAKC,iBAAiBtT,KACrCkK,OAAO,oBAAUuB,SAcfH,qBAAqB,SACf,UACD8H,SAGLhB,QAAQgB,QAERlP,YAIAyD,MAAQzL,KAAKyL,MAAMuC,OAAO,mBAASkJ,EAASxL,SAAS6D,UACrD4G,wBAEAhW,KAAK6L,EAAQgJ,UAAUC,OA1BP,aACdoC,cAAcH,KAGRhS,QAAQ,SAACpB,KACV7B,WAAWgE,YAAYnC,OAG5BiR,UAAU/I,EAAQgJ,UAAUsC,QAAS,CAAErI,2DA0B/BnL,UACR9D,KAAKyL,MAAM8L,KAAK,mBAAQhI,EAAKzL,UAAYA,yDAS3CuT,cAAcrX,KAAKyL,YACnBiB,eAAgB,OAGhBjB,MAAQzL,KAAKkN,iBAGbG,WAAWrN,KAAKyL,YAEhBtL,KAAK6L,EAAQgJ,UAAUC,OAAQ,aAE7B9G,mBAAmBqJ,EAAK/L,SACxBiB,eAAgB,SAIlBsB,OAAOhO,KAAKuM,mDAOZmI,yBACEhM,oBAAoB,SAAU1I,KAAKsN,gBAGrCxJ,QAAQG,UAAUC,OAAO,gBACzBJ,QAAQS,gBAAgB,cAGxB8S,cAAcrX,KAAKyL,YAEnBA,MAAMxK,OAAS,OACf0L,aAAa1L,OAAS,OAGtB+F,QAAQmG,MAAQ,UAChBrJ,QAAU,UAIV2I,aAAc,OACdD,WAAY,oCAyBJ1I,OAAS2T,0DAEhBtR,EAASJ,OAAOC,iBAAiBlC,EAAS,MAC5CH,EAAQuC,EAAepC,EAAS,QAASqC,GACzCvC,EAASsC,EAAepC,EAAS,SAAUqC,GAE3CsR,OACiBvR,EAAepC,EAAS,aAAcqC,GACrCD,EAAepC,EAAS,cAAeqC,MACzCD,EAAepC,EAAS,YAAaqC,GAClCD,EAAepC,EAAS,eAAgBqC,UAKxD,4DAae2P,EAAUjW,OAI1Bc,EAAOmV,EAASjK,IAAI,SAAC/H,OACjByB,EAAUzB,EAAVyB,MACFmS,EAAWnS,EAAM+L,mBACjBqG,EAAQpS,EAAM2N,yBAGd5B,mBATK,QAUL4B,gBAVK,MAYJ,6BASA,GAAGhF,cAGHhJ,QAAQ,SAACpB,EAAS/C,KACjBwE,MAAM+L,mBAAqB3Q,EAAKI,GAAG2W,WACnCnS,MAAM2N,gBAAkBvS,EAAKI,GAAG4W,wBAK9C3L,EAAQnI,YAAcA,EAEtBmI,EAAQM,UAAY,MACpBN,EAAQ4D,qBAAuB,SAG/B5D,EAAQgJ,UAAY,QACV,yBACC,mBAIXhJ,EAAQ7H,QAAUA,EAGlB6H,EAAQmE,WAAa,KACd,UACA,OAIPnE,EAAQhF,QAAU,OAETgF,EAAQM,gBAGR,WAGC,8CAGM,UAIP,iBAIM,cAIA,YAIF,YAIH,kBAIS,gBAIJ,6BAOC,kBAGC,oBAGG,mBAGH,aAKHN,EAAQmE,WAAWC,gBAGnB,mBAIK,GAGnBpE,EAAQhJ,MAAQA,EAChBgJ,EAAQ3I,KAAOA,EAGf2I,EAAQ4L,SAAW9Q,EACnBkF,EAAQ6L,gBAAkB3O,EAC1B8C,EAAQ8L,wBAA0BlO,EAClCoC,EAAQ+L,iBAAmBhO,EAC3BiC,EAAQgM,uBAAyB9N"} \ No newline at end of file +{"version":3,"file":"shuffle.min.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/layout.js","../src/array-min.js","../src/shuffle.js","../src/hyphenate.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width &&\n a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some(r => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some(itemRect => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map(itemRect => new Point(itemRect.left, itemRect.top));\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter ?\n attr.split(this.options.delimiter) :\n JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = item => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find(item => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","proto","Element","vendor","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","el","selector","nodeType","nodes","parentNode","querySelectorAll","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","_this","_this2","obj","Object","keys","key","_this3","style","removeClasses","position","visibility","before","opacity","after","transitionDelay","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","reverse","by","compare","randomize","sorter","arr","options","opts","assign","original","Array","from","revert","array","n","Math","floor","random","temp","sort","valA","valB","undefined","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","intersectingRect","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","TinyEmitter","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","shuffle","itemPositions","_getNextPositions","equals","_this4","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","itemSize","_this5","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_getConcealedItems","_this6","update","styleObject","roundTransforms","transform","itemCallback","done","_this7","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","parallel","_this8","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","sortObj","_filter","_shrink","_updateItemCount","sortOptions","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","sortedItems","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","_this9","isUpdateLayout","oldItems","_this10","getItemByElement","_disposeItems","REMOVED","find","_this11","includeMargins","duration","delay","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index cdcdffb..cd5a205 100644 --- a/docs/index.html +++ b/docs/index.html @@ -206,7 +206,7 @@ prism: true

    Dependencies

    Shuffle's dependencies are bundled with the dist file.

    -

    Shuffle does, however, expect the following ES6/7 features: Set, Array.from, Object.assign, Array.prototype.find, and Array.prototype.includes. In order to support browsers like IE11 and Safari 8, you must include a polyfill for these features. You can use a service like polyfill.io to only load the polyfills that specific browser needs, or a polyfill script like babel-polyfill (which uses core-js internally).

    +

    Shuffle does, however, expect the following ES6/7 features: Set, Array.from, Object.assign, Array.prototype.find, and Array.prototype.includes. In order to support browsers like IE11 and Safari 8, you must include a polyfill for these features. You can use a service like polyfill.io to only load the polyfills that specific browser needs, or a polyfill script like @babel/polyfill (which uses core-js internally).

    diff --git a/gulp/config.js b/gulp/config.js index e3a4412..7634d2c 100644 --- a/gulp/config.js +++ b/gulp/config.js @@ -12,7 +12,7 @@ const babelOptions = { }; const minifyOptions = { - sourceMap: true, + sourcemap: true, compress: { warnings: true, drop_console: true, diff --git a/package.json b/package.json index 24751d7..e96903b 100644 --- a/package.json +++ b/package.json @@ -49,11 +49,10 @@ "tiny-emitter": "^2.0.1" }, "devDependencies": { + "@babel/core": "^7.1.6", + "@babel/preset-env": "^7.1.6", "@odopod/eslint-config": "^2.0.0", "autoprefixer": "^9.1.2", - "babel-core": "^6.26.0", - "babel-plugin-external-helpers": "^6.22.0", - "babel-preset-env": "^1.6.1", "chai": "^4.0.1", "chai-dom": "^1.7.0", "core-js": "^2.5.3", @@ -65,11 +64,11 @@ "gulp-sass": "^4.0.0", "gulp-shell": "^0.6.5", "mocha": "^5.0.0", - "rollup": "^0.64.1", - "rollup-plugin-babel": "^3.0.3", + "rollup": "^0.67.3", + "rollup-plugin-babel": "^4.0.3", "rollup-plugin-commonjs": "^9.1.0", "rollup-plugin-node-resolve": "^3.0.2", - "rollup-plugin-terser": "^1.0.1", - "sinon": "^6.0.1" + "rollup-plugin-terser": "^3.0.0", + "sinon": "^7.1.1" } }