diff --git a/dist/shuffle.js b/dist/shuffle.js index 9fa114b..ab31fdf 100644 --- a/dist/shuffle.js +++ b/dist/shuffle.js @@ -888,6 +888,12 @@ var Shuffle = function (_TinyEmitter) { _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; + } + _this.lastSort = {}; _this.group = Shuffle.ALL_ITEMS; _this.lastFilter = Shuffle.ALL_ITEMS; @@ -1112,7 +1118,7 @@ var Shuffle = function (_TinyEmitter) { // Check each element's data-groups attribute against the given category. var attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); - var keys = this.options.delimeter ? attr.split(this.options.delimeter) : JSON.parse(attr); + var keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); function testCategory(category) { return keys.includes(category); @@ -2207,9 +2213,9 @@ Shuffle.options = { // how wide the columns are (in pixels). columnWidth: 0, - // If your group is not json, and is comma delimeted, you could set delimeter + // If your group is not json, and is comma delimeted, you could set delimiter // to ','. - delimeter: null, + delimiter: null, // Useful for percentage based heights when they might not always be exactly // the same (in pixels). diff --git a/dist/shuffle.js.map b/dist/shuffle.js.map index 13cfafb..1fb316f 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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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 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.delimeter ?\n attr.split(this.options.delimeter) :\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 delimeter\n // to ','.\n delimeter: 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","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","e","createElement","cssText","appendChild","window","getComputedStyle","ret","removeChild","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","sorter","arr","options","opts","Object","assign","original","Array","from","revert","by","sort","valA","valB","undefined","compare","reverse","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","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_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","nodeType","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimeter","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","before","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","after","equals","getStylesForTransition","transitionDelay","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","_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","__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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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","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","e","createElement","cssText","appendChild","window","getComputedStyle","ret","removeChild","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","sorter","arr","options","opts","Object","assign","original","Array","from","revert","by","sort","valA","valB","undefined","compare","reverse","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","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","nodeType","jquery","position","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","before","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","after","equals","getStylesForTransition","transitionDelay","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","_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","__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 0a369f4..206a99a 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 g||"width"!==e?g||"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}v.removeChild(y);var E={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function I(t,e){var i=Object.assign({},E,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 b={},S="transitionend",T=0;function k(t){return!!b[t]&&(b[t].element.removeEventListener(S,b[t].listener),b[t]=null,!0)}function w(t,e){var i=S+(T+=1),n=function(t){t.currentTarget===t.target&&(k(i),e(t))};return t.addEventListener(S,n),b[i]={element:t,listener:n},i}function C(t){return Math.max.apply(Math,t)}function L(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 M(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 A(t){return Array.from(new Set(t))}var F=0,x=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.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_"+F,F+=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.delimeter?n.split(this.options.delimeter):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 I(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?_(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=L(e.width,n,s,o),a=D(i,l,s),u=z(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()).forEach(function(i){function n(){i.applyCss(p.Css.HIDDEN.after)}if(i.isHidden)return i.applyCss(p.Css.HIDDEN.before),void n();i.scale=p.Scale.HIDDEN,i.isHidden=!0;var s=t.getStylesForTransition(i,p.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(e)+"ms",t._queue.push({item:i,styles:s,callback:n}),e+=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=w(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(k),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=I(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=A(t).map(function(t){return new p(t)});this._initItems(i),this._resetCols();var n=I(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=A(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=_(t,"width",i),s=_(t,"height",i);e&&(n+=_(t,"marginLeft",i)+_(t,"marginRight",i),s+=_(t,"marginTop",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})}}]),i}();return x.ShuffleItem=p,x.ALL_ITEMS="all",x.FILTER_ATTRIBUTE_KEY="groups",x.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},x.Classes=d,x.FilterMode={ANY:"any",ALL:"all"},x.options={group:x.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimeter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:o,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:x.FilterMode.ANY,isCentered:!1,roundTransforms:!0},x.Point=f,x.Rect=c,x.__sorter=I,x.__getColumnSpan=L,x.__getAvailablePositions=D,x.__getShortColumn=z,x.__getCenteredPositions=M,x}); +!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 g||"width"!==e?g||"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}v.removeChild(y);var E={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function I(t,e){var i=Object.assign({},E,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 b={},S="transitionend",T=0;function k(t){return!!b[t]&&(b[t].element.removeEventListener(S,b[t].listener),b[t]=null,!0)}function w(t,e){var i=S+(T+=1),n=function(t){t.currentTarget===t.target&&(k(i),e(t))};return t.addEventListener(S,n),b[i]={element:t,listener:n},i}function C(t){return Math.max.apply(Math,t)}function L(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 M(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 A(t){return Array.from(new Set(t))}var F=0,x=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_"+F,F+=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 I(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?_(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=L(e.width,n,s,o),a=D(i,l,s),u=z(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()).forEach(function(i){function n(){i.applyCss(p.Css.HIDDEN.after)}if(i.isHidden)return i.applyCss(p.Css.HIDDEN.before),void n();i.scale=p.Scale.HIDDEN,i.isHidden=!0;var s=t.getStylesForTransition(i,p.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(e)+"ms",t._queue.push({item:i,styles:s,callback:n}),e+=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=w(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(k),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=I(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=A(t).map(function(t){return new p(t)});this._initItems(i),this._resetCols();var n=I(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=A(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=_(t,"width",i),s=_(t,"height",i);e&&(n+=_(t,"marginLeft",i)+_(t,"marginRight",i),s+=_(t,"marginTop",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})}}]),i}();return x.ShuffleItem=p,x.ALL_ITEMS="all",x.FILTER_ATTRIBUTE_KEY="groups",x.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},x.Classes=d,x.FilterMode={ANY:"any",ALL:"all"},x.options={group:x.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:x.FilterMode.ANY,isCentered:!1,roundTransforms:!0},x.Point=f,x.Rect=c,x.__sorter=I,x.__getColumnSpan=L,x.__getAvailablePositions=D,x.__getShortColumn=z,x.__getCenteredPositions=M,x}); //# sourceMappingURL=shuffle.min.js.map diff --git a/dist/shuffle.min.js.map b/dist/shuffle.min.js.map index 96a8555..4f71422 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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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 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.delimeter ?\n attr.split(this.options.delimeter) :\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 delimeter\n // to ','.\n delimeter: 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","ret","window","getComputedStyle","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","removeChild","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","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_this","_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","delimeter","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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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","ret","window","getComputedStyle","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","removeChild","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,WACAC,GAAI,SAAUC,EAAMC,EAAUC,GAC5B,IAAIC,EAAIC,KAAKD,IAAMC,KAAKD,MAOxB,OALCA,EAAEH,KAAUG,EAAEH,QAAaK,MAC1BC,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,KAAUC,MAAMC,KAAKL,UAAW,GAChCM,IAAWd,KAAKD,IAAMC,KAAKD,OAASH,QAAagB,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,MACpBmB,EAAOnB,EAAEH,GACTuB,KAEJ,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,aACjD4B,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,KClCT,SAAwBC,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,wBCnC5C,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,YAAYN,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,eACHrB,EAAQC,OACRD,EAAQG,QACRH,EAAQO,oBAGLZ,QAAQS,gBAAgB,cACxBT,QAAU,cAInBD,EAAYe,uBAEE,eACL,OACC,aACM,wBACG,sCAIJ,aACG,kCAGK,6BAKR,qBAGG,yBACK,MAKvBf,EAAYkB,eACD,SACD,MC1GV,IAAMjB,EAAU2B,SAASC,MAAQD,SAASE,gBACpC5F,EAAI0F,SAASG,cAAc,OACjC7F,EAAEwF,MAAMM,QAAU,gDAClB/B,EAAQgC,YAAY/F,OAGdgG,EAAgB,SADJC,OAAOC,iBAAiBlG,EAAG,MAArC4D,MCQR,SAAwBuC,EACtBpC,EAASyB,OACTY,yDAASH,OAAOC,iBAAiBnC,EAAS,MAEtChB,EAAQD,EAAUsD,EAAOZ,WAGxBa,GAA4C,UAAVb,EAK3Ba,GAA4C,WAAVb,OACnC1C,EAAUsD,EAAOE,YACxBxD,EAAUsD,EAAOG,eACjBzD,EAAUsD,EAAOI,gBACjB1D,EAAUsD,EAAOK,uBARV3D,EAAUsD,EAAOM,aACxB5D,EAAUsD,EAAOO,cACjB7D,EAAUsD,EAAOQ,iBACjB9D,EAAUsD,EAAOS,kBAQd9D,EDxBTgB,EAAQ+C,YAAY9G,GEapB,IAAM+G,YAEK,KAGL,aAGK,gBAGE,MAIN,WAIP,SAAwBC,EAAOC,EAAKC,OAC5BC,EAAOC,OAAOC,UAAWN,EAAUG,GACnCI,EAAWC,MAAMC,KAAKP,GACxBQ,GAAS,SAERR,EAAI/F,OAILiG,EAAKO,UA1CX,SAAmBC,WACbC,EAAID,EAAMzG,OAEP0G,GAAG,IACH,MACC5G,EAAI6G,KAAKC,MAAMD,KAAKE,UAAYH,EAAI,IACpCI,EAAOL,EAAM3G,KACbA,GAAK2G,EAAMC,KACXA,GAAKI,SAGNL,EAgCED,CAAUT,IAKI,mBAAZE,EAAKc,KACVC,KAAK,SAAC9E,EAAGC,MAEPoE,SACK,MAGHU,EAAOhB,EAAKc,GAAG7E,EAAE+D,EAAK5B,MACtB6C,EAAOjB,EAAKc,GAAG5E,EAAE8D,EAAK5B,kBAGf8C,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,OC9FT,IAAMuB,KACAC,EAAY,gBACdC,EAAQ,EAOZ,SAAgBC,EAAoBlF,WAC9B+E,EAAY/E,OACFA,GAAIM,QAAQ6E,oBAAoBH,EAAWD,EAAY/E,GAAInD,YAC3DmD,GAAM,MACX,GAMX,SAAgBoF,EAAgB9E,EAASjE,OACjC2D,EAdCgF,MADE,GAgBHnI,EAAW,SAACwI,GACZA,EAAIC,gBAAkBD,EAAIE,WACRvF,KACXqF,cAILG,iBAAiBR,EAAWnI,KAExBmD,IAAQM,UAASzD,YAEtBmD,WChCeyF,EAASvB,UACxBE,KAAKsB,IAAI3I,MAAMqH,KAAMF,GCY9B,SAAgByB,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,GASzC,SAAgBO,EAAsBC,EAAWN,EAAYF,MAExC,IAAfE,SACKM,UAyBHC,KAGGhJ,EAAI,EAAGA,GAAKuI,EAAUE,EAAYzI,MAE/Bd,KAAKgJ,EAASa,EAAUlJ,MAAMG,EAAGA,EAAIyI,YAG1CO,EAWT,SAAgBC,EAAeF,EAAWG,WCjFTvC,EDkFzBwC,GClFyBxC,EDkFFoC,ECjFtBlC,KAAK+B,IAAIpJ,MAAMqH,KAAMF,IDkFnB3G,EAAI,EAAGC,EAAM8I,EAAU7I,OAAQF,EAAIC,EAAKD,OAC3C+I,EAAU/I,IAAMmJ,EAAcD,GAAUH,EAAU/I,IAAMmJ,EAAcD,SACjElJ,SAIJ,EA0CT,SAAgBoJ,EAAqBC,EAAWC,OACxCC,OAKIpF,QAAQ,SAACqF,GACbD,EAAOC,EAAS7G,OAEX6G,EAAS7G,KAAKzD,KAAKsK,KAGnBA,EAAS7G,MAAQ6G,SAOxBC,KACEC,KACAC,mBACCrF,KAAKiF,GAAQpF,QAAQ,SAACI,OACrB8E,EAAYE,EAAOhF,KACpBrF,KAAKmK,OACJO,EAAWP,EAAUA,EAAUnJ,OAAS,GACxC2J,EAAMD,EAASlH,KAAOkH,EAAShH,MAC/BkH,EAASjD,KAAK8B,OAAOW,EAAiBO,GAAO,GAE/CE,EAAaV,EACbW,GAAU,KACVF,EAAS,EAAG,KACRG,QACIZ,EAAUa,MAAM,SAACC,OACnBC,EAAU,IAAI9H,EAAK6H,EAAEzH,KAAOoH,EAAQK,EAAExH,IAAKwH,EAAEvH,MAAOuH,EAAEtH,OAAQsH,EAAE1H,IAGhE4H,GAAaZ,EAAMa,KAAK,mBAAKhI,EAAKiI,WAAWH,EAASD,cAEnDjL,KAAKkL,GACPC,SAKMJ,OAOZD,EAAS,KACRQ,YACenB,EAAUiB,KAAK,mBAAYb,EAAMa,KAAK,SAACH,OAClDI,EAAajI,EAAKiI,WAAWf,EAAUW,UACzCI,MACiBJ,GAEdI,MAIO,KACRE,EAAWd,EAAae,UAAU,mBAASC,EAAMC,SAASJ,OACnDK,OAAOJ,EAAU,EAAGf,EAAKe,OAIlChB,EAAMqB,OAAOf,KACR7K,KAAK6K,QAOVe,OAAOtL,SAAUmK,GACxBzC,KAAK,SAAC9E,EAAGC,UAAOD,EAAEK,GAAKJ,EAAEI,KACzBsI,IAAI,mBAAY,IAAI9I,EAAMuH,EAAS9G,KAAM8G,EAAS7G,gBE5L9CqI,EAAY9I,UACZqE,MAAMC,KAAK,IAAIyE,IAAI/I,IAI5B,IAAIO,EAAK,EAEHyI,yBAQQnI,OAASmD,yIAEdA,QAAUE,OAAOC,UAAW6E,EAAQhF,QAASA,GAI9CiF,EAAKjF,QAAQkF,cACVlF,QAAQmF,UAAYF,EAAKjF,QAAQkF,aAGnCE,cACAC,MAAQL,EAAQM,YAChBC,WAAaP,EAAQM,YACrBE,WAAY,IACZC,aAAc,IACdC,eAAgB,IAChBC,kBACAC,iBAAkB,IAClBC,cAECjL,EAAKqK,EAAKa,kBAAkBjJ,OAE7BjC,QACG,IAAImL,UAAU,6DAGjBlJ,QAAUjC,IACV2B,GAAK,WAAaA,KACjB,IAEDyJ,UACAN,eAAgB,uUAvCHO,8CA2CbxB,MAAQ1L,KAAKmN,iBAEblG,QAAQmG,MAAQpN,KAAK+M,kBAAkB/M,KAAKiH,QAAQmG,YAGpDtJ,QAAQG,UAAUI,IAAI4H,EAAQ9H,QAAQkJ,WAGtCC,WAAWtN,KAAK0L,YAGhB6B,UAAYvN,KAAKwN,4BACfxE,iBAAiB,SAAUhJ,KAAKuN,WAKX,aAAxB9H,SAASgI,WAA2B,KAChCC,EAAS1N,KAAK0N,OAAOC,KAAK3N,aACzBgJ,iBAAiB,OAAQ,SAAS4E,WAChCjF,oBAAoB,OAAQiF,aAMjCC,EAAe7H,OAAOC,iBAAiBjG,KAAK8D,QAAS,MACrDuG,EAAiB4B,EAAQ6B,QAAQ9N,KAAK8D,SAASH,WAGhDoK,gBAAgBF,QAIhBG,YAAY3D,QAGZ4D,OAAOjO,KAAKiH,QAAQqF,MAAOtM,KAAKiH,QAAQiH,kBAMxCpK,QAAQqK,iBACRC,mBAAmBpO,KAAK0L,YACxB5H,QAAQyB,MAAM8I,qBAAuBrO,KAAKiH,QAAQqH,YAAWtO,KAAKiH,QAAQsH,wDASzEC,EAAiBxO,KAAKyO,cAAcd,KAAK3N,aACxCA,KAAKiH,QAAQyH,SAClB1O,KAAKiH,QAAQyH,SAASF,EAAgBxO,KAAKiH,QAAQ0H,cACnDH,4CAScI,SAGM,iBAAXA,EACF5O,KAAK8D,QAAQ+K,cAAcD,GAGzBA,GAAUA,EAAO7M,UAAgC,IAApB6M,EAAO7M,SACtC6M,EAGEA,GAAUA,EAAOE,OACnBF,EAAO,GAGT,6CAQOzI,GAEU,WAApBA,EAAO4I,gBACJjL,QAAQyB,MAAMwJ,SAAW,YAIR,WAApB5I,EAAO6I,gBACJlL,QAAQyB,MAAMyJ,SAAW,gDAa1BC,yDAAWjP,KAAKwM,WAAY0C,yDAAalP,KAAK0L,MAC9CyD,EAAMnP,KAAKoP,iBAAiBH,EAAUC,eAGvCG,qBAAqBF,QAGrB3C,WAAayC,EAIM,iBAAbA,SACJ3C,MAAQ2C,GAGRE,2CAUQF,EAAUvD,cACrB4D,KACEC,YAGFN,IAAahD,EAAQM,YACbb,IAKJxG,QAAQ,SAACsK,GACTC,EAAKC,gBAAgBT,EAAUO,EAAK1L,WAC9B7D,KAAKuP,KAENvP,KAAKuP,kEAkBJP,EAAUnL,MACA,mBAAbmL,SACFA,EAASpO,KAAKiD,EAASA,EAAS9D,UAInC2P,EAAO7L,EAAQ8L,aAAa,QAAU3D,EAAQ4D,sBAC9CxK,EAAOrF,KAAKiH,QAAQmF,UACxBuD,EAAKG,MAAM9P,KAAKiH,QAAQmF,WACxB2D,KAAKC,MAAML,YAEJM,EAAahB,UACb5J,EAAKsG,SAASsD,UAGnB3H,MAAM4I,QAAQjB,GACZjP,KAAKiH,QAAQkJ,aAAelE,EAAQmE,WAAWC,IAC1CpB,EAAS5D,KAAK4E,GAEhBhB,EAAShE,MAAMgF,GAGjB5K,EAAKsG,SAASsD,uDAQAK,IAAAA,QAASC,IAAAA,SACtBrK,QAAQ,SAACsK,KACVc,WAGApL,QAAQ,SAACsK,KACTe,4CASE7E,KACHxG,QAAQ,SAACsK,KACRgB,+CASK9E,KACNxG,QAAQ,SAACsK,KACRiB,4DASFC,aAAe1Q,KAAK2Q,oBAAoB1P,kDAU5ByK,SACS1L,KAAKiH,QAAvBqH,IAAAA,MAAOC,IAAAA,OACTqC,EAAgB5Q,KAAKiH,QAAQ4J,eAAiB,cAAgB,MAAO,QAIrEC,EAAW3J,OAAO9B,KAAKxB,EAAYe,IAAIR,OAAO2M,QAAQjF,IAAI,mBAAekF,EC5TtEC,QAAQ,WAAY,SAACC,EAAKC,aAAWA,EAAGC,kBD6T3CC,EAAaT,EAAc/E,OAAOiF,GAAUQ,SAE5CpM,QAAQ,SAACsK,KACR1L,QAAQyB,MAAMgM,mBAAqBjD,EAAQ,OAC3CxK,QAAQyB,MAAMiM,yBAA2BjD,IACzCzK,QAAQyB,MAAMkM,mBAAqBJ,0DAKnC/J,MAAMC,KAAKvH,KAAK8D,QAAQ4N,UAC5BzD,OAAO,mBAAM1M,EAAQM,EAAI8P,EAAK1K,QAAQ2K,gBACtC9F,IAAI,mBAAM,IAAIjI,EAAYhC,4CAQhB6J,OACPgG,EAAWpK,MAAMC,KAAKvH,KAAK8D,QAAQ4N,iBAClC3K,EAAO/G,KAAK0L,MAAMG,OAAOH,gBAC3B5H,UACM4N,EAASG,QAAQ/N,yDAMrB9D,KAAK0L,MAAMuC,OAAO,mBAAQuB,EAAKzL,gEAI/B/D,KAAK0L,MAAMuC,OAAO,mBAASuB,EAAKzL,mDAU1BsG,EAAgByH,OACzBC,gBAwBS,OArB2B,mBAA7B/R,KAAKiH,QAAQoC,YACfrJ,KAAKiH,QAAQoC,YAAYgB,GAGvBrK,KAAKiH,QAAQmG,MACfnB,EAAQ6B,QAAQ9N,KAAKiH,QAAQmG,OAAOzJ,MAGlC3D,KAAKiH,QAAQoC,YACfrJ,KAAKiH,QAAQoC,YAGXrJ,KAAK0L,MAAMzK,OAAS,EACtBgL,EAAQ6B,QAAQ9N,KAAK0L,MAAM,GAAG5H,SAAS,GAAMH,MAI7C0G,OAKAA,GAGF0H,EAAOD,yCASDzH,SAE2B,mBAA7BrK,KAAKiH,QAAQ+K,YACfhS,KAAKiH,QAAQ+K,YAAY3H,GACvBrK,KAAKiH,QAAQmG,MACflH,EAAelG,KAAKiH,QAAQmG,MAAO,cAEnCpN,KAAKiH,QAAQ+K,sDAWZ3H,yDAAiB4B,EAAQ6B,QAAQ9N,KAAK8D,SAASH,MACnDsO,EAASjS,KAAKkS,eAAe7H,GAC7BhB,EAAcrJ,KAAKmS,eAAe9H,EAAgB4H,GACpDG,GAAqB/H,EAAiB4H,GAAU5I,EAGhDzB,KAAK6B,IAAI7B,KAAK8B,MAAM0I,GAAqBA,GACzCpS,KAAKiH,QAAQoL,oBAEKzK,KAAK8B,MAAM0I,SAG5BE,KAAO1K,KAAKsB,IAAItB,KAAKC,MAAMuK,GAAoB,QAC/C/H,eAAiBA,OACjBkI,SAAWlJ,mDAOXvF,QAAQyB,MAAM3B,OAAS5D,KAAKwS,oBAAsB,wDAShDvJ,EAASjJ,KAAK8J,qDAQL2I,UACT7K,KAAK+B,IAAI8I,EAAQzS,KAAKiH,QAAQyL,cAAe1S,KAAKiH,QAAQ0L,oDAQzD/S,OAAMe,4DACVX,KAAK0M,gBAIJkG,QAAU5S,UACVU,KAAKd,EAAMe,6CAQZI,EAAIf,KAAKsS,cACRxI,aACE/I,MACA,OACA+I,UAAU7J,KAAK,mCAShByL,cACAmH,EAAgB7S,KAAK8S,kBAAkBpH,GAEzCjD,EAAQ,IACNvD,QAAQ,SAACsK,EAAMzO,YACVlB,MACF8E,SAASd,EAAYe,IAAIN,QAAQyO,UAKpC/P,EAAMgQ,OAAOxD,EAAKxK,MAAO6N,EAAc9R,MAAQyO,EAAKxL,kBACjDW,SAASd,EAAYe,IAAIN,QAAQyM,mBAKnC/L,MAAQ6N,EAAc9R,KACtB+D,MAAQjB,EAAYkB,MAAMT,UAC1BN,UAAW,MAIVmC,EAAS8M,EAAKC,uBAAuB1D,EAAM3L,EAAYe,IAAIN,QAAQyM,UAClEoC,gBAAkBF,EAAKG,kBAAkB3K,GAAS,OAEpDqE,OAAO7M,sCAMH,8CAWKyL,iBAGZ1L,KAAKiH,QAAQoM,WAAY,KACrBC,EAAY5H,EAAMI,IAAI,SAAC0D,EAAMzO,OAC3BwS,EAAWtH,EAAQ6B,QAAQ0B,EAAK1L,SAAS,GACzCkB,EAAQwO,EAAKC,iBAAiBF,UAC7B,IAAIlQ,EAAK2B,EAAM/B,EAAG+B,EAAM9B,EAAGqQ,EAAS5P,MAAO4P,EAAS3P,OAAQ7C,YAG9Df,KAAK0T,wBAAwBJ,EAAWtT,KAAKqK,uBAK/CqB,EAAMI,IAAI,mBAAQ0H,EAAKC,iBAAiBxH,EAAQ6B,QAAQ0B,EAAK1L,SAAS,+CAS9DyP,UF/cnB,oBACEA,IAAAA,SAAUzJ,IAAAA,UAAW6J,IAAAA,SAAUC,IAAAA,MAAOrK,IAAAA,UAAWU,IAAAA,OAE3C4J,EAAO1K,EAAcoK,EAAS5P,MAAOgQ,EAAUC,EAAOrK,GACtDuK,EAAOjK,EAAsBC,EAAW+J,EAAMD,GAC9CG,EAAmB/J,EAAe8J,EAAM7J,GAGxCjF,EAAQ,IAAIhC,EAAM2Q,EAAWI,EAAkBD,EAAKC,IAKpDC,EAAYF,EAAKC,GAAoBR,EAAS3P,OAC3C7C,EAAI,EAAGA,EAAI8S,EAAM9S,MACdgT,EAAmBhT,GAAKiT,SAG7BhP,EE8bEiP,uBAEMjU,KAAK8J,mBACN9J,KAAKuS,eACRvS,KAAKsS,eACDtS,KAAKiH,QAAQoL,uBAChBrS,KAAKiH,QAAQgD,yDAWDG,EAAWC,UAC1BF,EAAqBC,EAAWC,gDASnC5B,EAAQ,0DADOzI,KAAKkU,sBAEbhP,QAAQ,SAACsK,YACT3P,MACF8E,SAASd,EAAYe,IAAIR,OAAO2O,UASnCvD,EAAKxL,kBACFW,SAASd,EAAYe,IAAIR,OAAO2M,mBAKlCjM,MAAQjB,EAAYkB,MAAMX,SAC1BJ,UAAW,MAEVmC,EAASgO,EAAKjB,uBAAuB1D,EAAM3L,EAAYe,IAAIR,OAAO2M,UACjEoC,gBAAkBgB,EAAKf,kBAAkB3K,GAAS,OAEpDqE,OAAO7M,sCAMH,4CAUND,KAAKyM,YAAazM,KAAK0M,kBAIvB0H,wDAWgB5E,EAAM6E,OAErBlO,EAASgB,OAAOC,UAAWiN,MAE7BrU,KAAKiH,QAAQ4J,cAAe,KACxB5N,EAAIjD,KAAKiH,QAAQqN,gBAAkB1M,KAAK8B,MAAM8F,EAAKxK,MAAM/B,GAAKuM,EAAKxK,MAAM/B,EACzEC,EAAIlD,KAAKiH,QAAQqN,gBAAkB1M,KAAK8B,MAAM8F,EAAKxK,MAAM9B,GAAKsM,EAAKxK,MAAM9B,IACxEqR,uBAAyBtR,SAAQC,eAAcsM,EAAK1K,iBAEpDrB,KAAO+L,EAAKxK,MAAM/B,EAAI,OACtBS,IAAM8L,EAAKxK,MAAM9B,EAAI,YAGvBiD,8CAUWrC,EAAS0Q,EAAcC,OACnCjR,EAAKoF,EAAgB9E,EAAS,SAAC+E,SAE9B,KAAMA,UAGR+D,aAAa3M,KAAKuD,kDASF0D,qBACd,SAACuN,KACDjF,KAAK7K,SAASuC,EAAKf,UACnBuO,oBAAoBxN,EAAKsI,KAAK1L,QAASoD,EAAKrH,SAAU4U,4CAUzDzU,KAAK6M,sBACF8H,sBAGDC,EAAW5U,KAAKiH,QAAQqH,MAAQ,EAChCuG,EAAW7U,KAAK8M,OAAO7L,OAAS,EAElC4T,GAAYD,GAAY5U,KAAK2M,mBAC1BmI,kBAAkB9U,KAAK8M,QACnB+H,QACJE,kBAAkB/U,KAAK8M,aACvBkI,UAAU/I,EAAQgJ,UAAUC,cAM5BF,UAAU/I,EAAQgJ,UAAUC,aAI9BpI,OAAO7L,OAAS,4CAOLsH,mBAEXsE,iBAAkB,EbztBV,SAAkBsI,EAAKC,EAASvV,GAC1CA,IACoB,mBAAZuV,GACTvV,EAAWuV,EACXA,EAAU,MAEVvV,EAAW+C,GAIf,IAAIyS,EAAUF,GAAOA,EAAIlU,OACzB,IAAKoU,EAAS,OAAOxV,EAAS,SAE9B,IAAIyV,GAAW,EACXC,EAAU,IAAIjO,MAAM+N,GAQxB,SAASG,EAAUzU,GACjB,OAAO,SAAU0U,EAAKC,GACpB,IAAIJ,EAAJ,CAEA,GAAIG,EAGF,OAFA5V,EAAS4V,EAAKF,QACdD,GAAW,GAIbC,EAAQxU,GAAK2U,IAENL,GAASxV,EAAS,KAAM0V,KAlBnCJ,EAAIjQ,QAAQkQ,EAAU,SAAUlV,EAAIa,GAClCb,EAAGW,KAAKuU,EAASI,EAAUzU,KACzB,SAAUb,EAAIa,GAChBb,EAAGsV,EAAUzU,OaysBKwH,EAAYuD,IAAI,mBAAO6J,EAAKC,uBAAuBxQ,KAEjDpF,KAAK6V,kBAAkBlI,KAAK3N,sDAK3C4M,aAAa1H,QAAQwD,QAGrBkE,aAAa3L,OAAS,OAGtB4L,iBAAkB,4CAQPiJ,MACZA,EAAQ7U,OAAQ,KACZ8U,EAAWD,EAAQhK,IAAI,mBAAO1G,EAAIoK,KAAK1L,YAErCkS,iBAAiBD,EAAU,aACzB7Q,QAAQ,SAACE,KACXoK,KAAK7K,SAASS,EAAIe,UAClBtG,iEAOL+M,aAAa3L,OAAS,OACtB4L,iBAAkB,OAClBmI,UAAU/I,EAAQgJ,UAAUC,uCAS5BjG,EAAUgH,GACVjW,KAAKyM,cAILwC,GAAaA,GAAgC,IAApBA,EAAShO,YAC1BgL,EAAQM,gBAGhB2J,QAAQjH,QAGRkH,eAGAC,wBAGAnO,KAAKgO,uCAOPI,yDAAcrW,KAAKqM,YACjBrM,KAAKyM,gBAIL6J,iBAEC5K,EAAQ3E,EAAO/G,KAAK2Q,oBAAqB0F,QAE1CE,QAAQ7K,QAIR8K,qBAGAC,yBAEApK,SAAWgK,wCAOXK,0DACD1W,KAAKyM,YACFiK,QAEE1I,mBAIF/F,8CAUFmM,QAAO,+BAQVuC,cACIjL,EAAQK,EAAY4K,GAAU7K,IAAI,mBAAM,IAAIjI,EAAYhC,UAGzDyL,WAAW5B,QAGX4K,iBAGCM,EAAc7P,EADH/G,KAAK6W,eAAenL,GACA1L,KAAKqM,UACpCyK,EAAoB9W,KAAKkW,QAAQlW,KAAKwM,WAAYoK,GAElDG,EAAY,mBAAQrL,EAAMC,SAAS6D,IACnCwH,EAAmB,SAACxH,KACnB1K,MAAQjB,EAAYkB,MAAMX,SAC1BJ,UAAW,IACXW,SAASd,EAAYe,IAAIR,OAAO2M,UAChCpM,SAASd,EAAYe,IAAIR,OAAO2O,QAKjCF,EAAgB7S,KAAK8S,kBAAkBgE,EAAkBxH,WAC7CA,QAAQpK,QAAQ,SAACsK,EAAMzO,GACnCgW,EAAUvH,OACPxK,MAAQ6N,EAAc9R,KACVyO,KACZ7K,SAASsS,EAAK/D,uBAAuB1D,YAI5BD,OAAOrK,QAAQ,SAACsK,GAC5BuH,EAAUvH,MACKA,UAKhB1L,QAAQqK,iBAGRC,mBAAmB1C,QAGnBA,MAAQ1L,KAAK6W,eAAenL,QAG5BuC,OAAOjO,KAAKwM,mDAOZC,WAAY,uCAOZyK,kEACAzK,WAAY,EACbyK,QACG9C,wCAUF2B,iBACAA,EAAS9U,YAIRiO,EAAanD,EAAYgK,GAEzBoB,EAAWjI,EACdpD,IAAI,mBAAWsL,EAAKC,iBAAiBvT,KACrCmK,OAAO,oBAAUuB,SAcfH,wCAEK8H,SAGLhB,QAAQgB,QAERlP,YAIAyD,MAAQ1L,KAAK0L,MAAMuC,OAAO,mBAASkJ,EAASxL,SAAS6D,UACrD4G,wBAEAjW,KAAK8L,EAAQgJ,UAAUC,OA1BP,aACdoC,cAAcH,KAGRjS,QAAQ,SAACpB,KACV7B,WAAW4E,YAAY/C,OAG5BkR,UAAU/I,EAAQgJ,UAAUsC,SAAWrI,2DA0B/BpL,UACR9D,KAAK0L,MAAM8L,KAAK,mBAAQhI,EAAK1L,UAAYA,yDAS3CwT,cAActX,KAAK0L,YACnBiB,eAAgB,OAGhBjB,MAAQ1L,KAAKmN,iBAGbG,WAAWtN,KAAK0L,YAEhBvL,KAAK8L,EAAQgJ,UAAUC,OAAQ,aAE7B9G,mBAAmBqJ,EAAK/L,SACxBiB,eAAgB,SAIlBsB,OAAOjO,KAAKwM,mDAOZmI,yBACEhM,oBAAoB,SAAU3I,KAAKuN,gBAGrCzJ,QAAQG,UAAUC,OAAO,gBACzBJ,QAAQS,gBAAgB,cAGxB+S,cAActX,KAAK0L,YAEnBA,MAAMzK,OAAS,OACf2L,aAAa3L,OAAS,OAGtBgG,QAAQmG,MAAQ,UAChBtJ,QAAU,UAIV4I,aAAc,OACdD,WAAY,oCAyBJ3I,OAAS4T,0DAEhBvR,EAASH,OAAOC,iBAAiBnC,EAAS,MAC5CH,EAAQuC,EAAepC,EAAS,QAASqC,GACzCvC,EAASsC,EAAepC,EAAS,SAAUqC,GAE3CuR,OACiBxR,EAAepC,EAAS,aAAcqC,GACrCD,EAAepC,EAAS,cAAeqC,MACzCD,EAAepC,EAAS,YAAaqC,GAClCD,EAAepC,EAAS,eAAgBqC,sEAkBzC4P,EAAUlW,OAI1Bc,EAAOoV,EAASjK,IAAI,SAAChI,OACjByB,EAAUzB,EAAVyB,MACFoS,EAAWpS,EAAMgM,mBACjBqG,EAAQrS,EAAM4N,yBAGd5B,mBATK,QAUL4B,gBAVK,mCAqBJ,GAAGhF,cAGHjJ,QAAQ,SAACpB,EAAS/C,KACjBwE,MAAMgM,mBAAqB5Q,EAAKI,GAAG4W,WACnCpS,MAAM4N,gBAAkBxS,EAAKI,GAAG6W,wBAK9C3L,EAAQpI,YAAcA,EAEtBoI,EAAQM,UAAY,MACpBN,EAAQ4D,qBAAuB,SAG/B5D,EAAQgJ,kBACE,yBACC,mBAIXhJ,EAAQ9H,QAAUA,EAGlB8H,EAAQmE,gBACD,UACA,OAIPnE,EAAQhF,eAECgF,EAAQM,gBAGR,WAGC,8CAGM,UAIP,iBAIM,cAIA,YAIF,YAIH,kBAIS,gBAIJ,6BAOC,kBAGC,oBAGG,mBAGH,aAKHN,EAAQmE,WAAWC,gBAGnB,mBAIK,GAGnBpE,EAAQjJ,MAAQA,EAChBiJ,EAAQ5I,KAAOA,EAGf4I,EAAQ4L,SAAW9Q,EACnBkF,EAAQ6L,gBAAkB3O,EAC1B8C,EAAQ8L,wBAA0BlO,EAClCoC,EAAQ+L,iBAAmBhO,EAC3BiC,EAAQgM,uBAAyB9N"} \ No newline at end of file diff --git a/docs/_includes/changelog.html b/docs/_includes/changelog.html index 25cac70..3b5e3ef 100644 --- a/docs/_includes/changelog.html +++ b/docs/_includes/changelog.html @@ -11,7 +11,7 @@
  • v4.1.1 3/21/17 - the before styles for a ShuffleItem were not applied if the item didn’t move.
  • v4.1.0 1/30/17 - Use webpack-2 to bundle Shuffle.
  • v4.0.2 9/15/16 - Update custom-event-polyfill dependency.
  • -
  • v4.0.1 7/30/16 - Fix delimeter option.
  • +
  • v4.0.1 7/30/16 - Fix delimiter option.
  • v4.0.0 4/20/16 - Rewrite in ES6 with babel. Remove jQuery and Modernizr dependencies. Remove support for IE<11. Docs improvements. Switch to gulp build system with webpack.
  • v3.1.0 3/23/15 - Allow zero speed option (#64) and cancel previous animations instead of ignoring new ones (#69). Handle non-integer columns better (#46)
  • v3.0.4 2/16/15 - Publish to NPM.
  • diff --git a/docs/_includes/options.html b/docs/_includes/options.html index 2e0fe41..f4e615f 100644 --- a/docs/_includes/options.html +++ b/docs/_includes/options.html @@ -7,7 +7,7 @@ Shuffle.options = { buffer: 0, // Useful for percentage based heights when they might not always be exactly the same (in pixels). columnThreshold: 0.01, // Reading the width of elements isn't precise enough and can cause columns to jump between values. columnWidth: 0, // A static number or function that returns a number which tells the plugin how wide the columns are (in pixels). - delimeter: null, // If your group is not json, and is comma delimeted, you could set delimeter to ','. + delimiter: null, // If your group is not json, and is comma delimeted, you could set delimiter to ','. easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)', // CSS easing function to use. filterMode: Shuffle.FilterMode.ANY, // When using an array with filter(), 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. group: Shuffle.ALL_ITEMS, // Initial filter group. diff --git a/docs/_includes/usage.html b/docs/_includes/usage.html index c609d79..a478bcd 100644 --- a/docs/_includes/usage.html +++ b/docs/_includes/usage.html @@ -1,7 +1,7 @@

    Usage

    The HTML Structure

    -

    The only real important thing here is the data-groups attribute. It has to be a valid JSON array of strings. It can also be a string delimeted by a value you provide with the delimeter option.

    +

    The only real important thing here is the data-groups attribute. It has to be a valid JSON array of strings. It can also be a string delimeted by a value you provide with the delimiter option.

    This example is using this site's grid. Each item would be 4 columns at the "sm" breakpoint (768px).

    diff --git a/docs/dist/shuffle.js b/docs/dist/shuffle.js index 9fa114b..ab31fdf 100644 --- a/docs/dist/shuffle.js +++ b/docs/dist/shuffle.js @@ -888,6 +888,12 @@ var Shuffle = function (_TinyEmitter) { _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; + } + _this.lastSort = {}; _this.group = Shuffle.ALL_ITEMS; _this.lastFilter = Shuffle.ALL_ITEMS; @@ -1112,7 +1118,7 @@ var Shuffle = function (_TinyEmitter) { // Check each element's data-groups attribute against the given category. var attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); - var keys = this.options.delimeter ? attr.split(this.options.delimeter) : JSON.parse(attr); + var keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); function testCategory(category) { return keys.includes(category); @@ -2207,9 +2213,9 @@ Shuffle.options = { // how wide the columns are (in pixels). columnWidth: 0, - // If your group is not json, and is comma delimeted, you could set delimeter + // If your group is not json, and is comma delimeted, you could set delimiter // to ','. - delimeter: null, + delimiter: null, // Useful for percentage based heights when they might not always be exactly // the same (in pixels). diff --git a/docs/dist/shuffle.js.map b/docs/dist/shuffle.js.map index 13cfafb..1fb316f 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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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 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.delimeter ?\n attr.split(this.options.delimeter) :\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 delimeter\n // to ','.\n delimeter: 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","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","e","createElement","cssText","appendChild","window","getComputedStyle","ret","removeChild","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","sorter","arr","options","opts","Object","assign","original","Array","from","revert","by","sort","valA","valB","undefined","compare","reverse","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","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_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","nodeType","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimeter","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","before","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","after","equals","getStylesForTransition","transitionDelay","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","_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","__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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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","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","e","createElement","cssText","appendChild","window","getComputedStyle","ret","removeChild","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","sorter","arr","options","opts","Object","assign","original","Array","from","revert","by","sort","valA","valB","undefined","compare","reverse","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","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","nodeType","jquery","position","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","before","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","after","equals","getStylesForTransition","transitionDelay","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","_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","__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 0a369f4..206a99a 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 g||"width"!==e?g||"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}v.removeChild(y);var E={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function I(t,e){var i=Object.assign({},E,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 b={},S="transitionend",T=0;function k(t){return!!b[t]&&(b[t].element.removeEventListener(S,b[t].listener),b[t]=null,!0)}function w(t,e){var i=S+(T+=1),n=function(t){t.currentTarget===t.target&&(k(i),e(t))};return t.addEventListener(S,n),b[i]={element:t,listener:n},i}function C(t){return Math.max.apply(Math,t)}function L(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 M(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 A(t){return Array.from(new Set(t))}var F=0,x=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.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_"+F,F+=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.delimeter?n.split(this.options.delimeter):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 I(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?_(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=L(e.width,n,s,o),a=D(i,l,s),u=z(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()).forEach(function(i){function n(){i.applyCss(p.Css.HIDDEN.after)}if(i.isHidden)return i.applyCss(p.Css.HIDDEN.before),void n();i.scale=p.Scale.HIDDEN,i.isHidden=!0;var s=t.getStylesForTransition(i,p.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(e)+"ms",t._queue.push({item:i,styles:s,callback:n}),e+=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=w(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(k),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=I(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=A(t).map(function(t){return new p(t)});this._initItems(i),this._resetCols();var n=I(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=A(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=_(t,"width",i),s=_(t,"height",i);e&&(n+=_(t,"marginLeft",i)+_(t,"marginRight",i),s+=_(t,"marginTop",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})}}]),i}();return x.ShuffleItem=p,x.ALL_ITEMS="all",x.FILTER_ATTRIBUTE_KEY="groups",x.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},x.Classes=d,x.FilterMode={ANY:"any",ALL:"all"},x.options={group:x.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimeter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:o,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:x.FilterMode.ANY,isCentered:!1,roundTransforms:!0},x.Point=f,x.Rect=c,x.__sorter=I,x.__getColumnSpan=L,x.__getAvailablePositions=D,x.__getShortColumn=z,x.__getCenteredPositions=M,x}); +!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 g||"width"!==e?g||"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}v.removeChild(y);var E={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function I(t,e){var i=Object.assign({},E,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 b={},S="transitionend",T=0;function k(t){return!!b[t]&&(b[t].element.removeEventListener(S,b[t].listener),b[t]=null,!0)}function w(t,e){var i=S+(T+=1),n=function(t){t.currentTarget===t.target&&(k(i),e(t))};return t.addEventListener(S,n),b[i]={element:t,listener:n},i}function C(t){return Math.max.apply(Math,t)}function L(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 M(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 A(t){return Array.from(new Set(t))}var F=0,x=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_"+F,F+=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 I(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?_(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=L(e.width,n,s,o),a=D(i,l,s),u=z(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()).forEach(function(i){function n(){i.applyCss(p.Css.HIDDEN.after)}if(i.isHidden)return i.applyCss(p.Css.HIDDEN.before),void n();i.scale=p.Scale.HIDDEN,i.isHidden=!0;var s=t.getStylesForTransition(i,p.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(e)+"ms",t._queue.push({item:i,styles:s,callback:n}),e+=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=w(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(k),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=I(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=A(t).map(function(t){return new p(t)});this._initItems(i),this._resetCols();var n=I(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=A(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=_(t,"width",i),s=_(t,"height",i);e&&(n+=_(t,"marginLeft",i)+_(t,"marginRight",i),s+=_(t,"marginTop",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})}}]),i}();return x.ShuffleItem=p,x.ALL_ITEMS="all",x.FILTER_ATTRIBUTE_KEY="groups",x.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},x.Classes=d,x.FilterMode={ANY:"any",ALL:"all"},x.options={group:x.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:x.FilterMode.ANY,isCentered:!1,roundTransforms:!0},x.Point=f,x.Rect=c,x.__sorter=I,x.__getColumnSpan=L,x.__getAvailablePositions=D,x.__getShortColumn=z,x.__getCenteredPositions=M,x}); //# sourceMappingURL=shuffle.min.js.map diff --git a/docs/dist/shuffle.min.js.map b/docs/dist/shuffle.min.js.map index 96a8555..4f71422 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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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 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.delimeter ?\n attr.split(this.options.delimeter) :\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 delimeter\n // to ','.\n delimeter: 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","ret","window","getComputedStyle","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","removeChild","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","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_this","_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","delimeter","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,WACAC,GAAI,SAAUC,EAAMC,EAAUC,GAC5B,IAAIC,EAAIC,KAAKD,IAAMC,KAAKD,MAOxB,OALCA,EAAEH,KAAUG,EAAEH,QAAaK,MAC1BC,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,KAAUC,MAAMC,KAAKL,UAAW,GAChCM,IAAWd,KAAKD,IAAMC,KAAKD,OAASH,QAAagB,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,MACpBmB,EAAOnB,EAAEH,GACTuB,KAEJ,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,aACjD4B,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,KClCT,SAAwBC,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,wBCnC5C,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,YAAYN,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,eACHrB,EAAQC,OACRD,EAAQG,QACRH,EAAQO,oBAGLZ,QAAQS,gBAAgB,cACxBT,QAAU,cAInBD,EAAYe,uBAEE,eACL,OACC,aACM,wBACG,sCAIJ,aACG,kCAGK,6BAKR,qBAGG,yBACK,MAKvBf,EAAYkB,eACD,SACD,MC1GV,IAAMjB,EAAU2B,SAASC,MAAQD,SAASE,gBACpC5F,EAAI0F,SAASG,cAAc,OACjC7F,EAAEwF,MAAMM,QAAU,gDAClB/B,EAAQgC,YAAY/F,OAGdgG,EAAgB,SADJC,OAAOC,iBAAiBlG,EAAG,MAArC4D,MCQR,SAAwBuC,EACtBpC,EAASyB,OACTY,yDAASH,OAAOC,iBAAiBnC,EAAS,MAEtChB,EAAQD,EAAUsD,EAAOZ,WAGxBa,GAA4C,UAAVb,EAK3Ba,GAA4C,WAAVb,OACnC1C,EAAUsD,EAAOE,YACxBxD,EAAUsD,EAAOG,eACjBzD,EAAUsD,EAAOI,gBACjB1D,EAAUsD,EAAOK,uBARV3D,EAAUsD,EAAOM,aACxB5D,EAAUsD,EAAOO,cACjB7D,EAAUsD,EAAOQ,iBACjB9D,EAAUsD,EAAOS,kBAQd9D,EDxBTgB,EAAQ+C,YAAY9G,GEapB,IAAM+G,YAEK,KAGL,aAGK,gBAGE,MAIN,WAIP,SAAwBC,EAAOC,EAAKC,OAC5BC,EAAOC,OAAOC,UAAWN,EAAUG,GACnCI,EAAWC,MAAMC,KAAKP,GACxBQ,GAAS,SAERR,EAAI/F,OAILiG,EAAKO,UA1CX,SAAmBC,WACbC,EAAID,EAAMzG,OAEP0G,GAAG,IACH,MACC5G,EAAI6G,KAAKC,MAAMD,KAAKE,UAAYH,EAAI,IACpCI,EAAOL,EAAM3G,KACbA,GAAK2G,EAAMC,KACXA,GAAKI,SAGNL,EAgCED,CAAUT,IAKI,mBAAZE,EAAKc,KACVC,KAAK,SAAC9E,EAAGC,MAEPoE,SACK,MAGHU,EAAOhB,EAAKc,GAAG7E,EAAE+D,EAAK5B,MACtB6C,EAAOjB,EAAKc,GAAG5E,EAAE8D,EAAK5B,kBAGf8C,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,OC9FT,IAAMuB,KACAC,EAAY,gBACdC,EAAQ,EAOZ,SAAgBC,EAAoBlF,WAC9B+E,EAAY/E,OACFA,GAAIM,QAAQ6E,oBAAoBH,EAAWD,EAAY/E,GAAInD,YAC3DmD,GAAM,MACX,GAMX,SAAgBoF,EAAgB9E,EAASjE,OACjC2D,EAdCgF,MADE,GAgBHnI,EAAW,SAACwI,GACZA,EAAIC,gBAAkBD,EAAIE,WACRvF,KACXqF,cAILG,iBAAiBR,EAAWnI,KAExBmD,IAAQM,UAASzD,YAEtBmD,WChCeyF,EAASvB,UACxBE,KAAKsB,IAAI3I,MAAMqH,KAAMF,GCY9B,SAAgByB,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,GASzC,SAAgBO,EAAsBC,EAAWN,EAAYF,MAExC,IAAfE,SACKM,UAyBHC,KAGGhJ,EAAI,EAAGA,GAAKuI,EAAUE,EAAYzI,MAE/Bd,KAAKgJ,EAASa,EAAUlJ,MAAMG,EAAGA,EAAIyI,YAG1CO,EAWT,SAAgBC,EAAeF,EAAWG,WCjFTvC,EDkFzBwC,GClFyBxC,EDkFFoC,ECjFtBlC,KAAK+B,IAAIpJ,MAAMqH,KAAMF,IDkFnB3G,EAAI,EAAGC,EAAM8I,EAAU7I,OAAQF,EAAIC,EAAKD,OAC3C+I,EAAU/I,IAAMmJ,EAAcD,GAAUH,EAAU/I,IAAMmJ,EAAcD,SACjElJ,SAIJ,EA0CT,SAAgBoJ,EAAqBC,EAAWC,OACxCC,OAKIpF,QAAQ,SAACqF,GACbD,EAAOC,EAAS7G,OAEX6G,EAAS7G,KAAKzD,KAAKsK,KAGnBA,EAAS7G,MAAQ6G,SAOxBC,KACEC,KACAC,mBACCrF,KAAKiF,GAAQpF,QAAQ,SAACI,OACrB8E,EAAYE,EAAOhF,KACpBrF,KAAKmK,OACJO,EAAWP,EAAUA,EAAUnJ,OAAS,GACxC2J,EAAMD,EAASlH,KAAOkH,EAAShH,MAC/BkH,EAASjD,KAAK8B,OAAOW,EAAiBO,GAAO,GAE/CE,EAAaV,EACbW,GAAU,KACVF,EAAS,EAAG,KACRG,QACIZ,EAAUa,MAAM,SAACC,OACnBC,EAAU,IAAI9H,EAAK6H,EAAEzH,KAAOoH,EAAQK,EAAExH,IAAKwH,EAAEvH,MAAOuH,EAAEtH,OAAQsH,EAAE1H,IAGhE4H,GAAaZ,EAAMa,KAAK,mBAAKhI,EAAKiI,WAAWH,EAASD,cAEnDjL,KAAKkL,GACPC,SAKMJ,OAOZD,EAAS,KACRQ,YACenB,EAAUiB,KAAK,mBAAYb,EAAMa,KAAK,SAACH,OAClDI,EAAajI,EAAKiI,WAAWf,EAAUW,UACzCI,MACiBJ,GAEdI,MAIO,KACRE,EAAWd,EAAae,UAAU,mBAASC,EAAMC,SAASJ,OACnDK,OAAOJ,EAAU,EAAGf,EAAKe,OAIlChB,EAAMqB,OAAOf,KACR7K,KAAK6K,QAOVe,OAAOtL,SAAUmK,GACxBzC,KAAK,SAAC9E,EAAGC,UAAOD,EAAEK,GAAKJ,EAAEI,KACzBsI,IAAI,mBAAY,IAAI9I,EAAMuH,EAAS9G,KAAM8G,EAAS7G,gBE5L9CqI,EAAY9I,UACZqE,MAAMC,KAAK,IAAIyE,IAAI/I,IAI5B,IAAIO,EAAK,EAEHyI,yBAQQnI,OAASmD,yIAEdA,QAAUE,OAAOC,UAAW6E,EAAQhF,QAASA,KAE7CiF,cACAC,MAAQF,EAAQG,YAChBC,WAAaJ,EAAQG,YACrBE,WAAY,IACZC,aAAc,IACdC,eAAgB,IAChBC,kBACAC,iBAAkB,IAClBC,cAEC9K,EAAK+K,EAAKC,kBAAkB/I,OAE7BjC,QACG,IAAIiL,UAAU,6DAGjBhJ,QAAUjC,IACV2B,GAAK,WAAaA,KACjB,IAEDuJ,UACAP,eAAgB,uUAjCHQ,8CAqCbtB,MAAQ1L,KAAKiN,iBAEbhG,QAAQiG,MAAQlN,KAAK6M,kBAAkB7M,KAAKiH,QAAQiG,YAGpDpJ,QAAQG,UAAUI,IAAI4H,EAAQ9H,QAAQgJ,WAGtCC,WAAWpN,KAAK0L,YAGhB2B,UAAYrN,KAAKsN,4BACftE,iBAAiB,SAAUhJ,KAAKqN,WAKX,aAAxB5H,SAAS8H,WAA2B,KAChCC,EAASxN,KAAKwN,OAAOC,KAAKzN,aACzBgJ,iBAAiB,OAAQ,SAAS0E,WAChC/E,oBAAoB,OAAQ+E,aAMjCC,EAAe3H,OAAOC,iBAAiBjG,KAAK8D,QAAS,MACrDuG,EAAiB4B,EAAQ2B,QAAQ5N,KAAK8D,SAASH,WAGhDkK,gBAAgBF,QAIhBG,YAAYzD,QAGZ0D,OAAO/N,KAAKiH,QAAQkF,MAAOnM,KAAKiH,QAAQ+G,kBAMxClK,QAAQmK,iBACRC,mBAAmBlO,KAAK0L,YACxB5H,QAAQyB,MAAM4I,qBAAuBnO,KAAKiH,QAAQmH,YAAWpO,KAAKiH,QAAQoH,wDASzEC,EAAiBtO,KAAKuO,cAAcd,KAAKzN,aACxCA,KAAKiH,QAAQuH,SAClBxO,KAAKiH,QAAQuH,SAASF,EAAgBtO,KAAKiH,QAAQwH,cACnDH,4CAScI,SAGM,iBAAXA,EACF1O,KAAK8D,QAAQ6K,cAAcD,GAGzBA,GAAUA,EAAO3M,UAAgC,IAApB2M,EAAO3M,SACtC2M,EAGEA,GAAUA,EAAOE,OACnBF,EAAO,GAGT,6CAQOvI,GAEU,WAApBA,EAAO0I,gBACJ/K,QAAQyB,MAAMsJ,SAAW,YAIR,WAApB1I,EAAO2I,gBACJhL,QAAQyB,MAAMuJ,SAAW,gDAa1BC,yDAAW/O,KAAKqM,WAAY2C,yDAAahP,KAAK0L,MAC9CuD,EAAMjP,KAAKkP,iBAAiBH,EAAUC,eAGvCG,qBAAqBF,QAGrB5C,WAAa0C,EAIM,iBAAbA,SACJ5C,MAAQ4C,GAGRE,2CAUQF,EAAUrD,cACrB0D,KACEC,YAGFN,IAAa9C,EAAQG,YACbV,IAKJxG,QAAQ,SAACoK,GACTC,EAAKC,gBAAgBT,EAAUO,EAAKxL,WAC9B7D,KAAKqP,KAENrP,KAAKqP,kEAkBJP,EAAUjL,MACA,mBAAbiL,SACFA,EAASlO,KAAKiD,EAASA,EAAS9D,UAInCyP,EAAO3L,EAAQ4L,aAAa,QAAUzD,EAAQ0D,sBAC9CtK,EAAOrF,KAAKiH,QAAQ2I,UACxBH,EAAKI,MAAM7P,KAAKiH,QAAQ2I,WACxBE,KAAKC,MAAMN,YAEJO,EAAajB,UACb1J,EAAKsG,SAASoD,UAGnBzH,MAAM2I,QAAQlB,GACZ/O,KAAKiH,QAAQiJ,aAAejE,EAAQkE,WAAWC,IAC1CrB,EAAS1D,KAAK2E,GAEhBjB,EAAS9D,MAAM+E,GAGjB3K,EAAKsG,SAASoD,uDAQAK,IAAAA,QAASC,IAAAA,SACtBnK,QAAQ,SAACoK,KACVe,WAGAnL,QAAQ,SAACoK,KACTgB,4CASE5E,KACHxG,QAAQ,SAACoK,KACRiB,+CASK7E,KACNxG,QAAQ,SAACoK,KACRkB,4DASFC,aAAezQ,KAAK0Q,oBAAoBzP,kDAU5ByK,SACS1L,KAAKiH,QAAvBmH,IAAAA,MAAOC,IAAAA,OACTsC,EAAgB3Q,KAAKiH,QAAQ2J,eAAiB,cAAgB,MAAO,QAIrEC,EAAW1J,OAAO9B,KAAKxB,EAAYe,IAAIR,OAAO0M,QAAQhF,IAAI,mBAAeiF,ECtTtEC,QAAQ,WAAY,SAACC,EAAKC,aAAWA,EAAGC,kBDuT3CC,EAAaT,EAAc9E,OAAOgF,GAAUQ,SAE5CnM,QAAQ,SAACoK,KACRxL,QAAQyB,MAAM+L,mBAAqBlD,EAAQ,OAC3CtK,QAAQyB,MAAMgM,yBAA2BlD,IACzCvK,QAAQyB,MAAMiM,mBAAqBJ,0DAKnC9J,MAAMC,KAAKvH,KAAK8D,QAAQ2N,UAC5B1D,OAAO,mBAAMxM,EAAQM,EAAI6P,EAAKzK,QAAQ0K,gBACtC7F,IAAI,mBAAM,IAAIjI,EAAYhC,4CAQhB6J,OACP+F,EAAWnK,MAAMC,KAAKvH,KAAK8D,QAAQ2N,iBAClC1K,EAAO/G,KAAK0L,MAAMG,OAAOH,gBAC3B5H,UACM2N,EAASG,QAAQ9N,yDAMrB9D,KAAK0L,MAAMqC,OAAO,mBAAQuB,EAAKvL,gEAI/B/D,KAAK0L,MAAMqC,OAAO,mBAASuB,EAAKvL,mDAU1BsG,EAAgBwH,OACzBC,gBAwBS,OArB2B,mBAA7B9R,KAAKiH,QAAQoC,YACfrJ,KAAKiH,QAAQoC,YAAYgB,GAGvBrK,KAAKiH,QAAQiG,MACfjB,EAAQ2B,QAAQ5N,KAAKiH,QAAQiG,OAAOvJ,MAGlC3D,KAAKiH,QAAQoC,YACfrJ,KAAKiH,QAAQoC,YAGXrJ,KAAK0L,MAAMzK,OAAS,EACtBgL,EAAQ2B,QAAQ5N,KAAK0L,MAAM,GAAG5H,SAAS,GAAMH,MAI7C0G,OAKAA,GAGFyH,EAAOD,yCASDxH,SAE2B,mBAA7BrK,KAAKiH,QAAQ8K,YACf/R,KAAKiH,QAAQ8K,YAAY1H,GACvBrK,KAAKiH,QAAQiG,MACfhH,EAAelG,KAAKiH,QAAQiG,MAAO,cAEnClN,KAAKiH,QAAQ8K,sDAWZ1H,yDAAiB4B,EAAQ2B,QAAQ5N,KAAK8D,SAASH,MACnDqO,EAAShS,KAAKiS,eAAe5H,GAC7BhB,EAAcrJ,KAAKkS,eAAe7H,EAAgB2H,GACpDG,GAAqB9H,EAAiB2H,GAAU3I,EAGhDzB,KAAK6B,IAAI7B,KAAK8B,MAAMyI,GAAqBA,GACzCnS,KAAKiH,QAAQmL,oBAEKxK,KAAK8B,MAAMyI,SAG5BE,KAAOzK,KAAKsB,IAAItB,KAAKC,MAAMsK,GAAoB,QAC/C9H,eAAiBA,OACjBiI,SAAWjJ,mDAOXvF,QAAQyB,MAAM3B,OAAS5D,KAAKuS,oBAAsB,wDAShDtJ,EAASjJ,KAAK8J,qDAQL0I,UACT5K,KAAK+B,IAAI6I,EAAQxS,KAAKiH,QAAQwL,cAAezS,KAAKiH,QAAQyL,oDAQzD9S,OAAMe,4DACVX,KAAKuM,gBAIJoG,QAAU3S,UACVU,KAAKd,EAAMe,6CAQZI,EAAIf,KAAKqS,cACRvI,aACE/I,MACA,OACA+I,UAAU7J,KAAK,mCAShByL,cACAkH,EAAgB5S,KAAK6S,kBAAkBnH,GAEzCjD,EAAQ,IACNvD,QAAQ,SAACoK,EAAMvO,YACVlB,MACF8E,SAASd,EAAYe,IAAIN,QAAQwO,UAKpC9P,EAAM+P,OAAOzD,EAAKtK,MAAO4N,EAAc7R,MAAQuO,EAAKtL,kBACjDW,SAASd,EAAYe,IAAIN,QAAQwM,mBAKnC9L,MAAQ4N,EAAc7R,KACtB+D,MAAQjB,EAAYkB,MAAMT,UAC1BN,UAAW,MAIVmC,EAAS6M,EAAKC,uBAAuB3D,EAAMzL,EAAYe,IAAIN,QAAQwM,UAClEoC,gBAAkBF,EAAKG,kBAAkB1K,GAAS,OAEpDkE,OAAO1M,sCAMH,8CAWKyL,iBAGZ1L,KAAKiH,QAAQmM,WAAY,KACrBC,EAAY3H,EAAMI,IAAI,SAACwD,EAAMvO,OAC3BuS,EAAWrH,EAAQ2B,QAAQ0B,EAAKxL,SAAS,GACzCkB,EAAQuO,EAAKC,iBAAiBF,UAC7B,IAAIjQ,EAAK2B,EAAM/B,EAAG+B,EAAM9B,EAAGoQ,EAAS3P,MAAO2P,EAAS1P,OAAQ7C,YAG9Df,KAAKyT,wBAAwBJ,EAAWrT,KAAKqK,uBAK/CqB,EAAMI,IAAI,mBAAQyH,EAAKC,iBAAiBvH,EAAQ2B,QAAQ0B,EAAKxL,SAAS,+CAS9DwP,UFzcnB,oBACEA,IAAAA,SAAUxJ,IAAAA,UAAW4J,IAAAA,SAAUC,IAAAA,MAAOpK,IAAAA,UAAWU,IAAAA,OAE3C2J,EAAOzK,EAAcmK,EAAS3P,MAAO+P,EAAUC,EAAOpK,GACtDsK,EAAOhK,EAAsBC,EAAW8J,EAAMD,GAC9CG,EAAmB9J,EAAe6J,EAAM5J,GAGxCjF,EAAQ,IAAIhC,EAAM0Q,EAAWI,EAAkBD,EAAKC,IAKpDC,EAAYF,EAAKC,GAAoBR,EAAS1P,OAC3C7C,EAAI,EAAGA,EAAI6S,EAAM7S,MACd+S,EAAmB/S,GAAKgT,SAG7B/O,EEwbEgP,uBAEMhU,KAAK8J,mBACN9J,KAAKsS,eACRtS,KAAKqS,eACDrS,KAAKiH,QAAQmL,uBAChBpS,KAAKiH,QAAQgD,yDAWDG,EAAWC,UAC1BF,EAAqBC,EAAWC,gDASnC5B,EAAQ,0DADOzI,KAAKiU,sBAEb/O,QAAQ,SAACoK,YACTzP,MACF8E,SAASd,EAAYe,IAAIR,OAAO0O,UASnCxD,EAAKtL,kBACFW,SAASd,EAAYe,IAAIR,OAAO0M,mBAKlChM,MAAQjB,EAAYkB,MAAMX,SAC1BJ,UAAW,MAEVmC,EAAS+N,EAAKjB,uBAAuB3D,EAAMzL,EAAYe,IAAIR,OAAO0M,UACjEoC,gBAAkBgB,EAAKf,kBAAkB1K,GAAS,OAEpDkE,OAAO1M,sCAMH,4CAUND,KAAKsM,YAAatM,KAAKuM,kBAIvB4H,wDAWgB7E,EAAM8E,OAErBjO,EAASgB,OAAOC,UAAWgN,MAE7BpU,KAAKiH,QAAQ2J,cAAe,KACxB3N,EAAIjD,KAAKiH,QAAQoN,gBAAkBzM,KAAK8B,MAAM4F,EAAKtK,MAAM/B,GAAKqM,EAAKtK,MAAM/B,EACzEC,EAAIlD,KAAKiH,QAAQoN,gBAAkBzM,KAAK8B,MAAM4F,EAAKtK,MAAM9B,GAAKoM,EAAKtK,MAAM9B,IACxEoR,uBAAyBrR,SAAQC,eAAcoM,EAAKxK,iBAEpDrB,KAAO6L,EAAKtK,MAAM/B,EAAI,OACtBS,IAAM4L,EAAKtK,MAAM9B,EAAI,YAGvBiD,8CAUWrC,EAASyQ,EAAcC,OACnChR,EAAKoF,EAAgB9E,EAAS,SAAC+E,SAE9B,KAAMA,UAGR4D,aAAaxM,KAAKuD,kDASF0D,qBACd,SAACsN,KACDlF,KAAK3K,SAASuC,EAAKf,UACnBsO,oBAAoBvN,EAAKoI,KAAKxL,QAASoD,EAAKrH,SAAU2U,4CAUzDxU,KAAK0M,sBACFgI,sBAGDC,EAAW3U,KAAKiH,QAAQmH,MAAQ,EAChCwG,EAAW5U,KAAK2M,OAAO1L,OAAS,EAElC2T,GAAYD,GAAY3U,KAAKwM,mBAC1BqI,kBAAkB7U,KAAK2M,QACnBiI,QACJE,kBAAkB9U,KAAK2M,aACvBoI,UAAU9I,EAAQ+I,UAAUC,cAM5BF,UAAU9I,EAAQ+I,UAAUC,aAI9BtI,OAAO1L,OAAS,4CAOLsH,mBAEXmE,iBAAkB,EbntBV,SAAkBwI,EAAKC,EAAStV,GAC1CA,IACoB,mBAAZsV,GACTtV,EAAWsV,EACXA,EAAU,MAEVtV,EAAW+C,GAIf,IAAIwS,EAAUF,GAAOA,EAAIjU,OACzB,IAAKmU,EAAS,OAAOvV,EAAS,SAE9B,IAAIwV,GAAW,EACXC,EAAU,IAAIhO,MAAM8N,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,OamsBKwH,EAAYuD,IAAI,mBAAO4J,EAAKC,uBAAuBvQ,KAEjDpF,KAAK4V,kBAAkBnI,KAAKzN,sDAK3CyM,aAAavH,QAAQwD,QAGrB+D,aAAaxL,OAAS,OAGtByL,iBAAkB,4CAQPmJ,MACZA,EAAQ5U,OAAQ,KACZ6U,EAAWD,EAAQ/J,IAAI,mBAAO1G,EAAIkK,KAAKxL,YAErCiS,iBAAiBD,EAAU,aACzB5Q,QAAQ,SAACE,KACXkK,KAAK3K,SAASS,EAAIe,UAClBtG,iEAOL4M,aAAaxL,OAAS,OACtByL,iBAAkB,OAClBqI,UAAU9I,EAAQ+I,UAAUC,uCAS5BlG,EAAUiH,GACVhW,KAAKsM,cAILyC,GAAaA,GAAgC,IAApBA,EAAS9N,YAC1BgL,EAAQG,gBAGhB6J,QAAQlH,QAGRmH,eAGAC,wBAGAlO,KAAK+N,uCAOPI,yDAAcpW,KAAKkM,YACjBlM,KAAKsM,gBAIL+J,iBAEC3K,EAAQ3E,EAAO/G,KAAK0Q,oBAAqB0F,QAE1CE,QAAQ5K,QAIR6K,qBAGAC,yBAEAtK,SAAWkK,wCAOXK,0DACDzW,KAAKsM,YACFmK,QAEE3I,mBAIF7F,8CAUFkM,QAAO,+BAQVuC,cACIhL,EAAQK,EAAY2K,GAAU5K,IAAI,mBAAM,IAAIjI,EAAYhC,UAGzDuL,WAAW1B,QAGX2K,iBAGCM,EAAc5P,EADH/G,KAAK4W,eAAelL,GACA1L,KAAKkM,UACpC2K,EAAoB7W,KAAKiW,QAAQjW,KAAKqM,WAAYsK,GAElDG,EAAY,mBAAQpL,EAAMC,SAAS2D,IACnCyH,EAAmB,SAACzH,KACnBxK,MAAQjB,EAAYkB,MAAMX,SAC1BJ,UAAW,IACXW,SAASd,EAAYe,IAAIR,OAAO0M,UAChCnM,SAASd,EAAYe,IAAIR,OAAO0O,QAKjCF,EAAgB5S,KAAK6S,kBAAkBgE,EAAkBzH,WAC7CA,QAAQlK,QAAQ,SAACoK,EAAMvO,GACnC+V,EAAUxH,OACPtK,MAAQ4N,EAAc7R,KACVuO,KACZ3K,SAASqS,EAAK/D,uBAAuB3D,YAI5BD,OAAOnK,QAAQ,SAACoK,GAC5BwH,EAAUxH,MACKA,UAKhBxL,QAAQmK,iBAGRC,mBAAmBxC,QAGnBA,MAAQ1L,KAAK4W,eAAelL,QAG5BqC,OAAO/N,KAAKqM,mDAOZC,WAAY,uCAOZ2K,kEACA3K,WAAY,EACb2K,QACG9C,wCAUF2B,iBACAA,EAAS7U,YAIR+N,EAAajD,EAAY+J,GAEzBoB,EAAWlI,EACdlD,IAAI,mBAAWqL,EAAKC,iBAAiBtT,KACrCiK,OAAO,oBAAUuB,SAcfH,wCAEK+H,SAGLhB,QAAQgB,QAERjP,YAIAyD,MAAQ1L,KAAK0L,MAAMqC,OAAO,mBAASmJ,EAASvL,SAAS2D,UACrD6G,wBAEAhW,KAAK8L,EAAQ+I,UAAUC,OA1BP,aACdoC,cAAcH,KAGRhS,QAAQ,SAACpB,KACV7B,WAAW4E,YAAY/C,OAG5BiR,UAAU9I,EAAQ+I,UAAUsC,SAAWtI,2DA0B/BlL,UACR9D,KAAK0L,MAAM6L,KAAK,mBAAQjI,EAAKxL,UAAYA,yDAS3CuT,cAAcrX,KAAK0L,YACnBc,eAAgB,OAGhBd,MAAQ1L,KAAKiN,iBAGbG,WAAWpN,KAAK0L,YAEhBvL,KAAK8L,EAAQ+I,UAAUC,OAAQ,aAE7B/G,mBAAmBsJ,EAAK9L,SACxBc,eAAgB,SAIlBuB,OAAO/N,KAAKqM,mDAOZqI,yBACE/L,oBAAoB,SAAU3I,KAAKqN,gBAGrCvJ,QAAQG,UAAUC,OAAO,gBACzBJ,QAAQS,gBAAgB,cAGxB8S,cAAcrX,KAAK0L,YAEnBA,MAAMzK,OAAS,OACfwL,aAAaxL,OAAS,OAGtBgG,QAAQiG,MAAQ,UAChBpJ,QAAU,UAIVyI,aAAc,OACdD,WAAY,oCAyBJxI,OAAS2T,0DAEhBtR,EAASH,OAAOC,iBAAiBnC,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,sEAkBzC2P,EAAUjW,OAI1Bc,EAAOmV,EAAShK,IAAI,SAAChI,OACjByB,EAAUzB,EAAVyB,MACFmS,EAAWnS,EAAM+L,mBACjBqG,EAAQpS,EAAM2N,yBAGd5B,mBATK,QAUL4B,gBAVK,mCAqBJ,GAAGjF,cAGH/I,QAAQ,SAACpB,EAAS/C,KACjBwE,MAAM+L,mBAAqB3Q,EAAKI,GAAG2W,WACnCnS,MAAM2N,gBAAkBvS,EAAKI,GAAG4W,wBAK9C1L,EAAQpI,YAAcA,EAEtBoI,EAAQG,UAAY,MACpBH,EAAQ0D,qBAAuB,SAG/B1D,EAAQ+I,kBACE,yBACC,mBAIX/I,EAAQ9H,QAAUA,EAGlB8H,EAAQkE,gBACD,UACA,OAIPlE,EAAQhF,eAECgF,EAAQG,gBAGR,WAGC,8CAGM,UAIP,iBAIM,cAIA,YAIF,YAIH,kBAIS,gBAIJ,6BAOC,kBAGC,oBAGG,mBAGH,aAKHH,EAAQkE,WAAWC,gBAGnB,mBAIK,GAGnBnE,EAAQjJ,MAAQA,EAChBiJ,EAAQ5I,KAAOA,EAGf4I,EAAQ2L,SAAW7Q,EACnBkF,EAAQ4L,gBAAkB1O,EAC1B8C,EAAQ6L,wBAA0BjO,EAClCoC,EAAQ8L,iBAAmB/N,EAC3BiC,EAAQ+L,uBAAyB7N"} \ 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","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst { width } = window.getComputedStyle(e, null);\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING 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 (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && 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","ret","window","getComputedStyle","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","removeChild","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 diff --git a/index.d.ts b/index.d.ts index e43e41e..0c192e8 100644 --- a/index.d.ts +++ b/index.d.ts @@ -258,8 +258,9 @@ declare namespace Shuffle { columnWidth?: number; /** - * If your group is not json, and is comma delimeted, you could set delimeter to ','. + * If your group is not json, and is comma delimeted, you could set delimiter to ','. */ + delimiter?: string; delimeter?: string; /** diff --git a/src/shuffle.js b/src/shuffle.js index 8634a97..22972cc 100644 --- a/src/shuffle.js +++ b/src/shuffle.js @@ -39,6 +39,12 @@ class Shuffle extends TinyEmitter { super(); 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; + } + this.lastSort = {}; this.group = Shuffle.ALL_ITEMS; this.lastFilter = Shuffle.ALL_ITEMS; @@ -239,8 +245,8 @@ class Shuffle extends TinyEmitter { // Check each element's data-groups attribute against the given category. const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); - const keys = this.options.delimeter ? - attr.split(this.options.delimeter) : + const keys = this.options.delimiter ? + attr.split(this.options.delimiter) : JSON.parse(attr); function testCategory(category) { @@ -1150,9 +1156,9 @@ Shuffle.options = { // how wide the columns are (in pixels). columnWidth: 0, - // If your group is not json, and is comma delimeted, you could set delimeter + // If your group is not json, and is comma delimeted, you could set delimiter // to ','. - delimeter: null, + delimiter: null, // Useful for percentage based heights when they might not always be exactly // the same (in pixels). diff --git a/test/fixtures/delimeter.html b/test/fixtures/delimiter.html similarity index 97% rename from test/fixtures/delimeter.html rename to test/fixtures/delimiter.html index 7d9ddc8..0072fc0 100644 --- a/test/fixtures/delimeter.html +++ b/test/fixtures/delimiter.html @@ -1,4 +1,4 @@ -
    +
    Person 1
    Person 2
    Person 3
    diff --git a/test/test.js b/test/test.js index b3a13d7..af4b8bc 100644 --- a/test/test.js +++ b/test/test.js @@ -94,7 +94,7 @@ describe('shuffle', function () { expect(instance.options.sizer).to.equal(null); expect(instance.options.columnWidth).to.equal(0); expect(instance.options.gutterWidth).to.equal(0); - expect(instance.options.delimeter).to.equal(null); + expect(instance.options.delimiter).to.equal(null); expect(instance.options.initialSort).to.equal(null); expect(instance.options.throttleTime).to.equal(300); expect(instance.id).to.equal('shuffle_0'); @@ -606,12 +606,12 @@ describe('shuffle', function () { }); }); - describe('delimeter fixture', function () { + describe('delimiter fixture', function () { beforeEach(function (done) { // Mock the transition end event wrapper. sinon.stub(Shuffle.prototype, '_whenTransitionDone').callsFake(whenTransitionDoneStub); - appendFixture('delimeter').then(done); + appendFixture('delimiter').then(done); }); afterEach(function () { @@ -619,7 +619,16 @@ describe('shuffle', function () { removeFixture(); }); - it('can have a custom delimeter', function () { + it('can have a custom delimiter', function () { + instance = new Shuffle(fixture, { + delimiter: ',', + group: 'design', + }); + + expect(instance.visibleItems).to.equal(3); + }); + + it('can use the old misspelled delimiter option', function () { instance = new Shuffle(fixture, { delimeter: ',', group: 'design',