+
{{ content }}
{% include footer.html %} diff --git a/docs/_posts/2013-06-19-adding-removing.html b/docs/_posts/2013-06-19-adding-removing.html index b71dd2f..deaadc5 100644 --- a/docs/_posts/2013-06-19-adding-removing.html +++ b/docs/_posts/2013-06-19-adding-removing.html @@ -150,7 +150,7 @@ photoCredit: false

Adding elements

Wherever you add the element in the DOM is where it will show up in the grid (assuming you’re using the default sort-by-dom-order). With this in mind, you can append, prepend, or insert elements wherever you need to get them to show up in the right order.

-
Demo.prototype.setupEvents = function () {
+        
setupEvents() {
   document.querySelector('#append').addEventListener('click', this.onAppendBoxes.bind(this));
 };
 
@@ -158,7 +158,7 @@ photoCredit: false
  * Create some DOM elements, append them to the shuffle container, then notify
  * shuffle about the new items. You could also insert the HTML as a string.
  */
-Demo.prototype.onAppendBoxes = function () {
+onAppendBoxes() {
   var elements = this._getArrayOfElementsToAdd();
 
   elements.forEach(function (element) {
diff --git a/docs/_posts/2013-08-25-animated.html b/docs/_posts/2013-08-25-animated.html
index af64199..0c90b12 100644
--- a/docs/_posts/2013-08-25-animated.html
+++ b/docs/_posts/2013-08-25-animated.html
@@ -4,7 +4,7 @@ title: Animate In Demo
 description: When elements enter the viewport, they transition in from zero opacity and from the bottom.
 image: /demos/animated.jpg
 prism: true
-externalJS: [ "https://unpkg.com/intersection-observer" ]
+externalJS: []
 extraJS: [ "demos/animate-in.js" ]
 ---
 
@@ -38,7 +38,7 @@ extraJS: [ "demos/animate-in.js" ]

About this demo

This was inspired by codrops’ demo Loading effects for grid items with css animations.

-

IntersectionObserver is used to determine when the elements enter the viewport. A polyfill is included on the page for browsers which don't support it.

+

IntersectionObserver is used to determine when the elements enter the viewport.

Source code for this demo

diff --git a/docs/_scss/components/_buttons.scss b/docs/_scss/components/_buttons.scss index 1df5e11..2cc0920 100644 --- a/docs/_scss/components/_buttons.scss +++ b/docs/_scss/components/_buttons.scss @@ -18,7 +18,7 @@ border-radius: 0 3px 3px 0; } - label.btn input[type=radio] { + label.btn input[type='radio'] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; @@ -27,14 +27,14 @@ .btn { display: inline-block; - padding: .75em .8em; + padding: 0.75em 0.8em; text-align: center; border-radius: 3px; border: 1px solid $gray20; color: $gray20; font-size: 1rem; background-color: rgba($gray20, 0); - transition: .2s ease-out; + transition: 0.2s ease-out; cursor: pointer; -webkit-appearance: none; @@ -53,13 +53,13 @@ &.active, &:active { - box-shadow: inset 0 1px 2px rgba(0,0,0,.3); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3); color: white; background-color: $gray20; } &:focus.active { - box-shadow: inset 0 1px 2px rgba(0,0,0,.3), 0 0 0 2px rgba($gray20, 0.4); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba($gray20, 0.4); } &:disabled { @@ -99,7 +99,7 @@ $btn-variants: ( } &:focus.active { - box-shadow: inset 0 1px 2px rgba(0,0,0,.3), 0 0 0 2px rgba($color, 0.4); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba($color, 0.4); } &:disabled { @@ -128,10 +128,10 @@ $btn-variants: ( left: 50%; width: $size; height: $size; - margin-left: -$size / 2; - margin-top: -$size / 2; + margin-left: -$size * 0.5; + margin-top: -$size * 0.5; opacity: 0; - transition: .2s; + transition: 0.2s; } // Circle diff --git a/docs/_scss/components/_demo-list.scss b/docs/_scss/components/_demo-list.scss index 5883f64..e46bb9a 100644 --- a/docs/_scss/components/_demo-list.scss +++ b/docs/_scss/components/_demo-list.scss @@ -7,21 +7,20 @@ .demo-list .figure-wrap img { // Promote to its own layer. makes filters look ok on retina with images transform: translateZ(0); - transition: .1s ease; + transition: 0.1s ease; } .demo-list:hover .figure-wrap { - transform: scale3d( 1, 1, 1 ); + transform: scale3d(1, 1, 1); img { - filter: grayscale(1); } } .demo-list:hover .figure-wrap:hover { z-index: 2; - transform: scale3d( 1.05, 1.05, 1 ); + transform: scale3d(1.05, 1.05, 1); img { filter: none; @@ -38,11 +37,10 @@ .demo-list .figure-wrap figcaption { height: 2em; - margin-top: .5em; + margin-top: 0.5em; margin-bottom: 1em; } - .demo-link-container::before { content: '➜'; display: inline-block; @@ -59,7 +57,6 @@ span.demo-link-container::before { } @media screen and (max-width: 47.9375em) { - .demo-list + .demo-list { margin-top: 1em; } diff --git a/docs/_scss/components/_site-nav.scss b/docs/_scss/components/_site-nav.scss index 8974146..05dae78 100644 --- a/docs/_scss/components/_site-nav.scss +++ b/docs/_scss/components/_site-nav.scss @@ -1,4 +1,7 @@ .site-nav { + position: sticky; + top: 0; + z-index: 40; padding: 10px 0; border-bottom: 1px solid $gray90; margin-bottom: 28px; @@ -37,7 +40,7 @@ } .site-nav__logo rect { - transition: 180ms cubic-bezier(0.4, 0.0, 0.2, 1); + transition: 180ms cubic-bezier(0.4, 0, 0.2, 1); } .site-nav__link { @@ -51,7 +54,7 @@ .site-nav__dropdown { position: absolute; - z-index: 2; + z-index: 50; top: 40px; right: 0; opacity: 0; @@ -130,7 +133,7 @@ border-top: 6px solid currentColor; border-left: 5px solid transparent; border-right: 5px solid transparent; - transition: transform 180ms cubic-bezier(0.4, 0.0, 0.2, 1); + transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1); } .site-nav__link--dropdown-active { @@ -302,7 +305,6 @@ } .site-nav__dropdown--simple-links { - &::before { right: 24px; } diff --git a/docs/_scss/extensions/_grid-framework.scss b/docs/_scss/extensions/_grid-framework.scss index 53299b8..df4168c 100644 --- a/docs/_scss/extensions/_grid-framework.scss +++ b/docs/_scss/extensions/_grid-framework.scss @@ -1,3 +1,5 @@ +@use 'sass:math'; + $grid-gutter-width: 16px; $grid-columns: 12; $grid-container: 'container'; @@ -8,34 +10,23 @@ $grid-ratio-name: 'aspect'; $grid-ratio-inner-name: 'aspect__inner'; $grid-container-padding: ( xs: 3.5%, - sm: 7% + sm: 7%, ); $grid-max-width--desktop: 1200px; -$grid-ratios: ( - (16, 9), - (9, 16), - (4, 3), - (3, 4), - (3, 2), - (3, 1), - (2, 3), - (2, 1), - (1, 2), - (1, 1) -); +$grid-ratios: ((16, 9), (9, 16), (4, 3), (3, 4), (3, 2), (3, 1), (2, 3), (2, 1), (1, 2), (1, 1)); // 7% => 0.07 -$_grid-padding-pct: map-get($grid-container-padding, "sm") / 100%; +$_grid-padding-pct: math.div(map-get($grid-container-padding, 'sm'), 100%); // 0.07 => 0.14 => 0.86 $_grid-padding-value: 1 - $_grid-padding-pct * 2; // Size of the window when the grid row has hit max-width. -$_viewport-at-max-grid-width: $grid-max-width--desktop / $_grid-padding-value; +$_viewport-at-max-grid-width: math.div($grid-max-width--desktop, $_grid-padding-value); $viewport-at-max-grid-width: round($_viewport-at-max-grid-width) + 0px; $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-pct) + 0px; @function get-column-selector($number, $breakpoint) { - @return ".#{$grid-prefix}-#{$number}\\@#{$breakpoint}"; + @return '.#{$grid-prefix}-#{$number}\\@#{$breakpoint}'; } @function get-grid-breakpoint-selectors($breakpoint) { @@ -56,7 +47,6 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding- @return $selectors; } - @mixin make-grid-columns() { $selectors: get-all-grid-breakpoint-selectors(); @@ -66,12 +56,11 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding- // Prevent columns from collapsing when empty min-height: 1px; // Inner gutter via padding - padding-left: ($grid-gutter-width / 2); - padding-right: ($grid-gutter-width / 2); + padding-left: ($grid-gutter-width * 0.5); + padding-right: ($grid-gutter-width * 0.5); } } - @mixin float-grid-columns($breakpoint) { $selectors: get-grid-breakpoint-selectors($breakpoint); @@ -80,21 +69,20 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding- } } - -@mixin grid-ratios($breakpoint: "") { +@mixin grid-ratios($breakpoint: '') { // If there is a grid breakpoint class here, prepend a @. // e.g. "@sm" or "" when there isn't a class. - @if $breakpoint != "" { - $breakpoint: "\\@" + $breakpoint; + @if $breakpoint != '' { + $breakpoint: '\\@'+ $breakpoint; } // Note @extend isn't used because it cannot be used within @media directives. @each $list in $grid-ratios { $top: nth($list, 1); $bottom: nth($list, 2); - $name: "#{$top}x#{$bottom}"; + $name: '#{$top}x#{$bottom}'; .#{$grid-ratio-name}--#{$name}#{$breakpoint} { - padding-bottom: percentage($bottom / $top); + padding-bottom: percentage(math.div($bottom, $top)); } } @@ -109,34 +97,34 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding- } @mixin calc-grid-column($index, $columns, $breakpoint, $type) { - @if ($type == "width") and ($index > 0) { + @if ($type == 'width') and ($index > 0) { .#{$grid-prefix}-#{$index}\@#{$breakpoint} { - width: percentage(($index / $columns)); + width: percentage(math.div($index, $columns)); } } - @if ($type == "push") and ($index > 0) { + @if ($type == 'push') and ($index > 0) { .#{$grid-prefix}-push-#{$index}\@#{$breakpoint} { - left: percentage(($index / $columns)); + left: percentage(math.div($index, $columns)); } } - @if ($type == "push") and ($index == 0) { + @if ($type == 'push') and ($index == 0) { .#{$grid-prefix}-push-0\@#{$breakpoint} { left: auto; } } - @if ($type == "pull") and ($index > 0) { + @if ($type == 'pull') and ($index > 0) { .#{$grid-prefix}-pull-#{$index}\@#{$breakpoint} { - right: percentage(($index / $columns)); + right: percentage(math.div($index, $columns)); } } - @if ($type == "pull") and ($index == 0) { + @if ($type == 'pull') and ($index == 0) { .#{$grid-prefix}-pull-0\@#{$breakpoint} { right: auto; } } - @if ($type == "offset") { + @if ($type == 'offset') { .#{$grid-prefix}-offset-#{$index}\@#{$breakpoint} { - margin-left: percentage(($index / $columns)); + margin-left: percentage(math.div($index, $columns)); } } } @@ -152,8 +140,8 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding- @include float-grid-columns($breakpoint); @include grid-ratios($breakpoint); - @include loop-grid-columns($columns, $breakpoint, "width"); - @include loop-grid-columns($columns, $breakpoint, "pull"); - @include loop-grid-columns($columns, $breakpoint, "push"); - @include loop-grid-columns($columns, $breakpoint, "offset"); + @include loop-grid-columns($columns, $breakpoint, 'width'); + @include loop-grid-columns($columns, $breakpoint, 'pull'); + @include loop-grid-columns($columns, $breakpoint, 'push'); + @include loop-grid-columns($columns, $breakpoint, 'offset'); } diff --git a/docs/_scss/extensions/_mixins.scss b/docs/_scss/extensions/_mixins.scss index 1bd62ce..5338ff1 100644 --- a/docs/_scss/extensions/_mixins.scss +++ b/docs/_scss/extensions/_mixins.scss @@ -1,4 +1,3 @@ - // @param {string} bp Breakpoint value. One of `xs, sm, md, lg`. // @param {boolean} isMaxWidth By default, the media queries are mobile first, // so they use `min-width: __px`. By passing `true`, the mixin will subtract @@ -6,11 +5,13 @@ // @param {boolean} isScreenOnly Whether to hide this media query from print styles. // // Note: For print media, we want the default styles and the xs breakpoint to take effect. +@use 'sass:math'; + @mixin breakpoint($bp, $isMaxWidth: false, $isScreenOnly: true) { $media-query: get-breakpoint-query($bp, $isMaxWidth); @if $isScreenOnly { - $media-query: "screen and #{$media-query}"; + $media-query: 'screen and #{$media-query}'; } @media #{$media-query} { @@ -29,7 +30,7 @@ @mixin clearfix() { &::before, &::after { - content: " "; + content: ' '; display: table; } @@ -47,7 +48,7 @@ } @mixin aspect($width, $height) { - padding-bottom: percentage($height / $width); + padding-bottom: percentage(math.div($height, $width)); } @mixin no-aspect() { @@ -65,9 +66,9 @@ } @if map-has-key($breakpoints, $bp) { - @return "(#{$media}: #{$breakpoint})"; + @return '(#{$media}: #{$breakpoint})'; } @else { @warn "#{$bp} not recognized. Valid breakpoints: #{map-keys($breakpoints)}"; - @return "screen"; + @return 'screen'; } } diff --git a/docs/_scss/extensions/_variables.scss b/docs/_scss/extensions/_variables.scss index 5f3c173..1c921e4 100644 --- a/docs/_scss/extensions/_variables.scss +++ b/docs/_scss/extensions/_variables.scss @@ -3,38 +3,38 @@ $breakpoints: ( sm: 768px, md: 1024px, lg: 1392px, - xl: 1680px + xl: 1680px, ); // Colors from Flat UI -$turqoise: #1ABC9C; -$greenSea: #16A085; -$emerald: #2ECC71; -$nephritis: #27AE60; -$river: #3498DB; -$belizeHole: #2980B9; -$amethyst: #9B59B6; -$wisteria: #8E44AD; -$wet-asphalt: #34495E; -$midnightBlue: #2C3E50; -$sunflower: #F1C40F; -$orange: #F39C12; -$carrot: #E67E22; -$pumpkin: #D35400; -$alizarin: #E74C3C; -$pomegranate: #C0392B; -$clouds: #ECF0F1; -$silver: #BDC3C7; -$concrete: #95A5A6; -$asbestos: #7F8C8D; +$turqoise: #1abc9c; +$greenSea: #16a085; +$emerald: #2ecc71; +$nephritis: #27ae60; +$river: #3498db; +$belizeHole: #2980b9; +$amethyst: #9b59b6; +$wisteria: #8e44ad; +$wet-asphalt: #34495e; +$midnightBlue: #2c3e50; +$sunflower: #f1c40f; +$orange: #f39c12; +$carrot: #e67e22; +$pumpkin: #d35400; +$alizarin: #e74c3c; +$pomegranate: #c0392b; +$clouds: #ecf0f1; +$silver: #bdc3c7; +$concrete: #95a5a6; +$asbestos: #7f8c8d; $black: #000; $gray10: $midnightBlue; $gray20: $wet-asphalt; -$gray30: #5D6D77; +$gray30: #5d6d77; $gray50: $asbestos; $gray60: $concrete; $gray80: $silver; -$gray90: #E1E5E6; +$gray90: #e1e5e6; $gray95: $clouds; -$white: #FFF; +$white: #fff; diff --git a/docs/_scss/global-rules/_forms.scss b/docs/_scss/global-rules/_forms.scss index d400cfc..fe5cd72 100644 --- a/docs/_scss/global-rules/_forms.scss +++ b/docs/_scss/global-rules/_forms.scss @@ -7,11 +7,11 @@ padding: 0.5em; font-size: 1rem; color: $gray20; - transition: .15s; + transition: 0.15s; &::placeholder { color: $gray60; - transition: .15s; + transition: 0.15s; } &:hover { diff --git a/docs/_scss/global-rules/_grid.scss b/docs/_scss/global-rules/_grid.scss index d90cf51..28044e5 100644 --- a/docs/_scss/global-rules/_grid.scss +++ b/docs/_scss/global-rules/_grid.scss @@ -1,9 +1,11 @@ -@import "../extensions/grid-framework"; +@use 'sass:math'; + +@import '../extensions/grid-framework'; // .container .#{$grid-container} { - padding-left: map-get($grid-container-padding, "xs"); - padding-right: map-get($grid-container-padding, "xs"); + padding-left: map-get($grid-container-padding, 'xs'); + padding-right: map-get($grid-container-padding, 'xs'); @include clearfix(); } @@ -14,8 +16,8 @@ @include clearfix(); .#{$grid-row} { - margin-left: $grid-gutter-width / -2; - margin-right: $grid-gutter-width / -2; + margin-left: math.div($grid-gutter-width, -2); + margin-right: math.div($grid-gutter-width, -2); } &--centered { @@ -50,13 +52,12 @@ @include make-grid(xs, 6); @include breakpoint(sm) { - @include make-grid(sm); // Add more padding to the container class. .#{$grid-container} { - padding-left: map-get($grid-container-padding, "sm"); - padding-right: map-get($grid-container-padding, "sm"); + padding-left: map-get($grid-container-padding, 'sm'); + padding-right: map-get($grid-container-padding, 'sm'); } .#{$grid-row} { @@ -65,7 +66,6 @@ } @include breakpoint(md) { - @include make-grid(md); } @@ -73,9 +73,9 @@ position: relative; overflow: visible; margin-top: 0.5em; - margin-right: calc(-3.5vw - #{($grid-gutter-width / 2)}); + margin-right: calc(-3.5vw - #{($grid-gutter-width * 0.5)}); margin-bottom: 0.5em; - margin-left: calc(-3.5vw - #{($grid-gutter-width / 2)}); + margin-left: calc(-3.5vw - #{($grid-gutter-width * 0.5)}); pre { position: relative; @@ -83,23 +83,22 @@ min-height: 56px; padding-top: 1em; padding-bottom: 1em; - padding-left: calc(3.5vw + #{($grid-gutter-width / 2)}); - padding-right: calc(3.5vw + #{($grid-gutter-width / 2)}); + padding-left: calc(3.5vw + #{($grid-gutter-width * 0.5)}); + padding-right: calc(3.5vw + #{($grid-gutter-width * 0.5)}); margin: 0; } } @include breakpoint(sm) { - .code-block { - margin-left: calc(-7vw - #{($grid-gutter-width / 2)}); - margin-right: calc(-7vw - #{($grid-gutter-width / 2)}); + margin-left: calc(-7vw - #{($grid-gutter-width * 0.5)}); + margin-right: calc(-7vw - #{($grid-gutter-width * 0.5)}); pre { position: relative; z-index: 1; - padding-left: calc(7vw + #{($grid-gutter-width / 2)}); - padding-right: calc(7vw + #{($grid-gutter-width / 2)}); + padding-left: calc(7vw + #{($grid-gutter-width * 0.5)}); + padding-right: calc(7vw + #{($grid-gutter-width * 0.5)}); } } } @@ -120,14 +119,13 @@ // } @media (min-width: $viewport-at-max-grid-width) { - .code-block { - margin-left: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width / 2}); - margin-right: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width / 2}); + margin-left: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width * 0.5}); + margin-right: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width * 0.5}); pre { - padding-left: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width / 2}); - padding-right: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width / 2}); + padding-left: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width * 0.5}); + padding-right: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width * 0.5}); } } } diff --git a/docs/_scss/global-rules/_helpers.scss b/docs/_scss/global-rules/_helpers.scss index 5120cf0..c916140 100644 --- a/docs/_scss/global-rules/_helpers.scss +++ b/docs/_scss/global-rules/_helpers.scss @@ -1,15 +1,21 @@ -.text-center { text-align: center; } +.text-center { + text-align: center; +} .ib { display: inline-block; } @include breakpoint(sm, true) { - .hidden\@xs { display: none; } + .hidden\@xs { + display: none; + } } @include breakpoint(sm) { - .visible\@xs { display: none; } + .visible\@xs { + display: none; + } } // Hide from both screenreaders and browsers. @@ -32,7 +38,7 @@ .clearfix, .clearfix::after { - content: " "; + content: ' '; display: table; clear: both; } @@ -45,8 +51,12 @@ float: right; } -.full-width { width: 100%; } -.full-height { height: 100%; } +.full-width { + width: 100%; +} +.full-height { + height: 100%; +} .hide-text { font: 0/0 a; diff --git a/docs/_scss/global-rules/_type.scss b/docs/_scss/global-rules/_type.scss index 54eb782..9951bd2 100644 --- a/docs/_scss/global-rules/_type.scss +++ b/docs/_scss/global-rules/_type.scss @@ -113,20 +113,20 @@ p { text-decoration: underline; } -code:not([class*="language"]) { +code:not([class*='language']) { padding: 0; padding-top: 0.2em; padding-bottom: 0.2em; margin: 0; font-size: 85%; color: $gray10; - background-color: rgba(27,31,35,0.05); + background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; - font-family: Menlo, Consolas, "Liberation Mono", Courier, monospace; + font-family: Menlo, Consolas, 'Liberation Mono', Courier, monospace; } -code:not([class*="language"])::before, -code:not([class*="language"])::after { - content: "\00a0"; - letter-spacing: -.2em; +code:not([class*='language'])::before, +code:not([class*='language'])::after { + content: '\00a0'; + letter-spacing: -0.2em; } diff --git a/docs/_scss/pages/_compound-filters.scss b/docs/_scss/pages/_compound-filters.scss index 7bff3ff..2f1f2eb 100644 --- a/docs/_scss/pages/_compound-filters.scss +++ b/docs/_scss/pages/_compound-filters.scss @@ -1,5 +1,4 @@ -@import "../extensions/variables"; - +@import '../extensions/variables'; .compound-filter-options { margin-top: 20px; @@ -7,7 +6,6 @@ } .filter-group--compound { - button { width: 40px; height: 40px; @@ -73,14 +71,13 @@ transform: rotate(45deg) scale(0.707106781); } - @mixin equilateralTriangle($size) { $sqrt3: 1.73205080757; - $halfSize: $size / 2; + $halfSize: $size * 0.5; $fullSideWidth: round($sqrt3 * $halfSize); $leftOver: $size - $fullSideWidth; - padding-top: $leftOver / 2; + padding-top: $leftOver * 0.5; height: 0; width: 0; border-width: 0 $halfSize $fullSideWidth $halfSize; diff --git a/docs/_scss/pages/_faq.scss b/docs/_scss/pages/_faq.scss index 9947d4d..dc8c901 100644 --- a/docs/_scss/pages/_faq.scss +++ b/docs/_scss/pages/_faq.scss @@ -9,7 +9,7 @@ float: none; margin: 2em 0; overflow: hidden; - transition: .2s ease-out; + transition: 0.2s ease-out; } .question--collapsed { @@ -18,7 +18,7 @@ border-width: 0; } -.question--collapsed + .question { +.question--collapsed + .question { margin-top: 0; } diff --git a/docs/_scss/pages/_homepage-filters.scss b/docs/_scss/pages/_homepage-filters.scss index 1ce29c3..28500a5 100644 --- a/docs/_scss/pages/_homepage-filters.scss +++ b/docs/_scss/pages/_homepage-filters.scss @@ -1,4 +1,3 @@ - // Filters .filter-label { display: block; diff --git a/docs/_scss/shuffle-styles.scss b/docs/_scss/shuffle-styles.scss index aaabd31..3b32347 100644 --- a/docs/_scss/shuffle-styles.scss +++ b/docs/_scss/shuffle-styles.scss @@ -1,5 +1,5 @@ -@import "./extensions/variables"; -@import "./extensions/mixins"; +@import './extensions/variables'; +@import './extensions/mixins'; /*=============================================*\ Some styles to show off masonry layout @@ -67,15 +67,13 @@ img.picture-item__blur { } @include breakpoint(sm) { - .picture-item--overlay { - .picture-item__details { position: absolute; bottom: 0; left: 0; width: 100%; - background-color: rgba(black, .6); + background-color: rgba(black, 0.6); color: white; overflow: hidden; } @@ -86,9 +84,7 @@ img.picture-item__blur { } @supports (filter: blur(1px)) and (clip-path: inset(0 0 0 0)) { - .picture-item--overlay { - .picture-item__blur { position: absolute; z-index: 1; @@ -112,7 +108,6 @@ img.picture-item__blur { } } - /* Shuffle needs either relative or absolute positioning on the container It will set it for you, but it'll cause another style recalculation and layout. @@ -129,7 +124,6 @@ img.picture-item__blur { visibility: hidden; } - /* Animate in styles */ .shuffle--animatein { overflow: visible; @@ -141,7 +135,7 @@ img.picture-item__blur { } .shuffle--animatein .picture-item__inner--transition { - transition: all .6s ease; + transition: all 0.6s ease; } .shuffle--animatein .picture-item.in .picture-item__inner { @@ -149,10 +143,7 @@ img.picture-item__blur { transform: translate(0, 0); } - - @include breakpoint(sm, true) { - .picture-item { height: auto; margin-top: 20px; @@ -160,12 +151,12 @@ img.picture-item__blur { .picture-item__details, .picture-item__description { - font-size: .875em; - padding: .625em; + font-size: 0.875em; + padding: 0.625em; } .picture-item__description { - padding-right: .875em; + padding-right: 0.875em; padding-bottom: 1.25em; } diff --git a/docs/_scss/style.scss b/docs/_scss/style.scss index 5303374..7033d53 100644 --- a/docs/_scss/style.scss +++ b/docs/_scss/style.scss @@ -1,16 +1,16 @@ -@import "./extensions/variables"; -@import "./extensions/mixins"; +@import './extensions/variables'; +@import './extensions/mixins'; -@import "./global-rules/global"; -@import "./global-rules/type"; -@import "./global-rules/grid"; -@import "./global-rules/forms"; -@import "./global-rules/helpers"; +@import './global-rules/global'; +@import './global-rules/type'; +@import './global-rules/grid'; +@import './global-rules/forms'; +@import './global-rules/helpers'; -@import "./components/buttons"; -@import "./components/demo-list"; -@import "./components/site-nav"; +@import './components/buttons'; +@import './components/demo-list'; +@import './components/site-nav'; -@import "./pages/homepage-filters"; -@import "./pages/compound-filters"; -@import "./pages/faq"; +@import './pages/homepage-filters'; +@import './pages/compound-filters'; +@import './pages/faq'; diff --git a/docs/css/prism.css b/docs/css/prism.css index cf4a934..b52518e 100644 --- a/docs/css/prism.css +++ b/docs/css/prism.css @@ -1,183 +1,4 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */ -/** - * prism.js default theme for JavaScript, CSS and HTML - * Based on dabblet (http://dabblet.com) - * @author Lea Verou - */ - -code[class*="language-"], -pre[class*="language-"] { - color: black; - background: none; - text-shadow: 0 1px white; - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, -code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { - text-shadow: none; - background: #b3d4fc; -} - -pre[class*="language-"]::selection, pre[class*="language-"] ::selection, -code[class*="language-"]::selection, code[class*="language-"] ::selection { - text-shadow: none; - background: #b3d4fc; -} - -@media print { - code[class*="language-"], - pre[class*="language-"] { - text-shadow: none; - } -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #f5f2f0; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} - -.token.punctuation { - color: #999; -} - -.namespace { - opacity: .7; -} - -.token.property, -.token.tag, -.token.boolean, -.token.number, -.token.constant, -.token.symbol, -.token.deleted { - color: #905; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.builtin, -.token.inserted { - color: #690; -} - -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #a67f59; - background: hsla(0, 0%, 100%, .5); -} - -.token.atrule, -.token.attr-value, -.token.keyword { - color: #07a; -} - -.token.function { - color: #DD4A68; -} - -.token.regex, -.token.important, -.token.variable { - color: #e90; -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} - -pre[data-line] { - position: relative; - padding: 1em 0 1em 3em; -} - -.line-highlight { - position: absolute; - left: 0; - right: 0; - padding: inherit 0; - margin-top: 1em; /* Same as .prism’s padding-top */ - - background: hsla(24, 20%, 50%,.08); - background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0)); - - pointer-events: none; - - line-height: inherit; - white-space: pre; -} - - .line-highlight:before, - .line-highlight[data-end]:after { - content: attr(data-start); - position: absolute; - top: .4em; - left: .6em; - min-width: 1em; - padding: 0 .5em; - background-color: hsla(24, 20%, 50%,.4); - color: hsl(24, 20%, 95%); - font: bold 65%/1.5 sans-serif; - text-align: center; - vertical-align: .3em; - border-radius: 999px; - text-shadow: none; - box-shadow: 0 1px white; - } - - .line-highlight[data-end]:after { - content: attr(data-end); - top: auto; - bottom: .4em; - } +/* PrismJS 1.26.0 +https://prismjs.com/download.html?#themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */ +code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} +pre[data-line]{position:relative;padding:1em 0 1em 3em}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}.line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:rgba(128,128,128,.2)} diff --git a/docs/css/shuffle-styles.css b/docs/css/shuffle-styles.css index 584772c..00b7ed9 100644 --- a/docs/css/shuffle-styles.css +++ b/docs/css/shuffle-styles.css @@ -1 +1 @@ -.picture-item{height:220px;margin-left:0;margin-top:24px}.picture-item img{display:block;width:100%}@supports ((-o-object-fit:cover) or (object-fit:cover)){.picture-item img{height:100%;max-width:none;-o-object-fit:cover;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{background:#ecf0f1;height:100%;overflow:hidden;position:relative}img.picture-item__blur{display:none}.picture-item__details{align-items:baseline;display:flex;justify-content:space-between;padding:1em;width:100%}.picture-item__description{margin:0;padding:0 2em 1em 1em;width:100%}.picture-item__title{flex-shrink:0;margin-right:4px}.picture-item__tags{flex-shrink:1;margin:0;text-align:right}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{background-color:rgba(0,0,0,.6);bottom:0;color:#fff;left:0;overflow:hidden;position:absolute;width:100%}.picture-item--overlay .picture-item__description{display:none}@supports (filter:blur(1px)) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{-webkit-clip-path:inset(170px 0 0 0);clip-path:inset(170px 0 0 0);display:block;filter:blur(7px);left:0;position:absolute;top:0;z-index:1}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{overflow:hidden;position:relative}.my-sizer-element{opacity:0;position:absolute;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{opacity:0;transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{opacity:1;transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-bottom:1.25em;padding-right:.875em}.picture-item--h2{height:auto}} \ No newline at end of file +.picture-item{height:220px;margin-left:0;margin-top:24px}.picture-item img{display:block;width:100%}@supports (object-fit:cover){.picture-item img{height:100%;max-width:none;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{background:#ecf0f1;height:100%;overflow:hidden;position:relative}img.picture-item__blur{display:none}.picture-item__details{align-items:baseline;display:flex;justify-content:space-between;padding:1em;width:100%}.picture-item__description{margin:0;padding:0 2em 1em 1em;width:100%}.picture-item__title{flex-shrink:0;margin-right:4px}.picture-item__tags{flex-shrink:1;margin:0;text-align:right}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{background-color:#0009;bottom:0;color:#fff;left:0;overflow:hidden;position:absolute;width:100%}.picture-item--overlay .picture-item__description{display:none}@supports (filter:blur(1px)) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{-webkit-clip-path:inset(170px 0 0 0);clip-path:inset(170px 0 0 0);display:block;filter:blur(7px);left:0;position:absolute;top:0;z-index:1}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{overflow:hidden;position:relative}.my-sizer-element{opacity:0;position:absolute;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{opacity:0;transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{opacity:1;transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-bottom:1.25em;padding-right:.875em}.picture-item--h2{height:auto}} \ No newline at end of file diff --git a/docs/css/style.css b/docs/css/style.css index c25d6b3..4f3a81b 100644 --- a/docs/css/style.css +++ b/docs/css/style.css @@ -1 +1 @@ -@charset "UTF-8";*,:after,:before{box-sizing:border-box}main{overflow:hidden}pre.max-height{max-height:30em}img,picture{display:block}img{height:auto;max-width:100%}figure,ul ul{margin:0}ul ul{list-style-type:circle;padding-left:1.25em}li{line-height:1.4}li+li{margin-top:4px}nav>a{display:block;margin:5px 0}#demos{margin-top:1em}body{color:#5d6d77;font-family:Open Sans,Helvetica Neue,Helvetica,sans-serif}a{text-decoration:none}a,a:visited{color:#3498db}a:hover{text-decoration:underline}a:active{color:#2ecc71}h1,h2,h3,h4,h5,h6{color:#34495e;font-weight:700}h1{font-size:10vw;font-weight:400;line-height:1}h1,h2{margin:3vw 0}h2{font-size:7vw;position:relative}h3{font-size:6vw;margin:2vw 0}h4{font-size:1.25em}p{line-height:1.4;margin:1em 0}.intro-text{font-size:1.125em;margin:.7em 0}@media screen and (min-width:768px){h1{font-size:3.5em;margin:.5em 0 .25em}h2{font-size:2.5em;margin:.45em 0}h3{font-size:1.5em;margin:.8em 0 .5em}h1>a,h2>a,h3>a{display:none}h1:hover>a,h2:hover>a,h3:hover>a{background:url(../img/link.svg) no-repeat;display:inline-block;height:50px;overflow:hidden;position:absolute;text-indent:-999em;top:0;width:50px}.intro-text{font-size:1.25em}}.unstyled{list-style-type:none;margin:0;padding:0}.type--underline{text-decoration:underline}code:not([class*=language]){background-color:rgba(27,31,35,.05);border-radius:3px;color:#2c3e50;font-family:Menlo,Consolas,Liberation Mono,Courier,monospace;font-size:85%;margin:0;padding:.2em 0}code:not([class*=language]):after,code:not([class*=language]):before{content:" ";letter-spacing:-.2em}.container{padding-left:3.5%;padding-right:3.5%}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.row{margin-left:auto;margin-right:auto}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.row .row{margin-left:-8px;margin-right:-8px}.row--centered{display:flex;flex-wrap:wrap;justify-content:center}.aspect{height:0;overflow:hidden;padding-bottom:100%;position:relative;width:100%}.aspect--16x9{padding-bottom:56.25%}.aspect--9x16{padding-bottom:177.7777777778%}.aspect--4x3{padding-bottom:75%}.aspect--3x4{padding-bottom:133.3333333333%}.aspect--3x2{padding-bottom:66.6666666667%}.aspect--3x1{padding-bottom:33.3333333333%}.aspect--2x3{padding-bottom:150%}.aspect--2x1{padding-bottom:50%}.aspect--1x2{padding-bottom:200%}.aspect--1x1{padding-bottom:100%}.aspect--none{height:auto;overflow:visible;padding-bottom:0}.aspect--none>.aspect__inner{position:static}.aspect>div,.aspect__inner{bottom:0;left:0;position:absolute;right:0;top:0}.col-10\@lg,.col-10\@md,.col-10\@sm,.col-10\@xs,.col-11\@lg,.col-11\@md,.col-11\@sm,.col-11\@xs,.col-12\@lg,.col-12\@md,.col-12\@sm,.col-12\@xs,.col-1\@lg,.col-1\@md,.col-1\@sm,.col-1\@xs,.col-2\@lg,.col-2\@md,.col-2\@sm,.col-2\@xs,.col-3\@lg,.col-3\@md,.col-3\@sm,.col-3\@xs,.col-4\@lg,.col-4\@md,.col-4\@sm,.col-4\@xs,.col-5\@lg,.col-5\@md,.col-5\@sm,.col-5\@xs,.col-6\@lg,.col-6\@md,.col-6\@sm,.col-6\@xs,.col-7\@lg,.col-7\@md,.col-7\@sm,.col-7\@xs,.col-8\@lg,.col-8\@md,.col-8\@sm,.col-8\@xs,.col-9\@lg,.col-9\@md,.col-9\@sm,.col-9\@xs{box-sizing:border-box;min-height:1px;padding-left:8px;padding-right:8px;position:relative}.col-10\@xs,.col-11\@xs,.col-12\@xs,.col-1\@xs,.col-2\@xs,.col-3\@xs,.col-4\@xs,.col-5\@xs,.col-6\@xs,.col-7\@xs,.col-8\@xs,.col-9\@xs{float:left}.aspect--16x9\@xs{padding-bottom:56.25%}.aspect--9x16\@xs{padding-bottom:177.7777777778%}.aspect--4x3\@xs{padding-bottom:75%}.aspect--3x4\@xs{padding-bottom:133.3333333333%}.aspect--3x2\@xs{padding-bottom:66.6666666667%}.aspect--3x1\@xs{padding-bottom:33.3333333333%}.aspect--2x3\@xs{padding-bottom:150%}.aspect--2x1\@xs{padding-bottom:50%}.aspect--1x2\@xs{padding-bottom:200%}.aspect--1x1\@xs{padding-bottom:100%}.aspect--none\@xs{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@xs>.aspect__inner{position:static}.col-1\@xs{width:16.6666666667%}.col-2\@xs{width:33.3333333333%}.col-3\@xs{width:50%}.col-4\@xs{width:66.6666666667%}.col-5\@xs{width:83.3333333333%}.col-6\@xs{width:100%}.col-pull-0\@xs{right:auto}.col-pull-1\@xs{right:16.6666666667%}.col-pull-2\@xs{right:33.3333333333%}.col-pull-3\@xs{right:50%}.col-pull-4\@xs{right:66.6666666667%}.col-pull-5\@xs{right:83.3333333333%}.col-pull-6\@xs{right:100%}.col-push-0\@xs{left:auto}.col-push-1\@xs{left:16.6666666667%}.col-push-2\@xs{left:33.3333333333%}.col-push-3\@xs{left:50%}.col-push-4\@xs{left:66.6666666667%}.col-push-5\@xs{left:83.3333333333%}.col-push-6\@xs{left:100%}.col-offset-0\@xs{margin-left:0}.col-offset-1\@xs{margin-left:16.6666666667%}.col-offset-2\@xs{margin-left:33.3333333333%}.col-offset-3\@xs{margin-left:50%}.col-offset-4\@xs{margin-left:66.6666666667%}.col-offset-5\@xs{margin-left:83.3333333333%}.col-offset-6\@xs{margin-left:100%}@media screen and (min-width:768px){.col-10\@sm,.col-11\@sm,.col-12\@sm,.col-1\@sm,.col-2\@sm,.col-3\@sm,.col-4\@sm,.col-5\@sm,.col-6\@sm,.col-7\@sm,.col-8\@sm,.col-9\@sm{float:left}.aspect--16x9\@sm{padding-bottom:56.25%}.aspect--9x16\@sm{padding-bottom:177.7777777778%}.aspect--4x3\@sm{padding-bottom:75%}.aspect--3x4\@sm{padding-bottom:133.3333333333%}.aspect--3x2\@sm{padding-bottom:66.6666666667%}.aspect--3x1\@sm{padding-bottom:33.3333333333%}.aspect--2x3\@sm{padding-bottom:150%}.aspect--2x1\@sm{padding-bottom:50%}.aspect--1x2\@sm{padding-bottom:200%}.aspect--1x1\@sm{padding-bottom:100%}.aspect--none\@sm{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@sm>.aspect__inner{position:static}.col-1\@sm{width:8.3333333333%}.col-2\@sm{width:16.6666666667%}.col-3\@sm{width:25%}.col-4\@sm{width:33.3333333333%}.col-5\@sm{width:41.6666666667%}.col-6\@sm{width:50%}.col-7\@sm{width:58.3333333333%}.col-8\@sm{width:66.6666666667%}.col-9\@sm{width:75%}.col-10\@sm{width:83.3333333333%}.col-11\@sm{width:91.6666666667%}.col-12\@sm{width:100%}.col-pull-0\@sm{right:auto}.col-pull-1\@sm{right:8.3333333333%}.col-pull-2\@sm{right:16.6666666667%}.col-pull-3\@sm{right:25%}.col-pull-4\@sm{right:33.3333333333%}.col-pull-5\@sm{right:41.6666666667%}.col-pull-6\@sm{right:50%}.col-pull-7\@sm{right:58.3333333333%}.col-pull-8\@sm{right:66.6666666667%}.col-pull-9\@sm{right:75%}.col-pull-10\@sm{right:83.3333333333%}.col-pull-11\@sm{right:91.6666666667%}.col-pull-12\@sm{right:100%}.col-push-0\@sm{left:auto}.col-push-1\@sm{left:8.3333333333%}.col-push-2\@sm{left:16.6666666667%}.col-push-3\@sm{left:25%}.col-push-4\@sm{left:33.3333333333%}.col-push-5\@sm{left:41.6666666667%}.col-push-6\@sm{left:50%}.col-push-7\@sm{left:58.3333333333%}.col-push-8\@sm{left:66.6666666667%}.col-push-9\@sm{left:75%}.col-push-10\@sm{left:83.3333333333%}.col-push-11\@sm{left:91.6666666667%}.col-push-12\@sm{left:100%}.col-offset-0\@sm{margin-left:0}.col-offset-1\@sm{margin-left:8.3333333333%}.col-offset-2\@sm{margin-left:16.6666666667%}.col-offset-3\@sm{margin-left:25%}.col-offset-4\@sm{margin-left:33.3333333333%}.col-offset-5\@sm{margin-left:41.6666666667%}.col-offset-6\@sm{margin-left:50%}.col-offset-7\@sm{margin-left:58.3333333333%}.col-offset-8\@sm{margin-left:66.6666666667%}.col-offset-9\@sm{margin-left:75%}.col-offset-10\@sm{margin-left:83.3333333333%}.col-offset-11\@sm{margin-left:91.6666666667%}.col-offset-12\@sm{margin-left:100%}.container{padding-left:7%;padding-right:7%}.row{max-width:1200px}}@media screen and (min-width:1024px){.col-10\@md,.col-11\@md,.col-12\@md,.col-1\@md,.col-2\@md,.col-3\@md,.col-4\@md,.col-5\@md,.col-6\@md,.col-7\@md,.col-8\@md,.col-9\@md{float:left}.aspect--16x9\@md{padding-bottom:56.25%}.aspect--9x16\@md{padding-bottom:177.7777777778%}.aspect--4x3\@md{padding-bottom:75%}.aspect--3x4\@md{padding-bottom:133.3333333333%}.aspect--3x2\@md{padding-bottom:66.6666666667%}.aspect--3x1\@md{padding-bottom:33.3333333333%}.aspect--2x3\@md{padding-bottom:150%}.aspect--2x1\@md{padding-bottom:50%}.aspect--1x2\@md{padding-bottom:200%}.aspect--1x1\@md{padding-bottom:100%}.aspect--none\@md{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@md>.aspect__inner{position:static}.col-1\@md{width:8.3333333333%}.col-2\@md{width:16.6666666667%}.col-3\@md{width:25%}.col-4\@md{width:33.3333333333%}.col-5\@md{width:41.6666666667%}.col-6\@md{width:50%}.col-7\@md{width:58.3333333333%}.col-8\@md{width:66.6666666667%}.col-9\@md{width:75%}.col-10\@md{width:83.3333333333%}.col-11\@md{width:91.6666666667%}.col-12\@md{width:100%}.col-pull-0\@md{right:auto}.col-pull-1\@md{right:8.3333333333%}.col-pull-2\@md{right:16.6666666667%}.col-pull-3\@md{right:25%}.col-pull-4\@md{right:33.3333333333%}.col-pull-5\@md{right:41.6666666667%}.col-pull-6\@md{right:50%}.col-pull-7\@md{right:58.3333333333%}.col-pull-8\@md{right:66.6666666667%}.col-pull-9\@md{right:75%}.col-pull-10\@md{right:83.3333333333%}.col-pull-11\@md{right:91.6666666667%}.col-pull-12\@md{right:100%}.col-push-0\@md{left:auto}.col-push-1\@md{left:8.3333333333%}.col-push-2\@md{left:16.6666666667%}.col-push-3\@md{left:25%}.col-push-4\@md{left:33.3333333333%}.col-push-5\@md{left:41.6666666667%}.col-push-6\@md{left:50%}.col-push-7\@md{left:58.3333333333%}.col-push-8\@md{left:66.6666666667%}.col-push-9\@md{left:75%}.col-push-10\@md{left:83.3333333333%}.col-push-11\@md{left:91.6666666667%}.col-push-12\@md{left:100%}.col-offset-0\@md{margin-left:0}.col-offset-1\@md{margin-left:8.3333333333%}.col-offset-2\@md{margin-left:16.6666666667%}.col-offset-3\@md{margin-left:25%}.col-offset-4\@md{margin-left:33.3333333333%}.col-offset-5\@md{margin-left:41.6666666667%}.col-offset-6\@md{margin-left:50%}.col-offset-7\@md{margin-left:58.3333333333%}.col-offset-8\@md{margin-left:66.6666666667%}.col-offset-9\@md{margin-left:75%}.col-offset-10\@md{margin-left:83.3333333333%}.col-offset-11\@md{margin-left:91.6666666667%}.col-offset-12\@md{margin-left:100%}}.code-block{margin:.5em calc(-3.5vw - 8px);overflow:visible;position:relative}.code-block pre{margin:0;min-height:56px;padding:1em calc(3.5vw + 8px);position:relative;z-index:1}@media screen and (min-width:768px){.code-block{margin-left:calc(-7vw - 8px);margin-right:calc(-7vw - 8px)}.code-block pre{padding-left:calc(7vw + 8px);padding-right:calc(7vw + 8px);position:relative;z-index:1}}@media (min-width:1395px){.code-block{margin-left:calc(-50vw + 592px);margin-right:calc(-50vw + 592px)}.code-block pre{padding-left:calc(50vw - 592px);padding-right:calc(50vw - 592px)}}.textfield{-webkit-appearance:none;border:2px solid #95a5a6;border-radius:4px;box-sizing:border-box;color:#34495e;font-size:1rem;padding:.5em;transition:.15s;width:100%}.textfield::-moz-placeholder{color:#95a5a6;-moz-transition:.15s;transition:.15s}.textfield:-ms-input-placeholder{color:#95a5a6;-ms-transition:.15s;transition:.15s}.textfield::placeholder{color:#95a5a6;transition:.15s}.textfield:hover{border-color:#5d6d77;color:#5d6d77;outline-width:0}.textfield:hover::-moz-placeholder{color:#5d6d77}.textfield:hover:-ms-input-placeholder{color:#5d6d77}.textfield:hover::placeholder{color:#5d6d77}.textfield:focus{border-color:#34495e;outline-width:0}.textfield:focus::-moz-placeholder{color:#34495e}.textfield:focus:-ms-input-placeholder{color:#34495e}.textfield:focus::placeholder{color:#34495e}.textfield--large{font-size:1.125em}.text-center{text-align:center}.ib{display:inline-block}@media screen and (max-width:767px){.hidden\@xs{display:none}}@media screen and (min-width:768px){.visible\@xs{display:none}}.hidden{display:none!important;visibility:hidden}.visuallyhidden{clip:rect(0 0 0 0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.clearfix,.clearfix:after{clear:both;content:" ";display:table}.pull-left{float:left}.pull-right{float:right}.full-width{width:100%}.full-height{height:100%}.hide-text{background-color:transparent;border:0;color:transparent;font:0/0 a;text-shadow:none}.table-center-wrap{display:table;table-layout:fixed}.table-center{display:table-cell;vertical-align:middle}.btn-group:after,.btn-group:before{content:" ";display:table}.btn-group:after{clear:both}.btn-group .btn{border-radius:0;float:left}.btn-group .btn:first-child{border-radius:3px 0 0 3px}.btn-group .btn:not(:first-child){margin-left:-1px}.btn-group .btn:last-child{border-radius:0 3px 3px 0}.btn-group label.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn{-webkit-appearance:none;background-color:rgba(52,73,94,0);border:1px solid #34495e;border-radius:3px;color:#34495e;cursor:pointer;display:inline-block;font-size:1rem;padding:.75em .8em;text-align:center;transition:.2s ease-out}@media (-moz-touch-enabled:0),(pointer:fine){.btn:hover{background-color:#34495e;color:#fff;text-decoration:none}}.btn:focus{box-shadow:0 0 0 2px rgba(52,73,94,.4);outline-width:0}.btn.active,.btn:active{background-color:#34495e;box-shadow:inset 0 1px 2px rgba(0,0,0,.3);color:#fff}.btn:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,73,94,.4)}.btn:disabled{background-color:rgba(52,73,94,0);color:#34495e;cursor:not-allowed;opacity:.7}.btn--warning{background-color:rgba(230,126,34,0);border-color:#e67e22;color:#e67e22}@media (-moz-touch-enabled:0),(pointer:fine){.btn--warning:hover{background-color:#e67e22}}.btn--warning:focus{box-shadow:0 0 0 2px rgba(230,126,34,.4)}.btn--warning.active,.btn--warning:active{background-color:#e67e22}.btn--warning:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(230,126,34,.4)}.btn--warning:disabled{background-color:rgba(230,126,34,0);color:#e67e22}.btn--primary{background-color:rgba(52,152,219,0);border-color:#3498db;color:#3498db}@media (-moz-touch-enabled:0),(pointer:fine){.btn--primary:hover{background-color:#3498db}}.btn--primary:focus{box-shadow:0 0 0 2px rgba(52,152,219,.4)}.btn--primary.active,.btn--primary:active{background-color:#3498db}.btn--primary:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,152,219,.4)}.btn--primary:disabled{background-color:rgba(52,152,219,0);color:#3498db}.btn--danger{background-color:rgba(231,76,60,0);border-color:#e74c3c;color:#e74c3c}@media (-moz-touch-enabled:0),(pointer:fine){.btn--danger:hover{background-color:#e74c3c}}.btn--danger:focus{box-shadow:0 0 0 2px rgba(231,76,60,.4)}.btn--danger.active,.btn--danger:active{background-color:#e74c3c}.btn--danger:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(231,76,60,.4)}.btn--danger:disabled{background-color:rgba(231,76,60,0);color:#e74c3c}.btn--go{background-color:rgba(46,204,113,0);border-color:#2ecc71;color:#2ecc71}@media (-moz-touch-enabled:0),(pointer:fine){.btn--go:hover{background-color:#2ecc71}}.btn--go:focus{box-shadow:0 0 0 2px rgba(46,204,113,.4)}.btn--go.active,.btn--go:active{background-color:#2ecc71}.btn--go:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(46,204,113,.4)}.btn--go:disabled{background-color:rgba(46,204,113,0);color:#2ecc71}@media screen and (max-width:767px){.btn{font-size:.875rem}}.filter-group .btn{position:relative}.filter-group .btn.active:after,.filter-group .btn.active:before{content:"";height:20px;left:50%;margin-left:-10px;margin-top:-10px;opacity:0;position:absolute;top:50%;transition:.2s;width:20px}.filter-group .btn:before{background-color:#2c3e50;border-radius:50%}.filter-group .btn:after{background-image:url(../img/check.svg);background-position:50%;background-repeat:no-repeat;background-size:60%}.filter-group .btn.active:after,.filter-group .btn.active:before{opacity:1}.demo-list .figure-wrap{position:relative;z-index:1}.demo-list .figure-wrap,.demo-list .figure-wrap img{transform:translateZ(0);transition:.1s ease}.demo-list:hover .figure-wrap{transform:scaleX(1)}.demo-list:hover .figure-wrap img{filter:grayscale(1)}.demo-list:hover .figure-wrap:hover{transform:scale3d(1.05,1.05,1);z-index:2}.demo-list:hover .figure-wrap:hover img{filter:none}.demo-list .figure-wrap:nth-child(4n+1){margin-left:0}.demo-list .figure-wrap>a{display:block}.demo-list .figure-wrap figcaption{height:2em;margin-bottom:1em;margin-top:.5em}.demo-link-container:before{color:#2ecc71;content:"➜";display:inline-block;margin-right:5px}.demo-link-container--external:before{transform:rotate(-45deg)}span.demo-link-container:before{margin-left:5px}@media screen and (max-width:47.9375em){.demo-list+.demo-list{margin-top:1em}.figure-wrap:nth-child(odd){margin-left:0}.figure-wrap:nth-child(n+3){margin-top:1em}}.site-nav{background:#ecf0f1;border-bottom:1px solid #e1e5e6;margin-bottom:28px;padding:10px 0}.site-nav__content{display:flex;justify-content:space-between}.site-nav__logo{font-size:20px}.site-nav__logo,.site-nav__logo:visited{color:#34495e}.site-nav__logo:hover,.site-nav__logo:visited:hover{text-decoration:none}.site-nav__links,.site-nav__logo{align-items:center;display:flex}.site-nav__logo svg{display:block;height:24px;margin-right:4px;width:24px}.site-nav__logo rect{transition:.18s cubic-bezier(.4,0,.2,1)}.site-nav__link{position:relative;z-index:3}.site-nav__link:not(:last-of-type){margin-right:8px}.site-nav__dropdown{background-color:#fff;box-shadow:0 7px 10px -1px rgba(0,0,0,.12);max-height:100vh;opacity:0;position:absolute;right:0;top:40px;transform:translateY(10px);transition:.3s cubic-bezier(.165,.84,.44,1);visibility:hidden;z-index:2}.site-nav__dropdown:before{border-bottom:8px solid #fff;border-left:9px solid transparent;border-right:9px solid transparent;content:"";display:block;position:absolute;right:32px;top:-8px}.site-nav__dropdown li+li{margin-top:8px}.site-nav__dropdown a{color:#5d6d77;display:block}.site-nav__dropdown a:hover{background-color:#ecf0f1;color:#5d6d77;text-decoration:none}.site-nav__dropdown figure{align-items:center;display:flex}.site-nav__dropdown picture{flex-shrink:0;height:75px;width:100px}.site-nav__dropdown figcaption{padding-left:8px;padding-right:8px}.site-nav__dropdown--simple-links a{padding:8px 16px}.site-nav__dropdown--simple-links li+li{margin-top:0}.site-nav__link-toggle{padding:6px 8px}.site-nav__link-toggle:after{border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid;content:"";display:inline-block;margin-left:4px;margin-top:-1px;transition:transform .18s cubic-bezier(.4,0,.2,1);vertical-align:middle}.site-nav__link--dropdown-active .site-nav__link-toggle:after{transform:rotate(-180deg)}.site-nav__link--dropdown-active .site-nav__dropdown{opacity:1;transform:translateY(0);visibility:visible}@media (-moz-touch-enabled:0),(pointer:fine){.site-nav__logo:hover rect:first-of-type{transform:translate(20px,10px);transition-delay:0ms}.site-nav__logo:hover rect:nth-of-type(2){transform:translateY(20px);transition-delay:10ms}.site-nav__logo:hover rect:nth-of-type(3){transform:translate(-20px,6px);transition-delay:20ms}.site-nav__logo:hover rect:nth-of-type(4){transform:translate(10px,-10px);transition-delay:30ms}.site-nav__logo:hover rect:nth-of-type(5){transform:translate(-10px,10px);transition-delay:40ms}.site-nav__logo:hover rect:nth-of-type(6){transform:translate(-20px,-14px);transition-delay:50ms}.site-nav__logo:hover rect:nth-of-type(7){transform:translateY(-20px);transition-delay:60ms}.site-nav__link-toggle:hover{border-color:#34495e}}@media screen and (max-width:767px){body.site-nav--open{padding-top:51px}body.site-nav--open .site-nav{left:0;position:fixed;top:0;width:100%;z-index:4}.site-nav__dropdown{-webkit-overflow-scrolling:touch;left:0;overflow:auto;padding:8px calc(3.5vw + 8px);position:fixed;right:0;top:51px;width:100vw}}@media screen and (min-width:768px){.site-nav{padding:16px 0}.site-nav__logo{font-size:24px}.site-nav__logo svg{height:32px;width:32px}.site-nav__link:not(:last-child){margin-right:16px}.site-nav__link--dropdown:not(:last-child){margin-right:12px}.site-nav__dropdown{box-shadow:0 0 10px rgba(0,0,0,.12);max-height:none!important;padding:16px;right:-100px}.site-nav__dropdown:before{right:132px}.site-nav__dropdown ul{-moz-column-count:2;column-count:2;-moz-column-gap:16px;column-gap:16px}.site-nav__dropdown li{-moz-column-break-inside:avoid;break-inside:avoid;page-break-inside:avoid}.site-nav__dropdown figcaption{white-space:nowrap}@supports (filter:drop-shadow(0 0 5px rgba(0,0,0,0.12))){.site-nav__dropdown{box-shadow:none;filter:drop-shadow(0 0 5px rgba(0,0,0,.12))}}.site-nav__link-img{height:24px;width:24px}.site-nav__dropdown--simple-links{padding:0;right:0}.site-nav__dropdown--simple-links:before{right:24px}.site-nav__dropdown--simple-links a{width:200px}}@media screen and (min-width:1024px){.site-nav__dropdown{right:0}.site-nav__dropdown:before{right:32px}.site-nav__dropdown--simple-links:before{right:24px}}.site-footer{background-color:#34495e;margin-top:2em;padding:1em 0}.site-footer p{color:#ecf0f1}.site-footer a{color:#fff;text-decoration:underline}.site-footer a:hover{color:#3498db}.has-code-block .code-block pre{margin-bottom:0}.has-code-block+.site-footer{margin-top:0}@media screen and (min-width:768px){.site-footer__credit{text-align:right}}.filter-label{color:#95a5a6;display:block;margin-bottom:4px;margin-top:0;padding:0}.filters-group{border:0;margin:0 0 4px;padding:0}@media screen and (min-width:768px){.filters-group-wrap{display:flex;justify-content:space-between}}.compound-filter-options{margin-bottom:40px;margin-top:20px}.filter-group--compound button{background-color:currentColor;height:40px;padding:0;width:40px}.filter-group--compound label{cursor:pointer}.filter-group--compound .ib+.ib{margin-left:8px}.shape-shuffle-container{overflow:hidden;position:relative}.shape{margin-left:0;margin-top:10px;position:relative}.shape .shape__space{background-color:#000;border:0 solid transparent;height:100%;width:100%}.shape--blue .shape__space{background-color:#3498db;border-bottom-color:#3498db}.shape--red .shape__space{background-color:#e74c3c;border-bottom-color:#e74c3c}.shape--orange .shape__space{background-color:#f39c12;border-bottom-color:#f39c12}.shape--green .shape__space{background-color:#2ecc71;border-bottom-color:#2ecc71}.shape--circle .shape__space{border-radius:50%}.shape--diamond .shape__space{transform:rotate(45deg) scale(.707106781)}.shape--triangle .shape__space{background-color:transparent;border-width:0 66px 114px;height:0;margin:auto;padding-top:9px;width:0}@media (min-width:425px){.shape--triangle .shape__space{border-width:0 90px 156px;height:0;padding-top:12px;width:0}}@media (min-width:600px){.shape--triangle .shape__space{border-width:0 131px 227px;height:0;padding-top:17.5px;width:0}}@media (min-width:768px){.shape--triangle .shape__space{border-width:0 74px 128px;height:0;padding-top:10px;width:0}}@media (min-width:1024px){.shape--triangle .shape__space{border-width:0 102px 177px;height:0;padding-top:13.5px;width:0}}@media (min-width:1200px){.shape--triangle .shape__space{border-width:0 135px 234px;height:0;padding-top:18px;width:0}}@media (min-width:1392px){.shape--triangle .shape__space{border-width:0 142px 246px;height:0;padding-top:19px;width:0}}.search-section{margin-bottom:1em;margin-top:1em}.question{float:none;margin:2em 0;overflow:hidden;transition:.2s ease-out}.question--collapsed{border-width:0;height:0!important;margin:0}.question--collapsed+.question{margin-top:0}.question--unanswered{border-top:2px solid #2ecc71;padding-top:1.25em}.question__title{margin-top:0}.question__answer{margin-bottom:0;padding-bottom:1px} \ No newline at end of file +@charset "UTF-8";*,:after,:before{box-sizing:border-box}main{overflow:hidden}pre.max-height{max-height:30em}img,picture{display:block}img{height:auto;max-width:100%}figure,ul ul{margin:0}ul ul{list-style-type:circle;padding-left:1.25em}li{line-height:1.4}li+li{margin-top:4px}nav>a{display:block;margin:5px 0}#demos{margin-top:1em}body{color:#5d6d77;font-family:Open Sans,Helvetica Neue,Helvetica,sans-serif}a{text-decoration:none}a,a:visited{color:#3498db}a:hover{text-decoration:underline}a:active{color:#2ecc71}h1,h2,h3,h4,h5,h6{color:#34495e;font-weight:700}h1{font-size:10vw;font-weight:400;line-height:1}h1,h2{margin:3vw 0}h2{font-size:7vw;position:relative}h3{font-size:6vw;margin:2vw 0}h4{font-size:1.25em}p{line-height:1.4;margin:1em 0}.intro-text{font-size:1.125em;margin:.7em 0}@media screen and (min-width:768px){h1{font-size:3.5em;margin:.5em 0 .25em}h2{font-size:2.5em;margin:.45em 0}h3{font-size:1.5em;margin:.8em 0 .5em}h1>a,h2>a,h3>a{display:none}h1:hover>a,h2:hover>a,h3:hover>a{background:url(../img/link.svg) no-repeat;display:inline-block;height:50px;overflow:hidden;position:absolute;text-indent:-999em;top:0;width:50px}.intro-text{font-size:1.25em}}.unstyled{list-style-type:none;margin:0;padding:0}.type--underline{text-decoration:underline}code:not([class*=language]){background-color:#1b1f230d;border-radius:3px;color:#2c3e50;font-family:Menlo,Consolas,Liberation Mono,Courier,monospace;font-size:85%;margin:0;padding:.2em 0}code:not([class*=language]):after,code:not([class*=language]):before{content:" ";letter-spacing:-.2em}.container{padding-left:3.5%;padding-right:3.5%}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.row{margin-left:auto;margin-right:auto}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.row .row{margin-left:-8px;margin-right:-8px}.row--centered{display:flex;flex-wrap:wrap;justify-content:center}.aspect{height:0;overflow:hidden;padding-bottom:100%;position:relative;width:100%}.aspect--16x9{padding-bottom:56.25%}.aspect--9x16{padding-bottom:177.7777777778%}.aspect--4x3{padding-bottom:75%}.aspect--3x4{padding-bottom:133.3333333333%}.aspect--3x2{padding-bottom:66.6666666667%}.aspect--3x1{padding-bottom:33.3333333333%}.aspect--2x3{padding-bottom:150%}.aspect--2x1{padding-bottom:50%}.aspect--1x2{padding-bottom:200%}.aspect--1x1{padding-bottom:100%}.aspect--none{height:auto;overflow:visible;padding-bottom:0}.aspect--none>.aspect__inner{position:static}.aspect>div,.aspect__inner{bottom:0;left:0;position:absolute;right:0;top:0}.col-10\@lg,.col-10\@md,.col-10\@sm,.col-10\@xs,.col-11\@lg,.col-11\@md,.col-11\@sm,.col-11\@xs,.col-12\@lg,.col-12\@md,.col-12\@sm,.col-12\@xs,.col-1\@lg,.col-1\@md,.col-1\@sm,.col-1\@xs,.col-2\@lg,.col-2\@md,.col-2\@sm,.col-2\@xs,.col-3\@lg,.col-3\@md,.col-3\@sm,.col-3\@xs,.col-4\@lg,.col-4\@md,.col-4\@sm,.col-4\@xs,.col-5\@lg,.col-5\@md,.col-5\@sm,.col-5\@xs,.col-6\@lg,.col-6\@md,.col-6\@sm,.col-6\@xs,.col-7\@lg,.col-7\@md,.col-7\@sm,.col-7\@xs,.col-8\@lg,.col-8\@md,.col-8\@sm,.col-8\@xs,.col-9\@lg,.col-9\@md,.col-9\@sm,.col-9\@xs{box-sizing:border-box;min-height:1px;padding-left:8px;padding-right:8px;position:relative}.col-10\@xs,.col-11\@xs,.col-12\@xs,.col-1\@xs,.col-2\@xs,.col-3\@xs,.col-4\@xs,.col-5\@xs,.col-6\@xs,.col-7\@xs,.col-8\@xs,.col-9\@xs{float:left}.aspect--16x9\@xs{padding-bottom:56.25%}.aspect--9x16\@xs{padding-bottom:177.7777777778%}.aspect--4x3\@xs{padding-bottom:75%}.aspect--3x4\@xs{padding-bottom:133.3333333333%}.aspect--3x2\@xs{padding-bottom:66.6666666667%}.aspect--3x1\@xs{padding-bottom:33.3333333333%}.aspect--2x3\@xs{padding-bottom:150%}.aspect--2x1\@xs{padding-bottom:50%}.aspect--1x2\@xs{padding-bottom:200%}.aspect--1x1\@xs{padding-bottom:100%}.aspect--none\@xs{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@xs>.aspect__inner{position:static}.col-1\@xs{width:16.6666666667%}.col-2\@xs{width:33.3333333333%}.col-3\@xs{width:50%}.col-4\@xs{width:66.6666666667%}.col-5\@xs{width:83.3333333333%}.col-6\@xs{width:100%}.col-pull-0\@xs{right:auto}.col-pull-1\@xs{right:16.6666666667%}.col-pull-2\@xs{right:33.3333333333%}.col-pull-3\@xs{right:50%}.col-pull-4\@xs{right:66.6666666667%}.col-pull-5\@xs{right:83.3333333333%}.col-pull-6\@xs{right:100%}.col-push-0\@xs{left:auto}.col-push-1\@xs{left:16.6666666667%}.col-push-2\@xs{left:33.3333333333%}.col-push-3\@xs{left:50%}.col-push-4\@xs{left:66.6666666667%}.col-push-5\@xs{left:83.3333333333%}.col-push-6\@xs{left:100%}.col-offset-0\@xs{margin-left:0}.col-offset-1\@xs{margin-left:16.6666666667%}.col-offset-2\@xs{margin-left:33.3333333333%}.col-offset-3\@xs{margin-left:50%}.col-offset-4\@xs{margin-left:66.6666666667%}.col-offset-5\@xs{margin-left:83.3333333333%}.col-offset-6\@xs{margin-left:100%}@media screen and (min-width:768px){.col-10\@sm,.col-11\@sm,.col-12\@sm,.col-1\@sm,.col-2\@sm,.col-3\@sm,.col-4\@sm,.col-5\@sm,.col-6\@sm,.col-7\@sm,.col-8\@sm,.col-9\@sm{float:left}.aspect--16x9\@sm{padding-bottom:56.25%}.aspect--9x16\@sm{padding-bottom:177.7777777778%}.aspect--4x3\@sm{padding-bottom:75%}.aspect--3x4\@sm{padding-bottom:133.3333333333%}.aspect--3x2\@sm{padding-bottom:66.6666666667%}.aspect--3x1\@sm{padding-bottom:33.3333333333%}.aspect--2x3\@sm{padding-bottom:150%}.aspect--2x1\@sm{padding-bottom:50%}.aspect--1x2\@sm{padding-bottom:200%}.aspect--1x1\@sm{padding-bottom:100%}.aspect--none\@sm{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@sm>.aspect__inner{position:static}.col-1\@sm{width:8.3333333333%}.col-2\@sm{width:16.6666666667%}.col-3\@sm{width:25%}.col-4\@sm{width:33.3333333333%}.col-5\@sm{width:41.6666666667%}.col-6\@sm{width:50%}.col-7\@sm{width:58.3333333333%}.col-8\@sm{width:66.6666666667%}.col-9\@sm{width:75%}.col-10\@sm{width:83.3333333333%}.col-11\@sm{width:91.6666666667%}.col-12\@sm{width:100%}.col-pull-0\@sm{right:auto}.col-pull-1\@sm{right:8.3333333333%}.col-pull-2\@sm{right:16.6666666667%}.col-pull-3\@sm{right:25%}.col-pull-4\@sm{right:33.3333333333%}.col-pull-5\@sm{right:41.6666666667%}.col-pull-6\@sm{right:50%}.col-pull-7\@sm{right:58.3333333333%}.col-pull-8\@sm{right:66.6666666667%}.col-pull-9\@sm{right:75%}.col-pull-10\@sm{right:83.3333333333%}.col-pull-11\@sm{right:91.6666666667%}.col-pull-12\@sm{right:100%}.col-push-0\@sm{left:auto}.col-push-1\@sm{left:8.3333333333%}.col-push-2\@sm{left:16.6666666667%}.col-push-3\@sm{left:25%}.col-push-4\@sm{left:33.3333333333%}.col-push-5\@sm{left:41.6666666667%}.col-push-6\@sm{left:50%}.col-push-7\@sm{left:58.3333333333%}.col-push-8\@sm{left:66.6666666667%}.col-push-9\@sm{left:75%}.col-push-10\@sm{left:83.3333333333%}.col-push-11\@sm{left:91.6666666667%}.col-push-12\@sm{left:100%}.col-offset-0\@sm{margin-left:0}.col-offset-1\@sm{margin-left:8.3333333333%}.col-offset-2\@sm{margin-left:16.6666666667%}.col-offset-3\@sm{margin-left:25%}.col-offset-4\@sm{margin-left:33.3333333333%}.col-offset-5\@sm{margin-left:41.6666666667%}.col-offset-6\@sm{margin-left:50%}.col-offset-7\@sm{margin-left:58.3333333333%}.col-offset-8\@sm{margin-left:66.6666666667%}.col-offset-9\@sm{margin-left:75%}.col-offset-10\@sm{margin-left:83.3333333333%}.col-offset-11\@sm{margin-left:91.6666666667%}.col-offset-12\@sm{margin-left:100%}.container{padding-left:7%;padding-right:7%}.row{max-width:1200px}}@media screen and (min-width:1024px){.col-10\@md,.col-11\@md,.col-12\@md,.col-1\@md,.col-2\@md,.col-3\@md,.col-4\@md,.col-5\@md,.col-6\@md,.col-7\@md,.col-8\@md,.col-9\@md{float:left}.aspect--16x9\@md{padding-bottom:56.25%}.aspect--9x16\@md{padding-bottom:177.7777777778%}.aspect--4x3\@md{padding-bottom:75%}.aspect--3x4\@md{padding-bottom:133.3333333333%}.aspect--3x2\@md{padding-bottom:66.6666666667%}.aspect--3x1\@md{padding-bottom:33.3333333333%}.aspect--2x3\@md{padding-bottom:150%}.aspect--2x1\@md{padding-bottom:50%}.aspect--1x2\@md{padding-bottom:200%}.aspect--1x1\@md{padding-bottom:100%}.aspect--none\@md{height:auto;overflow:visible;padding-bottom:0}.aspect--none\@md>.aspect__inner{position:static}.col-1\@md{width:8.3333333333%}.col-2\@md{width:16.6666666667%}.col-3\@md{width:25%}.col-4\@md{width:33.3333333333%}.col-5\@md{width:41.6666666667%}.col-6\@md{width:50%}.col-7\@md{width:58.3333333333%}.col-8\@md{width:66.6666666667%}.col-9\@md{width:75%}.col-10\@md{width:83.3333333333%}.col-11\@md{width:91.6666666667%}.col-12\@md{width:100%}.col-pull-0\@md{right:auto}.col-pull-1\@md{right:8.3333333333%}.col-pull-2\@md{right:16.6666666667%}.col-pull-3\@md{right:25%}.col-pull-4\@md{right:33.3333333333%}.col-pull-5\@md{right:41.6666666667%}.col-pull-6\@md{right:50%}.col-pull-7\@md{right:58.3333333333%}.col-pull-8\@md{right:66.6666666667%}.col-pull-9\@md{right:75%}.col-pull-10\@md{right:83.3333333333%}.col-pull-11\@md{right:91.6666666667%}.col-pull-12\@md{right:100%}.col-push-0\@md{left:auto}.col-push-1\@md{left:8.3333333333%}.col-push-2\@md{left:16.6666666667%}.col-push-3\@md{left:25%}.col-push-4\@md{left:33.3333333333%}.col-push-5\@md{left:41.6666666667%}.col-push-6\@md{left:50%}.col-push-7\@md{left:58.3333333333%}.col-push-8\@md{left:66.6666666667%}.col-push-9\@md{left:75%}.col-push-10\@md{left:83.3333333333%}.col-push-11\@md{left:91.6666666667%}.col-push-12\@md{left:100%}.col-offset-0\@md{margin-left:0}.col-offset-1\@md{margin-left:8.3333333333%}.col-offset-2\@md{margin-left:16.6666666667%}.col-offset-3\@md{margin-left:25%}.col-offset-4\@md{margin-left:33.3333333333%}.col-offset-5\@md{margin-left:41.6666666667%}.col-offset-6\@md{margin-left:50%}.col-offset-7\@md{margin-left:58.3333333333%}.col-offset-8\@md{margin-left:66.6666666667%}.col-offset-9\@md{margin-left:75%}.col-offset-10\@md{margin-left:83.3333333333%}.col-offset-11\@md{margin-left:91.6666666667%}.col-offset-12\@md{margin-left:100%}}.code-block{margin:.5em calc(-3.5vw - 8px);overflow:visible;position:relative}.code-block pre{margin:0;min-height:56px;padding:1em calc(3.5vw + 8px);position:relative;z-index:1}@media screen and (min-width:768px){.code-block{margin-left:calc(-7vw - 8px);margin-right:calc(-7vw - 8px)}.code-block pre{padding-left:calc(7vw + 8px);padding-right:calc(7vw + 8px);position:relative;z-index:1}}@media (min-width:1395px){.code-block{margin-left:calc(-50vw + 592px);margin-right:calc(-50vw + 592px)}.code-block pre{padding-left:calc(50vw - 592px);padding-right:calc(50vw - 592px)}}.textfield{-webkit-appearance:none;border:2px solid #95a5a6;border-radius:4px;box-sizing:border-box;color:#34495e;font-size:1rem;padding:.5em;transition:.15s;width:100%}.textfield::placeholder{color:#95a5a6;transition:.15s}.textfield:hover{border-color:#5d6d77;color:#5d6d77;outline-width:0}.textfield:hover::placeholder{color:#5d6d77}.textfield:focus{border-color:#34495e;outline-width:0}.textfield:focus::placeholder{color:#34495e}.textfield--large{font-size:1.125em}.text-center{text-align:center}.ib{display:inline-block}@media screen and (max-width:767px){.hidden\@xs{display:none}}@media screen and (min-width:768px){.visible\@xs{display:none}}.hidden{display:none!important;visibility:hidden}.visuallyhidden{clip:rect(0 0 0 0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.clearfix,.clearfix:after{clear:both;content:" ";display:table}.pull-left{float:left}.pull-right{float:right}.full-width{width:100%}.full-height{height:100%}.hide-text{background-color:initial;border:0;color:#0000;font:0/0 a;text-shadow:none}.table-center-wrap{display:table;table-layout:fixed}.table-center{display:table-cell;vertical-align:middle}.btn-group:after,.btn-group:before{content:" ";display:table}.btn-group:after{clear:both}.btn-group .btn{border-radius:0;float:left}.btn-group .btn:first-child{border-radius:3px 0 0 3px}.btn-group .btn:not(:first-child){margin-left:-1px}.btn-group .btn:last-child{border-radius:0 3px 3px 0}.btn-group label.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn{-webkit-appearance:none;background-color:#34495e00;border:1px solid #34495e;border-radius:3px;color:#34495e;cursor:pointer;display:inline-block;font-size:1rem;padding:.75em .8em;text-align:center;transition:.2s ease-out}@media (-moz-touch-enabled:0),(pointer:fine){.btn:hover{background-color:#34495e;color:#fff;text-decoration:none}}.btn:focus{box-shadow:0 0 0 2px #34495e66;outline-width:0}.btn.active,.btn:active{background-color:#34495e;box-shadow:inset 0 1px 2px #0000004d;color:#fff}.btn:focus.active{box-shadow:inset 0 1px 2px #0000004d,0 0 0 2px #34495e66}.btn:disabled{background-color:#34495e00;color:#34495e;cursor:not-allowed;opacity:.7}.btn--warning{background-color:#e67e2200;border-color:#e67e22;color:#e67e22}@media (-moz-touch-enabled:0),(pointer:fine){.btn--warning:hover{background-color:#e67e22}}.btn--warning:focus{box-shadow:0 0 0 2px #e67e2266}.btn--warning.active,.btn--warning:active{background-color:#e67e22}.btn--warning:focus.active{box-shadow:inset 0 1px 2px #0000004d,0 0 0 2px #e67e2266}.btn--warning:disabled{background-color:#e67e2200;color:#e67e22}.btn--primary{background-color:#3498db00;border-color:#3498db;color:#3498db}@media (-moz-touch-enabled:0),(pointer:fine){.btn--primary:hover{background-color:#3498db}}.btn--primary:focus{box-shadow:0 0 0 2px #3498db66}.btn--primary.active,.btn--primary:active{background-color:#3498db}.btn--primary:focus.active{box-shadow:inset 0 1px 2px #0000004d,0 0 0 2px #3498db66}.btn--primary:disabled{background-color:#3498db00;color:#3498db}.btn--danger{background-color:#e74c3c00;border-color:#e74c3c;color:#e74c3c}@media (-moz-touch-enabled:0),(pointer:fine){.btn--danger:hover{background-color:#e74c3c}}.btn--danger:focus{box-shadow:0 0 0 2px #e74c3c66}.btn--danger.active,.btn--danger:active{background-color:#e74c3c}.btn--danger:focus.active{box-shadow:inset 0 1px 2px #0000004d,0 0 0 2px #e74c3c66}.btn--danger:disabled{background-color:#e74c3c00;color:#e74c3c}.btn--go{background-color:#2ecc7100;border-color:#2ecc71;color:#2ecc71}@media (-moz-touch-enabled:0),(pointer:fine){.btn--go:hover{background-color:#2ecc71}}.btn--go:focus{box-shadow:0 0 0 2px #2ecc7166}.btn--go.active,.btn--go:active{background-color:#2ecc71}.btn--go:focus.active{box-shadow:inset 0 1px 2px #0000004d,0 0 0 2px #2ecc7166}.btn--go:disabled{background-color:#2ecc7100;color:#2ecc71}@media screen and (max-width:767px){.btn{font-size:.875rem}}.filter-group .btn{position:relative}.filter-group .btn.active:after,.filter-group .btn.active:before{content:"";height:20px;left:50%;margin-left:-10px;margin-top:-10px;opacity:0;position:absolute;top:50%;transition:.2s;width:20px}.filter-group .btn:before{background-color:#2c3e50;border-radius:50%}.filter-group .btn:after{background-image:url(../img/check.svg);background-position:50%;background-repeat:no-repeat;background-size:60%}.filter-group .btn.active:after,.filter-group .btn.active:before{opacity:1}.demo-list .figure-wrap{position:relative;z-index:1}.demo-list .figure-wrap,.demo-list .figure-wrap img{transform:translateZ(0);transition:.1s ease}.demo-list:hover .figure-wrap{transform:scaleX(1)}.demo-list:hover .figure-wrap img{filter:grayscale(1)}.demo-list:hover .figure-wrap:hover{transform:scale3d(1.05,1.05,1);z-index:2}.demo-list:hover .figure-wrap:hover img{filter:none}.demo-list .figure-wrap:nth-child(4n+1){margin-left:0}.demo-list .figure-wrap>a{display:block}.demo-list .figure-wrap figcaption{height:2em;margin-bottom:1em;margin-top:.5em}.demo-link-container:before{color:#2ecc71;content:"➜";display:inline-block;margin-right:5px}.demo-link-container--external:before{transform:rotate(-45deg)}span.demo-link-container:before{margin-left:5px}@media screen and (max-width:47.9375em){.demo-list+.demo-list{margin-top:1em}.figure-wrap:nth-child(odd){margin-left:0}.figure-wrap:nth-child(n+3){margin-top:1em}}.site-nav{background:#ecf0f1;border-bottom:1px solid #e1e5e6;margin-bottom:28px;padding:10px 0;position:sticky;top:0;z-index:40}.site-nav__content{display:flex;justify-content:space-between}.site-nav__logo{font-size:20px}.site-nav__logo,.site-nav__logo:visited{color:#34495e}.site-nav__logo:hover,.site-nav__logo:visited:hover{text-decoration:none}.site-nav__links,.site-nav__logo{align-items:center;display:flex}.site-nav__logo svg{display:block;height:24px;margin-right:4px;width:24px}.site-nav__logo rect{transition:.18s cubic-bezier(.4,0,.2,1)}.site-nav__link{position:relative;z-index:3}.site-nav__link:not(:last-of-type){margin-right:8px}.site-nav__dropdown{background-color:#fff;box-shadow:0 7px 10px -1px #0000001f;max-height:100vh;opacity:0;position:absolute;right:0;top:40px;transform:translateY(10px);transition:.3s cubic-bezier(.165,.84,.44,1);visibility:hidden;z-index:50}.site-nav__dropdown:before{border-bottom:8px solid #fff;border-left:9px solid #0000;border-right:9px solid #0000;content:"";display:block;position:absolute;right:32px;top:-8px}.site-nav__dropdown li+li{margin-top:8px}.site-nav__dropdown a{color:#5d6d77;display:block}.site-nav__dropdown a:hover{background-color:#ecf0f1;color:#5d6d77;text-decoration:none}.site-nav__dropdown figure{align-items:center;display:flex}.site-nav__dropdown picture{flex-shrink:0;height:75px;width:100px}.site-nav__dropdown figcaption{padding-left:8px;padding-right:8px}.site-nav__dropdown--simple-links a{padding:8px 16px}.site-nav__dropdown--simple-links li+li{margin-top:0}.site-nav__link-toggle{padding:6px 8px}.site-nav__link-toggle:after{border-left:5px solid #0000;border-right:5px solid #0000;border-top:6px solid;content:"";display:inline-block;margin-left:4px;margin-top:-1px;transition:transform .18s cubic-bezier(.4,0,.2,1);vertical-align:middle}.site-nav__link--dropdown-active .site-nav__link-toggle:after{transform:rotate(-180deg)}.site-nav__link--dropdown-active .site-nav__dropdown{opacity:1;transform:translateY(0);visibility:visible}@media (-moz-touch-enabled:0),(pointer:fine){.site-nav__logo:hover rect:first-of-type{transform:translate(20px,10px);transition-delay:0ms}.site-nav__logo:hover rect:nth-of-type(2){transform:translateY(20px);transition-delay:10ms}.site-nav__logo:hover rect:nth-of-type(3){transform:translate(-20px,6px);transition-delay:20ms}.site-nav__logo:hover rect:nth-of-type(4){transform:translate(10px,-10px);transition-delay:30ms}.site-nav__logo:hover rect:nth-of-type(5){transform:translate(-10px,10px);transition-delay:40ms}.site-nav__logo:hover rect:nth-of-type(6){transform:translate(-20px,-14px);transition-delay:50ms}.site-nav__logo:hover rect:nth-of-type(7){transform:translateY(-20px);transition-delay:60ms}.site-nav__link-toggle:hover{border-color:#34495e}}@media screen and (max-width:767px){body.site-nav--open{padding-top:51px}body.site-nav--open .site-nav{left:0;position:fixed;top:0;width:100%;z-index:4}.site-nav__dropdown{-webkit-overflow-scrolling:touch;left:0;overflow:auto;padding:8px calc(3.5vw + 8px);position:fixed;right:0;top:51px;width:100vw}}@media screen and (min-width:768px){.site-nav{padding:16px 0}.site-nav__logo{font-size:24px}.site-nav__logo svg{height:32px;width:32px}.site-nav__link:not(:last-child){margin-right:16px}.site-nav__link--dropdown:not(:last-child){margin-right:12px}.site-nav__dropdown{box-shadow:0 0 10px #0000001f;max-height:none!important;padding:16px;right:-100px}.site-nav__dropdown:before{right:132px}.site-nav__dropdown ul{column-count:2;column-gap:16px}.site-nav__dropdown li{break-inside:avoid;page-break-inside:avoid}.site-nav__dropdown figcaption{white-space:nowrap}@supports (filter:drop-shadow(0 0 5px rgba(0,0,0,0.12))){.site-nav__dropdown{box-shadow:none;filter:drop-shadow(0 0 5px rgba(0,0,0,.12))}}.site-nav__link-img{height:24px;width:24px}.site-nav__dropdown--simple-links{padding:0;right:0}.site-nav__dropdown--simple-links:before{right:24px}.site-nav__dropdown--simple-links a{width:200px}}@media screen and (min-width:1024px){.site-nav__dropdown{right:0}.site-nav__dropdown:before{right:32px}.site-nav__dropdown--simple-links:before{right:24px}}.site-footer{background-color:#34495e;margin-top:2em;padding:1em 0}.site-footer p{color:#ecf0f1}.site-footer a{color:#fff;text-decoration:underline}.site-footer a:hover{color:#3498db}.has-code-block .code-block pre{margin-bottom:0}.has-code-block+.site-footer{margin-top:0}@media screen and (min-width:768px){.site-footer__credit{text-align:right}}.filter-label{color:#95a5a6;display:block;margin-bottom:4px;margin-top:0;padding:0}.filters-group{border:0;margin:0 0 4px;padding:0}@media screen and (min-width:768px){.filters-group-wrap{display:flex;justify-content:space-between}}.compound-filter-options{margin-bottom:40px;margin-top:20px}.filter-group--compound button{background-color:currentColor;height:40px;padding:0;width:40px}.filter-group--compound label{cursor:pointer}.filter-group--compound .ib+.ib{margin-left:8px}.shape-shuffle-container{overflow:hidden;position:relative}.shape{margin-left:0;margin-top:10px;position:relative}.shape .shape__space{background-color:#000;border:0 solid #0000;height:100%;width:100%}.shape--blue .shape__space{background-color:#3498db;border-bottom-color:#3498db}.shape--red .shape__space{background-color:#e74c3c;border-bottom-color:#e74c3c}.shape--orange .shape__space{background-color:#f39c12;border-bottom-color:#f39c12}.shape--green .shape__space{background-color:#2ecc71;border-bottom-color:#2ecc71}.shape--circle .shape__space{border-radius:50%}.shape--diamond .shape__space{transform:rotate(45deg) scale(.707106781)}.shape--triangle .shape__space{background-color:initial;border-width:0 66px 114px;height:0;margin:auto;padding-top:9px;width:0}@media (min-width:425px){.shape--triangle .shape__space{border-width:0 90px 156px;height:0;padding-top:12px;width:0}}@media (min-width:600px){.shape--triangle .shape__space{border-width:0 131px 227px;height:0;padding-top:17.5px;width:0}}@media (min-width:768px){.shape--triangle .shape__space{border-width:0 74px 128px;height:0;padding-top:10px;width:0}}@media (min-width:1024px){.shape--triangle .shape__space{border-width:0 102px 177px;height:0;padding-top:13.5px;width:0}}@media (min-width:1200px){.shape--triangle .shape__space{border-width:0 135px 234px;height:0;padding-top:18px;width:0}}@media (min-width:1392px){.shape--triangle .shape__space{border-width:0 142px 246px;height:0;padding-top:19px;width:0}}.search-section{margin-bottom:1em;margin-top:1em}.question{float:none;margin:2em 0;overflow:hidden;transition:.2s ease-out}.question--collapsed{border-width:0;height:0!important;margin:0}.question--collapsed+.question{margin-top:0}.question--unanswered{border-top:2px solid #2ecc71;padding-top:1.25em}.question__title{margin-top:0}.question__answer{margin-bottom:0;padding-bottom:1px} \ No newline at end of file diff --git a/docs/dist/shuffle.js b/docs/dist/shuffle.js index 6ed9169..9ed9e62 100644 --- a/docs/dist/shuffle.js +++ b/docs/dist/shuffle.js @@ -4,115 +4,6 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Shuffle = factory()); })(this, (function () { 'use strict'; - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - Object.defineProperty(Constructor, "prototype", { - writable: false - }); - return Constructor; - } - - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - Object.defineProperty(subClass, "prototype", { - writable: false - }); - if (superClass) _setPrototypeOf(subClass, superClass); - } - - function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); - } - - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); - } - - function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); - return true; - } catch (e) { - return false; - } - } - - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; - } - - function _possibleConstructorReturn(self, call) { - if (call && (typeof call === "object" || typeof call === "function")) { - return call; - } else if (call !== void 0) { - throw new TypeError("Derived constructors may only return object or undefined"); - } - - return _assertThisInitialized(self); - } - - function _createSuper(Derived) { - var hasNativeReflectConstruct = _isNativeReflectConstruct(); - - return function _createSuperInternal() { - var Super = _getPrototypeOf(Derived), - result; - - if (hasNativeReflectConstruct) { - var NewTarget = _getPrototypeOf(this).constructor; - - result = Reflect.construct(Super, arguments, NewTarget); - } else { - result = Super.apply(this, arguments); - } - - return _possibleConstructorReturn(this, result); - }; - } - var tinyEmitter = {exports: {}}; function E () { @@ -184,35 +75,6 @@ var TinyEmitter = tinyEmitter.exports; - var proto = typeof Element !== 'undefined' ? Element.prototype : {}; - var vendor = proto.matches - || proto.matchesSelector - || proto.webkitMatchesSelector - || proto.mozMatchesSelector - || proto.msMatchesSelector - || proto.oMatchesSelector; - - var matchesSelector = match; - - /** - * Match `el` to `selector`. - * - * @param {Element} el - * @param {String} selector - * @return {Boolean} - * @api public - */ - - function match(el, selector) { - if (!el || el.nodeType !== 1) return false; - if (vendor) return vendor.call(el, selector); - var nodes = el.parentNode.querySelectorAll(selector); - for (var i = 0; i < nodes.length; i++) { - if (nodes[i] == el) return true; - } - return false; - } - var throttleit = throttle; /** @@ -296,15 +158,13 @@ return parseFloat(value) || 0; } - var Point = /*#__PURE__*/function () { + class Point { /** * Represents a coordinate pair. * @param {number} [x=0] X. * @param {number} [y=0] Y. */ - function Point(x, y) { - _classCallCheck(this, Point); - + constructor(x, y) { this.x = getNumber(x); this.y = getNumber(y); } @@ -316,17 +176,13 @@ */ - _createClass(Point, null, [{ - key: "equals", - value: function equals(a, b) { - return a.x === b.x && a.y === b.y; - } - }]); + static equals(a, b) { + return a.x === b.x && a.y === b.y; + } - return Point; - }(); + } - var Rect = /*#__PURE__*/function () { + class Rect { /** * Class for representing rectangular regions. * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js @@ -337,9 +193,7 @@ * @param {number} id Identifier * @constructor */ - function Rect(x, y, w, h, id) { - _classCallCheck(this, Rect); - + constructor(x, y, w, h, id) { this.id = id; /** @type {number} */ @@ -362,15 +216,11 @@ */ - _createClass(Rect, null, [{ - key: "intersects", - value: function intersects(a, b) { - return a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height; - } - }]); + static intersects(a, b) { + return a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height; + } - return Rect; - }(); + } var Classes = { BASE: 'shuffle', @@ -379,12 +229,10 @@ HIDDEN: 'shuffle-item--hidden' }; - var id$1 = 0; - - var ShuffleItem = /*#__PURE__*/function () { - function ShuffleItem(element, isRTL) { - _classCallCheck(this, ShuffleItem); + let id$1 = 0; + class ShuffleItem { + constructor(element, isRTL) { id$1 += 1; this.id = id$1; this.element = element; @@ -408,69 +256,53 @@ this.isHidden = false; } - _createClass(ShuffleItem, [{ - key: "show", - value: function show() { - this.isVisible = true; - this.element.classList.remove(Classes.HIDDEN); - this.element.classList.add(Classes.VISIBLE); - this.element.removeAttribute('aria-hidden'); - } - }, { - key: "hide", - value: function hide() { - this.isVisible = false; - this.element.classList.remove(Classes.VISIBLE); - this.element.classList.add(Classes.HIDDEN); - this.element.setAttribute('aria-hidden', true); - } - }, { - key: "init", - value: function init() { - this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]); - this.applyCss(ShuffleItem.Css.INITIAL); - this.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr); - this.scale = ShuffleItem.Scale.VISIBLE; - this.point = new Point(); - } - }, { - key: "addClasses", - value: function addClasses(classes) { - var _this = this; + show() { + this.isVisible = true; + this.element.classList.remove(Classes.HIDDEN); + this.element.classList.add(Classes.VISIBLE); + this.element.removeAttribute('aria-hidden'); + } - classes.forEach(function (className) { - _this.element.classList.add(className); - }); - } - }, { - key: "removeClasses", - value: function removeClasses(classes) { - var _this2 = this; + hide() { + this.isVisible = false; + this.element.classList.remove(Classes.VISIBLE); + this.element.classList.add(Classes.HIDDEN); + this.element.setAttribute('aria-hidden', true); + } - classes.forEach(function (className) { - _this2.element.classList.remove(className); - }); - } - }, { - key: "applyCss", - value: function applyCss(obj) { - var _this3 = this; + init() { + this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]); + this.applyCss(ShuffleItem.Css.INITIAL); + this.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr); + this.scale = ShuffleItem.Scale.VISIBLE; + this.point = new Point(); + } - Object.keys(obj).forEach(function (key) { - _this3.element.style[key] = obj[key]; - }); - } - }, { - key: "dispose", - value: function dispose() { - this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); - this.element.removeAttribute('style'); - this.element = null; - } - }]); + addClasses(classes) { + classes.forEach(className => { + this.element.classList.add(className); + }); + } - return ShuffleItem; - }(); + removeClasses(classes) { + classes.forEach(className => { + this.element.classList.remove(className); + }); + } + + applyCss(obj) { + Object.keys(obj).forEach(key => { + this.element.style[key] = obj[key]; + }); + } + + dispose() { + this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); + this.element.removeAttribute('style'); + this.element = null; + } + + } ShuffleItem.Css = { INITIAL: { @@ -511,20 +343,19 @@ HIDDEN: 0.001 }; - var value = null; - var testComputedSize = (function () { + let value = null; + var testComputedSize = (() => { if (value !== null) { return value; } - var element = document.body || document.documentElement; - var e = document.createElement('div'); + const element = document.body || document.documentElement; + const e = document.createElement('div'); e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;'; element.appendChild(e); - - var _window$getComputedSt = window.getComputedStyle(e, null), - width = _window$getComputedSt.width; // Fix for issue #314 - + const { + width + } = window.getComputedStyle(e, null); // Fix for issue #314 value = Math.round(getNumber(width)) === 10; element.removeChild(e); @@ -543,8 +374,8 @@ */ function getNumberStyle(element, style) { - var styles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window.getComputedStyle(element, null); - var value = getNumber(styles[style]); // Support IE<=11 and W3C spec. + let styles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window.getComputedStyle(element, null); + let value = getNumber(styles[style]); // Support IE<=11 and W3C spec. if (!testComputedSize() && style === 'width') { value += getNumber(styles.paddingLeft) + getNumber(styles.paddingRight) + getNumber(styles.borderLeftWidth) + getNumber(styles.borderRightWidth); @@ -563,12 +394,12 @@ * @return {Array} Randomly sorted array. */ function randomize(array) { - var n = array.length; + let n = array.length; while (n) { n -= 1; - var i = Math.floor(Math.random() * (n + 1)); - var temp = array[i]; + const i = Math.floor(Math.random() * (n + 1)); + const temp = array[i]; array[i] = array[n]; array[n] = temp; } @@ -576,7 +407,7 @@ return array; } - var defaults = { + const defaults = { // Use array.reverse() to reverse the results reverse: false, // Sorting function @@ -597,10 +428,11 @@ */ function sorter(arr, options) { - // eslint-disable-next-line prefer-object-spread - var opts = Object.assign({}, defaults, options); - var original = Array.from(arr); - var revert = false; + const opts = { ...defaults, + ...options + }; + const original = Array.from(arr); + let revert = false; if (!arr.length) { return []; @@ -613,14 +445,14 @@ if (typeof opts.by === 'function') { - arr.sort(function (a, b) { + arr.sort((a, b) => { // Exit early if we already know we want to revert if (revert) { return 0; } - var valA = opts.by(a[opts.key]); - var valB = opts.by(b[opts.key]); // If both values are undefined, use the DOM order + const valA = opts.by(a[opts.key]); + const valB = opts.by(b[opts.key]); // If both values are undefined, use the DOM order if (valA === undefined && valB === undefined) { revert = true; @@ -653,9 +485,9 @@ return arr; } - var transitions = {}; - var eventName = 'transitionend'; - var count = 0; + const transitions = {}; + const eventName = 'transitionend'; + let count = 0; function uniqueId() { count += 1; @@ -672,9 +504,9 @@ return false; } function onTransitionEnd(element, callback) { - var id = uniqueId(); + const id = uniqueId(); - var listener = function listener(evt) { + const listener = evt => { if (evt.currentTarget === evt.target) { cancelTransitionEnd(id); callback(evt); @@ -683,18 +515,18 @@ element.addEventListener(eventName, listener); transitions[id] = { - element: element, - listener: listener + element, + listener }; return id; } function arrayMax(array) { - return Math.max.apply(Math, array); // eslint-disable-line prefer-spread + return Math.max(...array); } function arrayMin(array) { - return Math.min.apply(Math, array); // eslint-disable-line prefer-spread + return Math.min(...array); } /** @@ -707,7 +539,7 @@ */ function getColumnSpan(itemWidth, columnWidth, columns, threshold) { - var columnSpan = itemWidth / columnWidth; // If the difference between the rounded column span number and the + let columnSpan = itemWidth / columnWidth; // If the difference between the rounded column span number and the // calculated column span number is really small, round the number to // make it fit. @@ -754,9 +586,9 @@ // [10, 20, 10, 0] => [20, 20, 10] => 10 - var available = []; // For how many possible positions for this item there are. + const available = []; // For how many possible positions for this item there are. - for (var i = 0; i <= columns - columnSpan; i++) { + for (let i = 0; i <= columns - columnSpan; i++) { // Find the bigger value for each place it could fit. available.push(arrayMax(positions.slice(i, i + columnSpan))); } @@ -773,9 +605,9 @@ */ function getShortColumn(positions, buffer) { - var minPosition = arrayMin(positions); + const minPosition = arrayMin(positions); - for (var i = 0, len = positions.length; i < len; i++) { + for (let i = 0, len = positions.length; i < len; i++) { if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) { return i; } @@ -795,23 +627,25 @@ */ function getItemPosition(_ref) { - var itemSize = _ref.itemSize, - positions = _ref.positions, - gridSize = _ref.gridSize, - total = _ref.total, - threshold = _ref.threshold, - buffer = _ref.buffer; - var span = getColumnSpan(itemSize.width, gridSize, total, threshold); - var setY = getAvailablePositions(positions, span, total); - var shortColumnIndex = getShortColumn(setY, buffer); // Position the item - - var point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); // Update the columns array with the new values for each column. + let { + itemSize, + positions, + gridSize, + total, + threshold, + buffer + } = _ref; + const span = getColumnSpan(itemSize.width, gridSize, total, threshold); + const setY = getAvailablePositions(positions, span, total); + const shortColumnIndex = getShortColumn(setY, buffer); // Position the item + + const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); // Update the columns array with the new values for each column. // e.g. before the update the columns could be [250, 0, 0, 0] for an item // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0]. - var setHeight = setY[shortColumnIndex] + itemSize.height; + const setHeight = setY[shortColumnIndex] + itemSize.height; - for (var i = 0; i < span; i++) { + for (let i = 0; i < span; i++) { positions[shortColumnIndex + i] = setHeight; } @@ -827,11 +661,11 @@ */ function getCenteredPositions(itemRects, containerWidth) { - var rowMap = {}; // Populate rows by their offset because items could jump between rows like: + const rowMap = {}; // Populate rows by their offset because items could jump between rows like: // a c // bbb - itemRects.forEach(function (itemRect) { + itemRects.forEach(itemRect => { if (rowMap[itemRect.top]) { // Push the point to the last row array. rowMap[itemRect.top].push(itemRect); @@ -843,26 +677,24 @@ // the remaining space by dividing it by 2. Then add that // offset to the x position of each point. - var rects = []; - var rows = []; - var centeredRows = []; - Object.keys(rowMap).forEach(function (key) { - var itemRects = rowMap[key]; + let rects = []; + const rows = []; + const centeredRows = []; + Object.keys(rowMap).forEach(key => { + const itemRects = rowMap[key]; rows.push(itemRects); - var lastItem = itemRects[itemRects.length - 1]; - var end = lastItem.left + lastItem.width; - var offset = Math.round((containerWidth - end) / 2); - var finalRects = itemRects; - var canMove = false; + const lastItem = itemRects[itemRects.length - 1]; + const end = lastItem.left + lastItem.width; + const offset = Math.round((containerWidth - end) / 2); + let finalRects = itemRects; + let canMove = false; if (offset > 0) { - var newRects = []; - canMove = itemRects.every(function (r) { - var newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); // Check all current rects to make sure none overlap. + const newRects = []; + canMove = itemRects.every(r => { + const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); // Check all current rects to make sure none overlap. - var noOverlap = !rects.some(function (r) { - return Rect.intersects(newRect, r); - }); + const noOverlap = !rects.some(r => Rect.intersects(newRect, r)); newRects.push(newRect); return noOverlap; }); // If none of the rectangles overlapped, the whole group can be centered. @@ -876,23 +708,19 @@ if (!canMove) { - var intersectingRect; - var hasOverlap = itemRects.some(function (itemRect) { - return rects.some(function (r) { - var intersects = Rect.intersects(itemRect, r); + let intersectingRect; + const hasOverlap = itemRects.some(itemRect => rects.some(r => { + const intersects = Rect.intersects(itemRect, r); - if (intersects) { - intersectingRect = r; - } + if (intersects) { + intersectingRect = r; + } - return intersects; - }); - }); // If there is any overlap, replace the overlapping row with the original. + return intersects; + })); // If there is any overlap, replace the overlapping row with the original. if (hasOverlap) { - var rowIndex = centeredRows.findIndex(function (items) { - return items.includes(intersectingRect); - }); + const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect)); centeredRows.splice(rowIndex, 1, rows[rowIndex]); } } @@ -904,12 +732,7 @@ // Then reset sort back to how the items were passed to this method. // Remove the wrapper object with index, map to a Point. - return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread - .sort(function (a, b) { - return a.id - b.id; - }).map(function (itemRect) { - return new Point(itemRect.left, itemRect.top); - }); + return centeredRows.flat().sort((a, b) => a.id - b.id).map(itemRect => new Point(itemRect.left, itemRect.top)); } /** @@ -919,9 +742,7 @@ * @return {string} The hyphenated string. */ function hyphenate(str) { - return str.replace(/([A-Z])/g, function (str, m1) { - return "-".concat(m1.toLowerCase()); - }); + return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`); } function arrayUnique(x) { @@ -929,13 +750,9 @@ } // Used for unique instance variables - var id = 0; - - var Shuffle = /*#__PURE__*/function (_TinyEmitter) { - _inherits(Shuffle, _TinyEmitter); - - var _super = _createSuper(Shuffle); + let id = 0; + class Shuffle extends TinyEmitter { /** * Categorize, sort, and filter a responsive grid of items. * @@ -943,1234 +760,1123 @@ * @param {Object} [options=Shuffle.options] Options object. * @constructor */ - function Shuffle(element) { - var _this; - - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck(this, Shuffle); - - _this = _super.call(this); // eslint-disable-next-line prefer-object-spread - - _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; - _this.isEnabled = true; - _this.isDestroyed = false; - _this.isInitialized = false; - _this._transitions = []; - _this.isTransitioning = false; - _this._queue = []; - - var el = _this._getElementOption(element); + constructor(element) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + this.options = { ...Shuffle.options, + ...options + }; + this.lastSort = {}; + this.group = Shuffle.ALL_ITEMS; + this.lastFilter = Shuffle.ALL_ITEMS; + this.isEnabled = true; + this.isDestroyed = false; + this.isInitialized = false; + this._transitions = []; + this.isTransitioning = false; + this._queue = []; + + const el = this._getElementOption(element); if (!el) { throw new TypeError('Shuffle needs to be initialized with an element.'); } - _this.element = el; - _this.id = 'shuffle_' + id; + this.element = el; + this.id = 'shuffle_' + id; id += 1; - _this._init(); + this._init(); - _this.isInitialized = true; - return _this; + this.isInitialized = true; } - _createClass(Shuffle, [{ - key: "_init", - value: function _init() { - this.items = this._getItems(); - this.sortedItems = this.items; - this.options.sizer = this._getElementOption(this.options.sizer); // Add class and invalidate styles + _init() { + this.items = this._getItems(); + this.sortedItems = this.items; + this.options.sizer = this._getElementOption(this.options.sizer); // Add class and invalidate styles - this.element.classList.add(Shuffle.Classes.BASE); // Set initial css for each item + this.element.classList.add(Shuffle.Classes.BASE); // Set initial css for each item - this._initItems(this.items); // Bind resize events + this._initItems(this.items); // Bind resize events - this._onResize = this._getResizeFunction(); - window.addEventListener('resize', this._onResize); // If the page has not already emitted the `load` event, call layout on load. - // This avoids layout issues caused by images and fonts loading after the - // instance has been initialized. + this._onResize = this._getResizeFunction(); + window.addEventListener('resize', this._onResize); // If the page has not already emitted the `load` event, call layout on load. + // This avoids layout issues caused by images and fonts loading after the + // instance has been initialized. - if (document.readyState !== 'complete') { - var layout = this.layout.bind(this); - window.addEventListener('load', function onLoad() { - window.removeEventListener('load', onLoad); - layout(); - }); - } // Get container css all in one request. Causes reflow + if (document.readyState !== 'complete') { + const layout = this.layout.bind(this); + window.addEventListener('load', function onLoad() { + window.removeEventListener('load', onLoad); + layout(); + }); + } // Get container css all in one request. Causes reflow - var containerCss = window.getComputedStyle(this.element, null); - var containerWidth = Shuffle.getSize(this.element).width; // Add styles to the container if it doesn't have them. + const containerCss = window.getComputedStyle(this.element, null); + const containerWidth = Shuffle.getSize(this.element).width; // Add styles to the container if it doesn't have them. - this._validateStyles(containerCss); // We already got the container's width above, no need to cause another - // reflow getting it again... Calculate the number of columns there will be + this._validateStyles(containerCss); // We already got the container's width above, no need to cause another + // reflow getting it again... Calculate the number of columns there will be - this._setColumns(containerWidth); // Kick off! + this._setColumns(containerWidth); // Kick off! - this.filter(this.options.group, this.options.initialSort); // The shuffle items haven't had transitions set on them yet so the user - // doesn't see the first layout. Set them now that the first layout is done. - // First, however, a synchronous layout must be caused for the previous - // styles to be applied without transitions. + this.filter(this.options.group, this.options.initialSort); // The shuffle items haven't had transitions set on them yet so the user + // doesn't see the first layout. Set them now that the first layout is done. + // First, however, a synchronous layout must be caused for the previous + // styles to be applied without transitions. - this.element.offsetWidth; // eslint-disable-line no-unused-expressions + this.element.offsetWidth; // eslint-disable-line no-unused-expressions - this.setItemTransitions(this.items); - this.element.style.transition = "height ".concat(this.options.speed, "ms ").concat(this.options.easing); - } - /** - * Returns a throttled and proxied function for the resize handler. - * @return {function} - * @private - */ + this.setItemTransitions(this.items); + this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`; + } + /** + * Returns a throttled and proxied function for the resize handler. + * @return {function} + * @private + */ - }, { - key: "_getResizeFunction", - value: function _getResizeFunction() { - var resizeFunction = this._handleResize.bind(this); - return this.options.throttle ? this.options.throttle(resizeFunction, this.options.throttleTime) : resizeFunction; - } - /** - * Retrieve an element from an option. - * @param {string|jQuery|Element} option The option to check. - * @return {?Element} The plain element or null. - * @private - */ + _getResizeFunction() { + const resizeFunction = this._handleResize.bind(this); - }, { - key: "_getElementOption", - value: function _getElementOption(option) { - // If column width is a string, treat is as a selector and search for the - // sizer element within the outermost container - if (typeof option === 'string') { - return this.element.querySelector(option); - } // Check for an element + return this.options.throttle ? this.options.throttle(resizeFunction, this.options.throttleTime) : resizeFunction; + } + /** + * Retrieve an element from an option. + * @param {string|jQuery|Element} option The option to check. + * @return {?Element} The plain element or null. + * @private + */ - if (option && option.nodeType && option.nodeType === 1) { - return option; - } // Check for jQuery object + _getElementOption(option) { + // If column width is a string, treat is as a selector and search for the + // sizer element within the outermost container + if (typeof option === 'string') { + return this.element.querySelector(option); + } // Check for an element - if (option && option.jquery) { - return option[0]; - } + if (option && option.nodeType && option.nodeType === 1) { + return option; + } // Check for jQuery object - return null; + + if (option && option.jquery) { + return option[0]; } - /** - * Ensures the shuffle container has the css styles it needs applied to it. - * @param {Object} styles Key value pairs for position and overflow. - * @private - */ - }, { - key: "_validateStyles", - value: function _validateStyles(styles) { - // Position cannot be static. - if (styles.position === 'static') { - this.element.style.position = 'relative'; - } // Overflow has to be hidden. + return null; + } + /** + * Ensures the shuffle container has the css styles it needs applied to it. + * @param {Object} styles Key value pairs for position and overflow. + * @private + */ + + _validateStyles(styles) { + // Position cannot be static. + if (styles.position === 'static') { + this.element.style.position = 'relative'; + } // Overflow has to be hidden. - if (styles.overflow !== 'hidden') { - this.element.style.overflow = 'hidden'; - } + + if (styles.overflow !== 'hidden') { + this.element.style.overflow = 'hidden'; } - /** - * Filter the elements by a category. - * @param {string|string[]|function(Element):boolean} [category] Category to - * filter by. If it's given, the last category will be used to filter the items. - * @param {Array} [collection] Optionally filter a collection. Defaults to - * all the items. - * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} - * @private - */ + } + /** + * Filter the elements by a category. + * @param {string|string[]|function(Element):boolean} [category] Category to + * filter by. If it's given, the last category will be used to filter the items. + * @param {Array} [collection] Optionally filter a collection. Defaults to + * all the items. + * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} + * @private + */ - }, { - key: "_filter", - value: function _filter() { - var category = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastFilter; - var collection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.items; - var set = this._getFilteredSets(category, collection); // Individually add/remove hidden/visible classes + _filter() { + let category = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastFilter; + let collection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.items; + const set = this._getFilteredSets(category, collection); // Individually add/remove hidden/visible classes - this._toggleFilterClasses(set); // Save the last filter in case elements are appended. + this._toggleFilterClasses(set); // Save the last filter in case elements are appended. - this.lastFilter = category; // This is saved mainly because providing a filter function (like searching) - // will overwrite the `lastFilter` property every time its called. - if (typeof category === 'string') { - this.group = category; - } + this.lastFilter = category; // This is saved mainly because providing a filter function (like searching) + // will overwrite the `lastFilter` property every time its called. - return set; + if (typeof category === 'string') { + this.group = category; } - /** - * Returns an object containing the visible and hidden elements. - * @param {string|string[]|function(Element):boolean} category Category or function to filter by. - * @param {ShuffleItem[]} items A collection of items to filter. - * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} - * @private - */ - }, { - key: "_getFilteredSets", - value: function _getFilteredSets(category, items) { - var _this2 = this; + return set; + } + /** + * Returns an object containing the visible and hidden elements. + * @param {string|string[]|function(Element):boolean} category Category or function to filter by. + * @param {ShuffleItem[]} items A collection of items to filter. + * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} + * @private + */ - var visible = []; - var hidden = []; // category === 'all', add visible class to everything - if (category === Shuffle.ALL_ITEMS) { - visible = items; // Loop through each item and use provided function to determine - // whether to hide it or not. - } else { - items.forEach(function (item) { - if (_this2._doesPassFilter(category, item.element)) { - visible.push(item); - } else { - hidden.push(item); - } - }); - } + _getFilteredSets(category, items) { + let visible = []; + const hidden = []; // category === 'all', add visible class to everything - return { - visible: visible, - hidden: hidden - }; + if (category === Shuffle.ALL_ITEMS) { + visible = items; // Loop through each item and use provided function to determine + // whether to hide it or not. + } else { + items.forEach(item => { + if (this._doesPassFilter(category, item.element)) { + visible.push(item); + } else { + hidden.push(item); + } + }); } - /** - * Test an item to see if it passes a category. - * @param {string|string[]|function():boolean} category Category or function to filter by. - * @param {Element} element An element to test. - * @return {boolean} Whether it passes the category/filter. - * @private - */ - - }, { - key: "_doesPassFilter", - value: function _doesPassFilter(category, element) { - if (typeof category === 'function') { - return category.call(element, element, this); - } // Check each element's data-groups attribute against the given category. + return { + visible, + hidden + }; + } + /** + * Test an item to see if it passes a category. + * @param {string|string[]|function():boolean} category Category or function to filter by. + * @param {Element} element An element to test. + * @return {boolean} Whether it passes the category/filter. + * @private + */ - var attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); - var keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); - function testCategory(category) { - return keys.includes(category); - } + _doesPassFilter(category, element) { + if (typeof category === 'function') { + return category.call(element, element, this); + } // Check each element's data-groups attribute against the given category. - if (Array.isArray(category)) { - if (this.options.filterMode === Shuffle.FilterMode.ANY) { - return category.some(testCategory); - } - return category.every(testCategory); - } + const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); + const keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); + function testCategory(category) { return keys.includes(category); } - /** - * Toggles the visible and hidden class names. - * @param {{visible, hidden}} Object with visible and hidden arrays. - * @private - */ - - }, { - key: "_toggleFilterClasses", - value: function _toggleFilterClasses(_ref) { - var visible = _ref.visible, - hidden = _ref.hidden; - visible.forEach(function (item) { - item.show(); - }); - hidden.forEach(function (item) { - item.hide(); - }); - } - /** - * Set the initial css for each item - * @param {ShuffleItem[]} items Set to initialize. - * @private - */ - - }, { - key: "_initItems", - value: function _initItems(items) { - items.forEach(function (item) { - item.init(); - }); - } - /** - * Remove element reference and styles. - * @param {ShuffleItem[]} items Set to dispose. - * @private - */ - }, { - key: "_disposeItems", - value: function _disposeItems(items) { - items.forEach(function (item) { - item.dispose(); - }); - } - /** - * Updates the visible item count. - * @private - */ + if (Array.isArray(category)) { + if (this.options.filterMode === Shuffle.FilterMode.ANY) { + return category.some(testCategory); + } - }, { - key: "_updateItemCount", - value: function _updateItemCount() { - this.visibleItems = this._getFilteredItems().length; + return category.every(testCategory); } - /** - * Sets css transform transition on a group of elements. This is not executed - * at the same time as `item.init` so that transitions don't occur upon - * initialization of a new Shuffle instance. - * @param {ShuffleItem[]} items Shuffle items to set transitions on. - * @protected - */ - }, { - key: "setItemTransitions", - value: function setItemTransitions(items) { - var _this$options = this.options, - speed = _this$options.speed, - easing = _this$options.easing; - var positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; // Allow users to transtion other properties if they exist in the `before` - // css mapping of the shuffle item. - - var cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(function (k) { - return hyphenate(k); - }); - var properties = positionProps.concat(cssProps).join(); - items.forEach(function (item) { - item.element.style.transitionDuration = speed + 'ms'; - item.element.style.transitionTimingFunction = easing; - item.element.style.transitionProperty = properties; - }); - } - }, { - key: "_getItems", - value: function _getItems() { - var _this3 = this; - - return Array.from(this.element.children).filter(function (el) { - return matchesSelector(el, _this3.options.itemSelector); - }).map(function (el) { - return new ShuffleItem(el, _this3.options.isRTL); - }); - } - /** - * Combine the current items array with a new one and sort it by DOM order. - * @param {ShuffleItem[]} items Items to track. - * @return {ShuffleItem[]} - */ + return keys.includes(category); + } + /** + * Toggles the visible and hidden class names. + * @param {{visible, hidden}} Object with visible and hidden arrays. + * @private + */ - }, { - key: "_mergeNewItems", - value: function _mergeNewItems(items) { - var children = Array.from(this.element.children); - return sorter(this.items.concat(items), { - by: function by(element) { - return children.indexOf(element); - } - }); - } - }, { - key: "_getFilteredItems", - value: function _getFilteredItems() { - return this.items.filter(function (item) { - return item.isVisible; - }); - } - }, { - key: "_getConcealedItems", - value: function _getConcealedItems() { - return this.items.filter(function (item) { - return !item.isVisible; - }); - } - /** - * Returns the column size, based on column width and sizer options. - * @param {number} containerWidth Size of the parent container. - * @param {number} gutterSize Size of the gutters. - * @return {number} - * @private - */ - }, { - key: "_getColumnSize", - value: function _getColumnSize(containerWidth, gutterSize) { - var size; // If the columnWidth property is a function, then the grid is fluid - - if (typeof this.options.columnWidth === 'function') { - size = this.options.columnWidth(containerWidth); // columnWidth option isn't a function, are they using a sizing element? - } else if (this.options.sizer) { - size = Shuffle.getSize(this.options.sizer).width; // if not, how about the explicitly set option? - } else if (this.options.columnWidth) { - size = this.options.columnWidth; // or use the size of the first item - } else if (this.items.length > 0) { - size = Shuffle.getSize(this.items[0].element, true).width; // if there's no items, use size of container - } else { - size = containerWidth; - } // Don't let them set a column width of zero. + _toggleFilterClasses(_ref) { + let { + visible, + hidden + } = _ref; + visible.forEach(item => { + item.show(); + }); + hidden.forEach(item => { + item.hide(); + }); + } + /** + * Set the initial css for each item + * @param {ShuffleItem[]} items Set to initialize. + * @private + */ - if (size === 0) { - size = containerWidth; - } + _initItems(items) { + items.forEach(item => { + item.init(); + }); + } + /** + * Remove element reference and styles. + * @param {ShuffleItem[]} items Set to dispose. + * @private + */ - return size + gutterSize; - } - /** - * Returns the gutter size, based on gutter width and sizer options. - * @param {number} containerWidth Size of the parent container. - * @return {number} - * @private - */ - }, { - key: "_getGutterSize", - value: function _getGutterSize(containerWidth) { - var size; + _disposeItems(items) { + items.forEach(item => { + item.dispose(); + }); + } + /** + * Updates the visible item count. + * @private + */ - if (typeof this.options.gutterWidth === 'function') { - size = this.options.gutterWidth(containerWidth); - } else if (this.options.sizer) { - size = getNumberStyle(this.options.sizer, 'marginLeft'); - } else { - size = this.options.gutterWidth; - } - return size; - } - /** - * Calculate the number of columns to be used. Gets css if using sizer element. - * @param {number} [containerWidth] Optionally specify a container width if - * it's already available. - */ + _updateItemCount() { + this.visibleItems = this._getFilteredItems().length; + } + /** + * Sets css transform transition on a group of elements. This is not executed + * at the same time as `item.init` so that transitions don't occur upon + * initialization of a new Shuffle instance. + * @param {ShuffleItem[]} items Shuffle items to set transitions on. + * @protected + */ - }, { - key: "_setColumns", - value: function _setColumns() { - var containerWidth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Shuffle.getSize(this.element).width; - var gutter = this._getGutterSize(containerWidth); + setItemTransitions(items) { + const { + speed, + easing + } = this.options; + const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; // Allow users to transtion other properties if they exist in the `before` + // css mapping of the shuffle item. + + const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k)); + const properties = positionProps.concat(cssProps).join(); + items.forEach(item => { + item.element.style.transitionDuration = speed + 'ms'; + item.element.style.transitionTimingFunction = easing; + item.element.style.transitionProperty = properties; + }); + } - var columnWidth = this._getColumnSize(containerWidth, gutter); + _getItems() { + return Array.from(this.element.children).filter(el => el.matches(this.options.itemSelector)).map(el => new ShuffleItem(el, this.options.isRTL)); + } + /** + * Combine the current items array with a new one and sort it by DOM order. + * @param {ShuffleItem[]} items Items to track. + * @return {ShuffleItem[]} + */ - var calculatedColumns = (containerWidth + gutter) / columnWidth; // Widths given from getStyles are not precise enough... - if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) < this.options.columnThreshold) { - // e.g. calculatedColumns = 11.998876 - calculatedColumns = Math.round(calculatedColumns); + _mergeNewItems(items) { + const children = Array.from(this.element.children); + return sorter(this.items.concat(items), { + by(element) { + return children.indexOf(element); } - this.cols = Math.max(Math.floor(calculatedColumns || 0), 1); - this.containerWidth = containerWidth; - this.colWidth = columnWidth; - } - /** - * Adjust the height of the grid - */ + }); + } - }, { - key: "_setContainerSize", - value: function _setContainerSize() { - this.element.style.height = this._getContainerSize() + 'px'; - } - /** - * Based on the column heights, it returns the biggest one. - * @return {number} - * @private - */ + _getFilteredItems() { + return this.items.filter(item => item.isVisible); + } - }, { - key: "_getContainerSize", - value: function _getContainerSize() { - return arrayMax(this.positions); - } - /** - * Get the clamped stagger amount. - * @param {number} index Index of the item to be staggered. - * @return {number} - */ + _getConcealedItems() { + return this.items.filter(item => !item.isVisible); + } + /** + * Returns the column size, based on column width and sizer options. + * @param {number} containerWidth Size of the parent container. + * @param {number} gutterSize Size of the gutters. + * @return {number} + * @private + */ - }, { - key: "_getStaggerAmount", - value: function _getStaggerAmount(index) { - return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax); - } - /** - * Emit an event from this instance. - * @param {string} name Event name. - * @param {Object} [data={}] Optional object data. - */ - }, { - key: "_dispatch", - value: function _dispatch(name) { - var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + _getColumnSize(containerWidth, gutterSize) { + let size; // If the columnWidth property is a function, then the grid is fluid + + if (typeof this.options.columnWidth === 'function') { + size = this.options.columnWidth(containerWidth); // columnWidth option isn't a function, are they using a sizing element? + } else if (this.options.sizer) { + size = Shuffle.getSize(this.options.sizer).width; // if not, how about the explicitly set option? + } else if (this.options.columnWidth) { + size = this.options.columnWidth; // or use the size of the first item + } else if (this.items.length > 0) { + size = Shuffle.getSize(this.items[0].element, true).width; // if there's no items, use size of container + } else { + size = containerWidth; + } // Don't let them set a column width of zero. - if (this.isDestroyed) { - return; - } - data.shuffle = this; - this.emit(name, data); + if (size === 0) { + size = containerWidth; } - /** - * Zeros out the y columns array, which is used to determine item placement. - * @private - */ - }, { - key: "_resetCols", - value: function _resetCols() { - var i = this.cols; - this.positions = []; + return size + gutterSize; + } + /** + * Returns the gutter size, based on gutter width and sizer options. + * @param {number} containerWidth Size of the parent container. + * @return {number} + * @private + */ - while (i) { - i -= 1; - this.positions.push(0); - } + + _getGutterSize(containerWidth) { + let size; + + if (typeof this.options.gutterWidth === 'function') { + size = this.options.gutterWidth(containerWidth); + } else if (this.options.sizer) { + size = getNumberStyle(this.options.sizer, 'marginLeft'); + } else { + size = this.options.gutterWidth; } - /** - * Loops through each item that should be shown and calculates the x, y position. - * @param {ShuffleItem[]} items Array of items that will be shown/layed - * out in order in their array. - */ - }, { - key: "_layout", - value: function _layout(items) { - var _this4 = this; + return size; + } + /** + * Calculate the number of columns to be used. Gets css if using sizer element. + * @param {number} [containerWidth] Optionally specify a container width if + * it's already available. + */ - var itemPositions = this._getNextPositions(items); - var count = 0; - items.forEach(function (item, i) { - function callback() { - item.applyCss(ShuffleItem.Css.VISIBLE.after); - } // If the item will not change its position, do not add it to the render - // queue. Transitions don't fire when setting a property to the same value. + _setColumns() { + let containerWidth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Shuffle.getSize(this.element).width; + const gutter = this._getGutterSize(containerWidth); - if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) { - item.applyCss(ShuffleItem.Css.VISIBLE.before); - callback(); - return; - } + const columnWidth = this._getColumnSize(containerWidth, gutter); - item.point = itemPositions[i]; - item.scale = ShuffleItem.Scale.VISIBLE; - item.isHidden = false; // Clone the object so that the `before` object isn't modified when the - // transition delay is added. + let calculatedColumns = (containerWidth + gutter) / columnWidth; // Widths given from getStyles are not precise enough... - var styles = _this4.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before); + if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) < this.options.columnThreshold) { + // e.g. calculatedColumns = 11.998876 + calculatedColumns = Math.round(calculatedColumns); + } - styles.transitionDelay = _this4._getStaggerAmount(count) + 'ms'; + this.cols = Math.max(Math.floor(calculatedColumns || 0), 1); + this.containerWidth = containerWidth; + this.colWidth = columnWidth; + } + /** + * Adjust the height of the grid + */ - _this4._queue.push({ - item: item, - styles: styles, - callback: callback - }); - count += 1; - }); - } - /** - * Return an array of Point instances representing the future positions of - * each item. - * @param {ShuffleItem[]} items Array of sorted shuffle items. - * @return {Point[]} - * @private - */ + _setContainerSize() { + this.element.style.height = this._getContainerSize() + 'px'; + } + /** + * Based on the column heights, it returns the biggest one. + * @return {number} + * @private + */ - }, { - key: "_getNextPositions", - value: function _getNextPositions(items) { - var _this5 = this; - // If position data is going to be changed, add the item's size to the - // transformer to allow for calculations. - if (this.options.isCentered) { - var itemsData = items.map(function (item, i) { - var itemSize = Shuffle.getSize(item.element, true); + _getContainerSize() { + return arrayMax(this.positions); + } + /** + * Get the clamped stagger amount. + * @param {number} index Index of the item to be staggered. + * @return {number} + */ - var point = _this5._getItemPosition(itemSize); - return new Rect(point.x, point.y, itemSize.width, itemSize.height, i); - }); - return this.getTransformedPositions(itemsData, this.containerWidth); - } // If no transforms are going to happen, simply return an array of the - // future points of each item. + _getStaggerAmount(index) { + return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax); + } + /** + * Emit an event from this instance. + * @param {string} name Event name. + * @param {Object} [data={}] Optional object data. + */ - return items.map(function (item) { - return _this5._getItemPosition(Shuffle.getSize(item.element, true)); - }); - } - /** - * Determine the location of the next item, based on its size. - * @param {{width: number, height: number}} itemSize Object with width and height. - * @return {Point} - * @private - */ + _dispatch(name) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - }, { - key: "_getItemPosition", - value: function _getItemPosition(itemSize) { - return getItemPosition({ - itemSize: itemSize, - positions: this.positions, - gridSize: this.colWidth, - total: this.cols, - threshold: this.options.columnThreshold, - buffer: this.options.buffer - }); + if (this.isDestroyed) { + return; } - /** - * Mutate positions before they're applied. - * @param {Rect[]} itemRects Item data objects. - * @param {number} containerWidth Width of the containing element. - * @return {Point[]} - * @protected - */ - }, { - key: "getTransformedPositions", - value: function getTransformedPositions(itemRects, containerWidth) { - return getCenteredPositions(itemRects, containerWidth); + data.shuffle = this; + this.emit(name, data); + } + /** + * Zeros out the y columns array, which is used to determine item placement. + * @private + */ + + + _resetCols() { + let i = this.cols; + this.positions = []; + + while (i) { + i -= 1; + this.positions.push(0); } - /** - * Hides the elements that don't match our filter. - * @param {ShuffleItem[]} collection Collection to shrink. - * @private - */ + } + /** + * Loops through each item that should be shown and calculates the x, y position. + * @param {ShuffleItem[]} items Array of items that will be shown/layed + * out in order in their array. + */ - }, { - key: "_shrink", - value: function _shrink() { - var _this6 = this; - - var collection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._getConcealedItems(); - var count = 0; - collection.forEach(function (item) { - function callback() { - item.applyCss(ShuffleItem.Css.HIDDEN.after); - } // Continuing would add a transitionend event listener to the element, but - // that listener would not execute because the transform and opacity would - // stay the same. - // The callback is executed here because it is not guaranteed to be called - // after the transitionend event because the transitionend could be - // canceled if another animation starts. - - - if (item.isHidden) { - item.applyCss(ShuffleItem.Css.HIDDEN.before); - callback(); - return; - } - item.scale = ShuffleItem.Scale.HIDDEN; - item.isHidden = true; + _layout(items) { + const itemPositions = this._getNextPositions(items); - var styles = _this6.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before); + let count = 0; + items.forEach((item, i) => { + function callback() { + item.applyCss(ShuffleItem.Css.VISIBLE.after); + } // If the item will not change its position, do not add it to the render + // queue. Transitions don't fire when setting a property to the same value. - styles.transitionDelay = _this6._getStaggerAmount(count) + 'ms'; - _this6._queue.push({ - item: item, - styles: styles, - callback: callback - }); + if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) { + item.applyCss(ShuffleItem.Css.VISIBLE.before); + callback(); + return; + } - count += 1; + item.point = itemPositions[i]; + item.scale = ShuffleItem.Scale.VISIBLE; + item.isHidden = false; // Clone the object so that the `before` object isn't modified when the + // transition delay is added. + + const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before); + styles.transitionDelay = this._getStaggerAmount(count) + 'ms'; + + this._queue.push({ + item, + styles, + callback }); - } - /** - * Resize handler. - * @private - */ - }, { - key: "_handleResize", - value: function _handleResize() { - // If shuffle is disabled, destroyed, don't do anything - if (!this.isEnabled || this.isDestroyed) { + count += 1; + }); + } + /** + * Return an array of Point instances representing the future positions of + * each item. + * @param {ShuffleItem[]} items Array of sorted shuffle items. + * @return {Point[]} + * @private + */ + + + _getNextPositions(items) { + // If position data is going to be changed, add the item's size to the + // transformer to allow for calculations. + if (this.options.isCentered) { + const itemsData = items.map((item, i) => { + const itemSize = Shuffle.getSize(item.element, true); + + const point = this._getItemPosition(itemSize); + + return new Rect(point.x, point.y, itemSize.width, itemSize.height, i); + }); + return this.getTransformedPositions(itemsData, this.containerWidth); + } // If no transforms are going to happen, simply return an array of the + // future points of each item. + + + return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true))); + } + /** + * Determine the location of the next item, based on its size. + * @param {{width: number, height: number}} itemSize Object with width and height. + * @return {Point} + * @private + */ + + + _getItemPosition(itemSize) { + return getItemPosition({ + itemSize, + positions: this.positions, + gridSize: this.colWidth, + total: this.cols, + threshold: this.options.columnThreshold, + buffer: this.options.buffer + }); + } + /** + * Mutate positions before they're applied. + * @param {Rect[]} itemRects Item data objects. + * @param {number} containerWidth Width of the containing element. + * @return {Point[]} + * @protected + */ + + + getTransformedPositions(itemRects, containerWidth) { + return getCenteredPositions(itemRects, containerWidth); + } + /** + * Hides the elements that don't match our filter. + * @param {ShuffleItem[]} collection Collection to shrink. + * @private + */ + + + _shrink() { + let collection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._getConcealedItems(); + let count = 0; + collection.forEach(item => { + function callback() { + item.applyCss(ShuffleItem.Css.HIDDEN.after); + } // Continuing would add a transitionend event listener to the element, but + // that listener would not execute because the transform and opacity would + // stay the same. + // The callback is executed here because it is not guaranteed to be called + // after the transitionend event because the transitionend could be + // canceled if another animation starts. + + + if (item.isHidden) { + item.applyCss(ShuffleItem.Css.HIDDEN.before); + callback(); return; } - this.update(); + item.scale = ShuffleItem.Scale.HIDDEN; + item.isHidden = true; + const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before); + styles.transitionDelay = this._getStaggerAmount(count) + 'ms'; + + this._queue.push({ + item, + styles, + callback + }); + + count += 1; + }); + } + /** + * Resize handler. + * @private + */ + + + _handleResize() { + // If shuffle is disabled, destroyed, don't do anything + if (!this.isEnabled || this.isDestroyed) { + return; } - /** - * Returns styles which will be applied to the an item for a transition. - * @param {ShuffleItem} item Item to get styles for. Should have updated - * scale and point properties. - * @param {Object} styleObject Extra styles that will be used in the transition. - * @return {!Object} Transforms for transitions, left/top for animate. - * @protected - */ - }, { - key: "getStylesForTransition", - value: function getStylesForTransition(item, styleObject) { - // Clone the object to avoid mutating the original. - // eslint-disable-next-line prefer-object-spread - var styles = Object.assign({}, styleObject); - - if (this.options.useTransforms) { - var sign = this.options.isRTL ? '-' : ''; - var x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x; - var y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y; - styles.transform = "translate(".concat(sign).concat(x, "px, ").concat(y, "px) scale(").concat(item.scale, ")"); - } else { - if (this.options.isRTL) { - styles.right = item.point.x + 'px'; - } else { - styles.left = item.point.x + 'px'; - } + this.update(); + } + /** + * Returns styles which will be applied to the an item for a transition. + * @param {ShuffleItem} item Item to get styles for. Should have updated + * scale and point properties. + * @param {Object} styleObject Extra styles that will be used in the transition. + * @return {!Object} Transforms for transitions, left/top for animate. + * @protected + */ + - styles.top = item.point.y + 'px'; + getStylesForTransition(item, styleObject) { + // Clone the object to avoid mutating the original. + const styles = { ...styleObject + }; + + if (this.options.useTransforms) { + const sign = this.options.isRTL ? '-' : ''; + const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x; + const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y; + styles.transform = `translate(${sign}${x}px, ${y}px) scale(${item.scale})`; + } else { + if (this.options.isRTL) { + styles.right = item.point.x + 'px'; + } else { + styles.left = item.point.x + 'px'; } - return styles; + styles.top = item.point.y + 'px'; } - /** - * Listen for the transition end on an element and execute the itemCallback - * when it finishes. - * @param {Element} element Element to listen on. - * @param {function} itemCallback Callback for the item. - * @param {function} done Callback to notify `parallel` that this one is done. - */ - }, { - key: "_whenTransitionDone", - value: function _whenTransitionDone(element, itemCallback, done) { - var id = onTransitionEnd(element, function (evt) { - itemCallback(); - done(null, evt); - }); + return styles; + } + /** + * Listen for the transition end on an element and execute the itemCallback + * when it finishes. + * @param {Element} element Element to listen on. + * @param {function} itemCallback Callback for the item. + * @param {function} done Callback to notify `parallel` that this one is done. + */ - this._transitions.push(id); - } - /** - * Return a function which will set CSS styles and call the `done` function - * when (if) the transition finishes. - * @param {Object} opts Transition object. - * @return {function} A function to be called with a `done` function. - */ - }, { - key: "_getTransitionFunction", - value: function _getTransitionFunction(opts) { - var _this7 = this; + _whenTransitionDone(element, itemCallback, done) { + const id = onTransitionEnd(element, evt => { + itemCallback(); + done(null, evt); + }); - return function (done) { - opts.item.applyCss(opts.styles); + this._transitions.push(id); + } + /** + * Return a function which will set CSS styles and call the `done` function + * when (if) the transition finishes. + * @param {Object} opts Transition object. + * @return {function} A function to be called with a `done` function. + */ - _this7._whenTransitionDone(opts.item.element, opts.callback, done); - }; + + _getTransitionFunction(opts) { + return done => { + opts.item.applyCss(opts.styles); + + this._whenTransitionDone(opts.item.element, opts.callback, done); + }; + } + /** + * Execute the styles gathered in the style queue. This applies styles to elements, + * triggering transitions. + * @private + */ + + + _processQueue() { + if (this.isTransitioning) { + this._cancelMovement(); } - /** - * Execute the styles gathered in the style queue. This applies styles to elements, - * triggering transitions. - * @private - */ - }, { - key: "_processQueue", - value: function _processQueue() { - if (this.isTransitioning) { - this._cancelMovement(); - } + const hasSpeed = this.options.speed > 0; + const hasQueue = this._queue.length > 0; - var hasSpeed = this.options.speed > 0; - var hasQueue = this._queue.length > 0; + if (hasQueue && hasSpeed && this.isInitialized) { + this._startTransitions(this._queue); + } else if (hasQueue) { + this._styleImmediately(this._queue); - if (hasQueue && hasSpeed && this.isInitialized) { - this._startTransitions(this._queue); - } else if (hasQueue) { - this._styleImmediately(this._queue); + this._dispatch(Shuffle.EventType.LAYOUT); // A call to layout happened, but none of the newly visible items will + // change position or the transition duration is zero, which will not trigger + // the transitionend event. - this._dispatch(Shuffle.EventType.LAYOUT); // A call to layout happened, but none of the newly visible items will - // change position or the transition duration is zero, which will not trigger - // the transitionend event. + } else { + this._dispatch(Shuffle.EventType.LAYOUT); + } // Remove everything in the style queue - } else { - this._dispatch(Shuffle.EventType.LAYOUT); - } // Remove everything in the style queue + this._queue.length = 0; + } + /** + * Wait for each transition to finish, the emit the layout event. + * @param {Object[]} transitions Array of transition objects. + */ - this._queue.length = 0; - } - /** - * Wait for each transition to finish, the emit the layout event. - * @param {Object[]} transitions Array of transition objects. - */ - }, { - key: "_startTransitions", - value: function _startTransitions(transitions) { - var _this8 = this; + _startTransitions(transitions) { + // Set flag that shuffle is currently in motion. + this.isTransitioning = true; // Create an array of functions to be called. - // Set flag that shuffle is currently in motion. - this.isTransitioning = true; // Create an array of functions to be called. + const callbacks = transitions.map(obj => this._getTransitionFunction(obj)); + arrayParallel(callbacks, this._movementFinished.bind(this)); + } - var callbacks = transitions.map(function (obj) { - return _this8._getTransitionFunction(obj); - }); - arrayParallel(callbacks, this._movementFinished.bind(this)); - } - }, { - key: "_cancelMovement", - value: function _cancelMovement() { - // Remove the transition end event for each listener. - this._transitions.forEach(cancelTransitionEnd); // Reset the array. + _cancelMovement() { + // Remove the transition end event for each listener. + this._transitions.forEach(cancelTransitionEnd); // Reset the array. - this._transitions.length = 0; // Show it's no longer active. + this._transitions.length = 0; // Show it's no longer active. - this.isTransitioning = false; - } - /** - * Apply styles without a transition. - * @param {Object[]} objects Array of transition objects. - * @private - */ + this.isTransitioning = false; + } + /** + * Apply styles without a transition. + * @param {Object[]} objects Array of transition objects. + * @private + */ - }, { - key: "_styleImmediately", - value: function _styleImmediately(objects) { - if (objects.length) { - var elements = objects.map(function (obj) { - return obj.item.element; - }); - Shuffle._skipTransitions(elements, function () { - objects.forEach(function (obj) { - obj.item.applyCss(obj.styles); - obj.callback(); - }); + _styleImmediately(objects) { + if (objects.length) { + const elements = objects.map(obj => obj.item.element); + + Shuffle._skipTransitions(elements, () => { + objects.forEach(obj => { + obj.item.applyCss(obj.styles); + obj.callback(); }); - } + }); } - }, { - key: "_movementFinished", - value: function _movementFinished() { - this._transitions.length = 0; - this.isTransitioning = false; + } - this._dispatch(Shuffle.EventType.LAYOUT); + _movementFinished() { + this._transitions.length = 0; + this.isTransitioning = false; + + this._dispatch(Shuffle.EventType.LAYOUT); + } + /** + * The magic. This is what makes the plugin 'shuffle' + * @param {string|string[]|function(Element):boolean} [category] Category to filter by. + * Can be a function, string, or array of strings. + * @param {SortOptions} [sortOptions] A sort object which can sort the visible set + */ + + + filter(category, sortOptions) { + if (!this.isEnabled) { + return; } - /** - * The magic. This is what makes the plugin 'shuffle' - * @param {string|string[]|function(Element):boolean} [category] Category to filter by. - * Can be a function, string, or array of strings. - * @param {SortOptions} [sortOptions] A sort object which can sort the visible set - */ - }, { - key: "filter", - value: function filter(category, sortOptions) { - if (!this.isEnabled) { - return; - } + if (!category || category && category.length === 0) { + category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign + } - if (!category || category && category.length === 0) { - category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign - } + this._filter(category); // Shrink each hidden item - this._filter(category); // Shrink each hidden item + this._shrink(); // How many visible elements? - this._shrink(); // How many visible elements? + this._updateItemCount(); // Update transforms on visible elements so they will animate to their new positions. - this._updateItemCount(); // Update transforms on visible elements so they will animate to their new positions. + this.sort(sortOptions); + } + /** + * Gets the visible elements, sorts them, and passes them to layout. + * @param {SortOptions} [sortOptions] The options object to pass to `sorter`. + */ + + + sort() { + let sortOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastSort; - this.sort(sortOptions); + if (!this.isEnabled) { + return; } - /** - * Gets the visible elements, sorts them, and passes them to layout. - * @param {SortOptions} [sortOptions] The options object to pass to `sorter`. - */ - }, { - key: "sort", - value: function sort() { - var sortOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastSort; + this._resetCols(); - if (!this.isEnabled) { - return; - } + const items = sorter(this._getFilteredItems(), sortOptions); + this.sortedItems = items; - this._resetCols(); + this._layout(items); // `_layout` always happens after `_shrink`, so it's safe to process the style + // queue here with styles from the shrink method. - var items = sorter(this._getFilteredItems(), sortOptions); - this.sortedItems = items; - this._layout(items); // `_layout` always happens after `_shrink`, so it's safe to process the style - // queue here with styles from the shrink method. + this._processQueue(); // Adjust the height of the container. - this._processQueue(); // Adjust the height of the container. + this._setContainerSize(); + this.lastSort = sortOptions; + } + /** + * Reposition everything. + * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated. + */ + + + update() { + let isOnlyLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - this._setContainerSize(); + if (this.isEnabled) { + if (!isOnlyLayout) { + // Get updated colCount + this._setColumns(); + } // Layout items - this.lastSort = sortOptions; + + this.sort(); } - /** - * Reposition everything. - * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated. - */ + } + /** + * Use this instead of `update()` if you don't need the columns and gutters updated + * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations + * could be off. + */ - }, { - key: "update", - value: function update() { - var isOnlyLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - if (this.isEnabled) { - if (!isOnlyLayout) { - // Get updated colCount - this._setColumns(); - } // Layout items + layout() { + this.update(true); + } + /** + * New items have been appended to shuffle. Mix them in with the current + * filter or sort status. + * @param {Element[]} newItems Collection of new items. + */ - this.sort(); - } - } - /** - * Use this instead of `update()` if you don't need the columns and gutters updated - * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations - * could be off. - */ + add(newItems) { + const items = arrayUnique(newItems).map(el => new ShuffleItem(el, this.options.isRTL)); // Add classes and set initial positions. - }, { - key: "layout", - value: function layout() { - this.update(true); - } - /** - * New items have been appended to shuffle. Mix them in with the current - * filter or sort status. - * @param {Element[]} newItems Collection of new items. - */ + this._initItems(items); // Determine which items will go with the current filter. - }, { - key: "add", - value: function add(newItems) { - var _this9 = this; - var items = arrayUnique(newItems).map(function (el) { - return new ShuffleItem(el, _this9.options.isRTL); - }); // Add classes and set initial positions. + this._resetCols(); - this._initItems(items); // Determine which items will go with the current filter. + const allItems = this._mergeNewItems(items); + const sortedItems = sorter(allItems, this.lastSort); - this._resetCols(); + const allSortedItemsSet = this._filter(this.lastFilter, sortedItems); - var allItems = this._mergeNewItems(items); + const isNewItem = item => items.includes(item); - var sortedItems = sorter(allItems, this.lastSort); + const applyHiddenState = item => { + item.scale = ShuffleItem.Scale.HIDDEN; + item.isHidden = true; + item.applyCss(ShuffleItem.Css.HIDDEN.before); + item.applyCss(ShuffleItem.Css.HIDDEN.after); + }; // Layout all items again so that new items get positions. + // Synchonously apply positions. - var allSortedItemsSet = this._filter(this.lastFilter, sortedItems); - var isNewItem = function isNewItem(item) { - return items.includes(item); - }; + const itemPositions = this._getNextPositions(allSortedItemsSet.visible); - var applyHiddenState = function applyHiddenState(item) { - item.scale = ShuffleItem.Scale.HIDDEN; - item.isHidden = true; - item.applyCss(ShuffleItem.Css.HIDDEN.before); - item.applyCss(ShuffleItem.Css.HIDDEN.after); - }; // Layout all items again so that new items get positions. - // Synchonously apply positions. + allSortedItemsSet.visible.forEach((item, i) => { + if (isNewItem(item)) { + item.point = itemPositions[i]; + applyHiddenState(item); + item.applyCss(this.getStylesForTransition(item, {})); + } + }); + allSortedItemsSet.hidden.forEach(item => { + if (isNewItem(item)) { + applyHiddenState(item); + } + }); // Cause layout so that the styles above are applied. + this.element.offsetWidth; // eslint-disable-line no-unused-expressions + // Add transition to each item. - var itemPositions = this._getNextPositions(allSortedItemsSet.visible); + this.setItemTransitions(items); // Update the list of items. - allSortedItemsSet.visible.forEach(function (item, i) { - if (isNewItem(item)) { - item.point = itemPositions[i]; - applyHiddenState(item); - item.applyCss(_this9.getStylesForTransition(item, {})); - } - }); - allSortedItemsSet.hidden.forEach(function (item) { - if (isNewItem(item)) { - applyHiddenState(item); - } - }); // Cause layout so that the styles above are applied. + this.items = this._mergeNewItems(items); // Update layout/visibility of new and old items. + + this.filter(this.lastFilter); + } + /** + * Disables shuffle from updating dimensions and layout on resize + */ - this.element.offsetWidth; // eslint-disable-line no-unused-expressions - // Add transition to each item. - this.setItemTransitions(items); // Update the list of items. + disable() { + this.isEnabled = false; + } + /** + * Enables shuffle again + * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters + */ - this.items = this._mergeNewItems(items); // Update layout/visibility of new and old items. - this.filter(this.lastFilter); - } - /** - * Disables shuffle from updating dimensions and layout on resize - */ + enable() { + let isUpdateLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + this.isEnabled = true; - }, { - key: "disable", - value: function disable() { - this.isEnabled = false; + if (isUpdateLayout) { + this.update(); } - /** - * Enables shuffle again - * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters - */ + } + /** + * Remove 1 or more shuffle items. + * @param {Element[]} elements An array containing one or more + * elements in shuffle + * @return {Shuffle} The shuffle instance. + */ - }, { - key: "enable", - value: function enable() { - var isUpdateLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - this.isEnabled = true; - if (isUpdateLayout) { - this.update(); - } + remove(elements) { + if (!elements.length) { + return; } - /** - * Remove 1 or more shuffle items. - * @param {Element[]} elements An array containing one or more - * elements in shuffle - * @return {Shuffle} The shuffle instance. - */ - }, { - key: "remove", - value: function remove(elements) { - var _this10 = this; + const collection = arrayUnique(elements); + const oldItems = collection.map(element => this.getItemByElement(element)).filter(item => !!item); - if (!elements.length) { - return; - } + const handleLayout = () => { + this._disposeItems(oldItems); // Remove the collection in the callback - var collection = arrayUnique(elements); - var oldItems = collection.map(function (element) { - return _this10.getItemByElement(element); - }).filter(function (item) { - return !!item; + + collection.forEach(element => { + element.parentNode.removeChild(element); }); - var handleLayout = function handleLayout() { - _this10._disposeItems(oldItems); // Remove the collection in the callback + this._dispatch(Shuffle.EventType.REMOVED, { + collection + }); + }; // Hide collection first. - collection.forEach(function (element) { - element.parentNode.removeChild(element); - }); + this._toggleFilterClasses({ + visible: [], + hidden: oldItems + }); - _this10._dispatch(Shuffle.EventType.REMOVED, { - collection: collection - }); - }; // Hide collection first. + this._shrink(oldItems); + this.sort(); // Update the list of items here because `remove` could be called again + // with an item that is in the process of being removed. - this._toggleFilterClasses({ - visible: [], - hidden: oldItems - }); + this.items = this.items.filter(item => !oldItems.includes(item)); - this._shrink(oldItems); + this._updateItemCount(); - this.sort(); // Update the list of items here because `remove` could be called again - // with an item that is in the process of being removed. + this.once(Shuffle.EventType.LAYOUT, handleLayout); + } + /** + * Retrieve a shuffle item by its element. + * @param {Element} element Element to look for. + * @return {?ShuffleItem} A shuffle item or undefined if it's not found. + */ - this.items = this.items.filter(function (item) { - return !oldItems.includes(item); - }); - this._updateItemCount(); + getItemByElement(element) { + return this.items.find(item => item.element === element); + } + /** + * Dump the elements currently stored and reinitialize all child elements which + * match the `itemSelector`. + */ - this.once(Shuffle.EventType.LAYOUT, handleLayout); - } - /** - * Retrieve a shuffle item by its element. - * @param {Element} element Element to look for. - * @return {?ShuffleItem} A shuffle item or undefined if it's not found. - */ - }, { - key: "getItemByElement", - value: function getItemByElement(element) { - return this.items.find(function (item) { - return item.element === element; - }); - } - /** - * Dump the elements currently stored and reinitialize all child elements which - * match the `itemSelector`. - */ + resetItems() { + // Remove refs to current items. + this._disposeItems(this.items); - }, { - key: "resetItems", - value: function resetItems() { - var _this11 = this; + this.isInitialized = false; // Find new items in the DOM. - // Remove refs to current items. - this._disposeItems(this.items); + this.items = this._getItems(); // Set initial styles on the new items. - this.isInitialized = false; // Find new items in the DOM. + this._initItems(this.items); - this.items = this._getItems(); // Set initial styles on the new items. + this.once(Shuffle.EventType.LAYOUT, () => { + // Add transition to each item. + this.setItemTransitions(this.items); + this.isInitialized = true; + }); // Lay out all items. - this._initItems(this.items); + this.filter(this.lastFilter); + } + /** + * Destroys shuffle, removes events, styles, and classes + */ - this.once(Shuffle.EventType.LAYOUT, function () { - // Add transition to each item. - _this11.setItemTransitions(_this11.items); - _this11.isInitialized = true; - }); // Lay out all items. + destroy() { + this._cancelMovement(); - this.filter(this.lastFilter); - } - /** - * Destroys shuffle, removes events, styles, and classes - */ + window.removeEventListener('resize', this._onResize); // Reset container styles - }, { - key: "destroy", - value: function destroy() { - this._cancelMovement(); + this.element.classList.remove('shuffle'); + this.element.removeAttribute('style'); // Reset individual item styles - window.removeEventListener('resize', this._onResize); // Reset container styles + this._disposeItems(this.items); - this.element.classList.remove('shuffle'); - this.element.removeAttribute('style'); // Reset individual item styles + this.items.length = 0; + this.sortedItems.length = 0; + this._transitions.length = 0; // Null DOM references - this._disposeItems(this.items); + this.options.sizer = null; + this.element = null; // Set a flag so if a debounced resize has been triggered, + // it can first check if it is actually isDestroyed and not doing anything + + this.isDestroyed = true; + this.isEnabled = false; + } + /** + * Returns the outer width of an element, optionally including its margins. + * + * There are a few different methods for getting the width of an element, none of + * which work perfectly for all Shuffle's use cases. + * + * 1. getBoundingClientRect() `left` and `right` properties. + * - Accounts for transform scaled elements, making it useless for Shuffle + * elements which have shrunk. + * 2. The `offsetWidth` property. + * - This value stays the same regardless of the elements transform property, + * however, it does not return subpixel values. + * 3. getComputedStyle() + * - This works great Chrome, Firefox, Safari, but IE<=11 does not include + * padding and border when box-sizing: border-box is set, requiring a feature + * test and extra work to add the padding back for IE and other browsers which + * follow the W3C spec here. + * + * @param {Element} element The element. + * @param {boolean} [includeMargins=false] Whether to include margins. + * @return {{width: number, height: number}} The width and height. + */ - this.items.length = 0; - this.sortedItems.length = 0; - this._transitions.length = 0; // Null DOM references - this.options.sizer = null; - this.element = null; // Set a flag so if a debounced resize has been triggered, - // it can first check if it is actually isDestroyed and not doing anything + static getSize(element) { + let includeMargins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + // Store the styles so that they can be used by others without asking for it again. + const styles = window.getComputedStyle(element, null); + let width = getNumberStyle(element, 'width', styles); + let height = getNumberStyle(element, 'height', styles); - this.isDestroyed = true; - this.isEnabled = false; + if (includeMargins) { + const marginLeft = getNumberStyle(element, 'marginLeft', styles); + const marginRight = getNumberStyle(element, 'marginRight', styles); + const marginTop = getNumberStyle(element, 'marginTop', styles); + const marginBottom = getNumberStyle(element, 'marginBottom', styles); + width += marginLeft + marginRight; + height += marginTop + marginBottom; } - /** - * Returns the outer width of an element, optionally including its margins. - * - * There are a few different methods for getting the width of an element, none of - * which work perfectly for all Shuffle's use cases. - * - * 1. getBoundingClientRect() `left` and `right` properties. - * - Accounts for transform scaled elements, making it useless for Shuffle - * elements which have shrunk. - * 2. The `offsetWidth` property. - * - This value stays the same regardless of the elements transform property, - * however, it does not return subpixel values. - * 3. getComputedStyle() - * - This works great Chrome, Firefox, Safari, but IE<=11 does not include - * padding and border when box-sizing: border-box is set, requiring a feature - * test and extra work to add the padding back for IE and other browsers which - * follow the W3C spec here. - * - * @param {Element} element The element. - * @param {boolean} [includeMargins=false] Whether to include margins. - * @return {{width: number, height: number}} The width and height. - */ - }], [{ - key: "getSize", - value: function getSize(element) { - var includeMargins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - // Store the styles so that they can be used by others without asking for it again. - var styles = window.getComputedStyle(element, null); - var width = getNumberStyle(element, 'width', styles); - var height = getNumberStyle(element, 'height', styles); - - if (includeMargins) { - var marginLeft = getNumberStyle(element, 'marginLeft', styles); - var marginRight = getNumberStyle(element, 'marginRight', styles); - var marginTop = getNumberStyle(element, 'marginTop', styles); - var marginBottom = getNumberStyle(element, 'marginBottom', styles); - width += marginLeft + marginRight; - height += marginTop + marginBottom; - } + return { + width, + height + }; + } + /** + * Change a property or execute a function which will not have a transition + * @param {Element[]} elements DOM elements that won't be transitioned. + * @param {function} callback A function which will be called while transition + * is set to 0ms. + * @private + */ + + static _skipTransitions(elements, callback) { + const zero = '0ms'; // Save current duration and delay. + + const data = elements.map(element => { + const { + style + } = element; + const duration = style.transitionDuration; + const delay = style.transitionDelay; // Set the duration to zero so it happens immediately + + style.transitionDuration = zero; + style.transitionDelay = zero; return { - width: width, - height: height + duration, + delay }; - } - /** - * Change a property or execute a function which will not have a transition - * @param {Element[]} elements DOM elements that won't be transitioned. - * @param {function} callback A function which will be called while transition - * is set to 0ms. - * @private - */ - - }, { - key: "_skipTransitions", - value: function _skipTransitions(elements, callback) { - var zero = '0ms'; // Save current duration and delay. - - var data = elements.map(function (element) { - var style = element.style; - var duration = style.transitionDuration; - var delay = style.transitionDelay; // Set the duration to zero so it happens immediately - - style.transitionDuration = zero; - style.transitionDelay = zero; - return { - duration: duration, - delay: delay - }; - }); - callback(); // Cause forced synchronous layout. + }); + callback(); // Cause forced synchronous layout. - elements[0].offsetWidth; // eslint-disable-line no-unused-expressions - // Put the duration back + elements[0].offsetWidth; // eslint-disable-line no-unused-expressions + // Put the duration back - elements.forEach(function (element, i) { - element.style.transitionDuration = data[i].duration; - element.style.transitionDelay = data[i].delay; - }); - } - }]); + elements.forEach((element, i) => { + element.style.transitionDuration = data[i].duration; + element.style.transitionDelay = data[i].delay; + }); + } - return Shuffle; - }(TinyEmitter); + } Shuffle.ShuffleItem = ShuffleItem; Shuffle.ALL_ITEMS = 'all'; diff --git a/docs/dist/shuffle.js.map b/docs/dist/shuffle.js.map index 6d2f78b..9b18949 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;\nmodule.exports.TinyEmitter = 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, isRTL) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Set correct direction of item\n */\n this.isRTL = isRTL;\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.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr);\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 visibility: 'visible',\n willChange: 'transform',\n },\n DIRECTION: {\n ltr: {\n left: 0,\n },\n rtl: {\n right: 0,\n },\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","import getNumber from './get-number';\n\nlet value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n const { width } = window.getComputedStyle(e, null);\n // Fix for issue #314\n value = Math.round(getNumber(width)) === 10;\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft)\n + getNumber(styles.paddingRight)\n + getNumber(styles.borderLeftWidth)\n + getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop)\n + getNumber(styles.paddingBottom)\n + getNumber(styles.borderTopWidth)\n + getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n // eslint-disable-next-line prefer-object-spread\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 { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn, getCenteredPositions } 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 // eslint-disable-next-line prefer-object-spread\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 this.sortedItems = this.items;\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 ? this.options.throttle(resizeFunction, this.options.throttleTime) : 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\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n 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 ? attr.split(this.options.delimiter) : 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, this.options.isRTL));\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) < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 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 // eslint-disable-next-line prefer-object-spread\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const sign = this.options.isRTL ? '-' : '';\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(${sign}${x}px, ${y}px) scale(${item.scale})`;\n } else {\n if (this.options.isRTL) {\n styles.right = item.point.x + 'px';\n } else {\n styles.left = item.point.x + 'px';\n }\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 {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\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(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [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 this.sortedItems = items;\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, this.options.isRTL));\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.map((element) => this.getItemByElement(element)).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.sortedItems.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 // Attempt to align grid items to right.\n isRTL: 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":["tinyEmitterModule","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isRTL","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","DIRECTION","rtl","ltr","scale","Scale","point","classes","forEach","className","obj","Object","keys","key","style","removeClasses","position","visibility","willChange","right","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","Math","round","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","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","sortedItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","data","shuffle","emit","itemPositions","_getNextPositions","equals","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","sign","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","parallel","_movementFinished","objects","elements","_skipTransitions","sortOptions","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","allItems","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","once","find","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/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;\nmodule.exports.TinyEmitter = E;\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 && a.top < b.top + b.height && b.top < a.top + a.height\n );\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, isRTL) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Set correct direction of item\n */\n this.isRTL = isRTL;\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.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr);\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([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n visibility: 'visible',\n willChange: 'transform',\n },\n DIRECTION: {\n ltr: {\n left: 0,\n },\n rtl: {\n right: 0,\n },\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","import getNumber from './get-number';\n\nlet value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n const { width } = window.getComputedStyle(e, null);\n // Fix for issue #314\n value = Math.round(getNumber(width)) === 10;\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(element, style, styles = window.getComputedStyle(element, null)) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value +=\n getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value +=\n 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/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n const opts = { ...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(...array);\n}\n","export default function arrayMin(array) {\n return Math.min(...array);\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({ itemSize, positions, gridSize, total, threshold, buffer }) {\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) =>\n rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }),\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 centeredRows\n .flat()\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 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 { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn, getCenteredPositions } 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 = { ...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 this.sortedItems = this.items;\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 ? this.options.throttle(resizeFunction, this.options.throttleTime) : 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\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n 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 ? attr.split(this.options.delimiter) : 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) => el.matches(this.options.itemSelector))\n .map((el) => new ShuffleItem(el, this.options.isRTL));\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) < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 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 = { ...styleObject };\n\n if (this.options.useTransforms) {\n const sign = this.options.isRTL ? '-' : '';\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(${sign}${x}px, ${y}px) scale(${item.scale})`;\n } else {\n if (this.options.isRTL) {\n styles.right = item.point.x + 'px';\n } else {\n styles.left = item.point.x + 'px';\n }\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 {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\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(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [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 this.sortedItems = items;\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, this.options.isRTL));\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.map((element) => this.getItemByElement(element)).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.sortedItems.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 // Attempt to align grid items to right.\n isRTL: 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":["tinyEmitterModule","getNumber","value","parseFloat","Point","constructor","x","y","equals","a","b","Rect","w","h","id","left","top","width","height","intersects","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isRTL","isVisible","isHidden","show","classList","remove","Classes","add","removeAttribute","hide","setAttribute","init","addClasses","applyCss","Css","INITIAL","DIRECTION","rtl","ltr","scale","Scale","point","classes","forEach","className","removeClasses","obj","Object","keys","key","style","dispose","position","visibility","willChange","right","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","Math","round","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","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","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","flat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","TinyEmitter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sortedItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","_filter","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimiter","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","_disposeItems","_updateItemCount","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","_mergeNewItems","indexOf","_getConcealedItems","_getColumnSize","gutterSize","size","_getGutterSize","gutterWidth","gutter","calculatedColumns","columnThreshold","cols","colWidth","_setContainerSize","_getContainerSize","_getStaggerAmount","index","staggerAmount","staggerAmountMax","_dispatch","name","data","shuffle","emit","_resetCols","_layout","itemPositions","_getNextPositions","getStylesForTransition","isCentered","itemsData","_getItemPosition","getTransformedPositions","_shrink","update","styleObject","sign","roundTransforms","transform","_whenTransitionDone","itemCallback","done","_getTransitionFunction","_processQueue","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","EventType","LAYOUT","callbacks","parallel","_movementFinished","objects","elements","_skipTransitions","sortOptions","isOnlyLayout","newItems","allItems","allSortedItemsSet","isNewItem","applyHiddenState","disable","enable","isUpdateLayout","oldItems","getItemByElement","handleLayout","parentNode","REMOVED","once","find","resetItems","destroy","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":";;;;;;;;EAAA,SAAS,CAAC,IAAI;EACd;EACA;EACA,CAAC;AACD;EACA,CAAC,CAAC,SAAS,GAAG;EACd,EAAE,EAAE,EAAE,UAAU,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE;EACrC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACpC;EACA,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC;EACrC,MAAM,EAAE,EAAE,QAAQ;EAClB,MAAM,GAAG,EAAE,GAAG;EACd,KAAK,CAAC,CAAC;AACP;EACA,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;AACH;EACA,EAAE,IAAI,EAAE,UAAU,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE;EACvC,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,SAAS,QAAQ,IAAI;EACzB,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;EAC/B,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;EACrC,KACA;EACA,IAAI,QAAQ,CAAC,CAAC,GAAG,SAAQ;EACzB,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;EACxC,GAAG;AACH;EACA,EAAE,IAAI,EAAE,UAAU,IAAI,EAAE;EACxB,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;EAC3C,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;EACjE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;AAC5B;EACA,IAAI,KAAK,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;EAC1B,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;EAC9C,KAAK;AACL;EACA,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;AACH;EACA,EAAE,GAAG,EAAE,UAAU,IAAI,EAAE,QAAQ,EAAE;EACjC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;EACpC,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;EACvB,IAAI,IAAI,UAAU,GAAG,EAAE,CAAC;AACxB;EACA,IAAI,IAAI,IAAI,IAAI,QAAQ,EAAE;EAC1B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,QAAQ;EAChE,UAAU,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACnC,OAAO;EACP,KAAK;AACL;EACA;EACA;EACA;AACA;EACA,IAAI,CAAC,UAAU,CAAC,MAAM;EACtB,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,UAAU;EAC5B,QAAQ,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;AACvB;EACA,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,CAAC,CAAC;AACF;AACAA,qBAAc,GAAG,CAAC,CAAC;iCACO,GAAG;;;;MClE7B,UAAc,GAAG,QAAQ,CAAC;AAC1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;EACA,SAAS,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;EAC/B,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC;EAChC,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;AACf;EACA,EAAE,OAAO,SAAS,SAAS,IAAI;EAC/B,IAAI,GAAG,GAAG,IAAI,CAAC;EACf,IAAI,IAAI,GAAG,SAAS,CAAC;EACrB,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,SAAS;EAClB,MAAM,IAAI,KAAK,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;EAChC,WAAW,SAAS,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC;EACtD,IAAI,OAAO,GAAG,CAAC;EACf,GAAG,CAAC;AACJ;EACA,EAAE,SAAS,IAAI,IAAI;EACnB,IAAI,SAAS,GAAG,CAAC,CAAC;EAClB,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;EACvB,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;EAChC,IAAI,GAAG,GAAG,IAAI,CAAC;EACf,IAAI,IAAI,GAAG,IAAI,CAAC;EAChB,GAAG;EACH;;MC/BA,aAAc,GAAG,SAAS,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE;EAC3D,EAAE,IAAI,CAAC,QAAQ,EAAE;EACjB,IAAI,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;EACvC,MAAM,QAAQ,GAAG,QAAO;EACxB,MAAM,OAAO,GAAG,KAAI;EACpB,KAAK,MAAM;EACX,MAAM,QAAQ,GAAG,KAAI;EACrB,KAAK;EACL,GAAG;AACH;EACA,EAAE,IAAI,OAAO,GAAG,GAAG,IAAI,GAAG,CAAC,OAAM;EACjC,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1C;EACA,EAAE,IAAI,QAAQ,GAAG,MAAK;EACtB,EAAE,IAAI,OAAO,GAAG,IAAI,KAAK,CAAC,OAAO,EAAC;AAClC;EACA,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,UAAU,EAAE,EAAE,CAAC,EAAE;EACzC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAC;EAClC,GAAG,GAAG,UAAU,EAAE,EAAE,CAAC,EAAE;EACvB,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAC;EACpB,GAAG,EAAC;AACJ;EACA,EAAE,SAAS,SAAS,CAAC,CAAC,EAAE;EACxB,IAAI,OAAO,UAAU,GAAG,EAAE,MAAM,EAAE;EAClC,MAAM,IAAI,QAAQ,EAAE,OAAO;AAC3B;EACA,MAAM,IAAI,GAAG,EAAE;EACf,QAAQ,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAC;EAC9B,QAAQ,QAAQ,GAAG,KAAI;EACvB,QAAQ,MAAM;EACd,OAAO;AACP;EACA,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAM;AACzB;EACA,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC9C,KAAK;EACL,GAAG;EACH,EAAC;AACD;EACA,SAAS,IAAI,GAAG;;ECvChB;EACA;EACA;EACA;EACA;EACe,SAASC,SAAT,CAAmBC,KAAnB,EAA0B;EACvC,SAAOC,UAAU,CAACD,KAAD,CAAV,IAAqB,CAA5B;EACD;;ECLD,MAAME,KAAN,CAAY;EACV;EACF;EACA;EACA;EACA;EACEC,EAAAA,WAAW,CAACC,CAAD,EAAIC,CAAJ,EAAO;EAChB,SAAKD,CAAL,GAASL,SAAS,CAACK,CAAD,CAAlB;EACA,SAAKC,CAAL,GAASN,SAAS,CAACM,CAAD,CAAlB;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACe,SAANC,MAAM,CAACC,CAAD,EAAIC,CAAJ,EAAO;EAClB,WAAOD,CAAC,CAACH,CAAF,KAAQI,CAAC,CAACJ,CAAV,IAAeG,CAAC,CAACF,CAAF,KAAQG,CAAC,CAACH,CAAhC;EACD;;EAnBS;;ECFG,MAAMI,IAAN,CAAW;EACxB;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACEN,EAAAA,WAAW,CAACC,CAAD,EAAIC,CAAJ,EAAOK,CAAP,EAAUC,CAAV,EAAaC,EAAb,EAAiB;EAC1B,SAAKA,EAAL,GAAUA,EAAV;EAEA;;EACA,SAAKC,IAAL,GAAYT,CAAZ;EAEA;;EACA,SAAKU,GAAL,GAAWT,CAAX;EAEA;;EACA,SAAKU,KAAL,GAAaL,CAAb;EAEA;;EACA,SAAKM,MAAL,GAAcL,CAAd;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACmB,SAAVM,UAAU,CAACV,CAAD,EAAIC,CAAJ,EAAO;EACtB,WACED,CAAC,CAACM,IAAF,GAASL,CAAC,CAACK,IAAF,GAASL,CAAC,CAACO,KAApB,IAA6BP,CAAC,CAACK,IAAF,GAASN,CAAC,CAACM,IAAF,GAASN,CAAC,CAACQ,KAAjD,IAA0DR,CAAC,CAACO,GAAF,GAAQN,CAAC,CAACM,GAAF,GAAQN,CAAC,CAACQ,MAA5E,IAAsFR,CAAC,CAACM,GAAF,GAAQP,CAAC,CAACO,GAAF,GAAQP,CAAC,CAACS,MAD1G;EAGD;;EArCuB;;ACA1B,gBAAe;EACbE,EAAAA,IAAI,EAAE,SADO;EAEbC,EAAAA,YAAY,EAAE,cAFD;EAGbC,EAAAA,OAAO,EAAE,uBAHI;EAIbC,EAAAA,MAAM,EAAE;EAJK,CAAf;;ECGA,IAAIT,IAAE,GAAG,CAAT;;EAEA,MAAMU,WAAN,CAAkB;EAChBnB,EAAAA,WAAW,CAACoB,OAAD,EAAUC,KAAV,EAAiB;EAC1BZ,IAAAA,IAAE,IAAI,CAAN;EACA,SAAKA,EAAL,GAAUA,IAAV;EACA,SAAKW,OAAL,GAAeA,OAAf;EAEA;EACJ;EACA;;EACI,SAAKC,KAAL,GAAaA,KAAb;EAEA;EACJ;EACA;;EACI,SAAKC,SAAL,GAAiB,IAAjB;EAEA;EACJ;EACA;EACA;EACA;EACA;;EACI,SAAKC,QAAL,GAAgB,KAAhB;EACD;;EAEDC,EAAAA,IAAI,GAAG;EACL,SAAKF,SAAL,GAAiB,IAAjB;EACA,SAAKF,OAAL,CAAaK,SAAb,CAAuBC,MAAvB,CAA8BC,OAAO,CAACT,MAAtC;EACA,SAAKE,OAAL,CAAaK,SAAb,CAAuBG,GAAvB,CAA2BD,OAAO,CAACV,OAAnC;EACA,SAAKG,OAAL,CAAaS,eAAb,CAA6B,aAA7B;EACD;;EAEDC,EAAAA,IAAI,GAAG;EACL,SAAKR,SAAL,GAAiB,KAAjB;EACA,SAAKF,OAAL,CAAaK,SAAb,CAAuBC,MAAvB,CAA8BC,OAAO,CAACV,OAAtC;EACA,SAAKG,OAAL,CAAaK,SAAb,CAAuBG,GAAvB,CAA2BD,OAAO,CAACT,MAAnC;EACA,SAAKE,OAAL,CAAaW,YAAb,CAA0B,aAA1B,EAAyC,IAAzC;EACD;;EAEDC,EAAAA,IAAI,GAAG;EACL,SAAKC,UAAL,CAAgB,CAACN,OAAO,CAACX,YAAT,EAAuBW,OAAO,CAACV,OAA/B,CAAhB;EACA,SAAKiB,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBC,OAA9B;EACA,SAAKF,QAAL,CAAc,KAAKb,KAAL,GAAaF,WAAW,CAACgB,GAAZ,CAAgBE,SAAhB,CAA0BC,GAAvC,GAA6CnB,WAAW,CAACgB,GAAZ,CAAgBE,SAAhB,CAA0BE,GAArF;EACA,SAAKC,KAAL,GAAarB,WAAW,CAACsB,KAAZ,CAAkBxB,OAA/B;EACA,SAAKyB,KAAL,GAAa,IAAI3C,KAAJ,EAAb;EACD;;EAEDkC,EAAAA,UAAU,CAACU,OAAD,EAAU;EAClBA,IAAAA,OAAO,CAACC,OAAR,CAAiBC,SAAD,IAAe;EAC7B,WAAKzB,OAAL,CAAaK,SAAb,CAAuBG,GAAvB,CAA2BiB,SAA3B;EACD,KAFD;EAGD;;EAEDC,EAAAA,aAAa,CAACH,OAAD,EAAU;EACrBA,IAAAA,OAAO,CAACC,OAAR,CAAiBC,SAAD,IAAe;EAC7B,WAAKzB,OAAL,CAAaK,SAAb,CAAuBC,MAAvB,CAA8BmB,SAA9B;EACD,KAFD;EAGD;;EAEDX,EAAAA,QAAQ,CAACa,GAAD,EAAM;EACZC,IAAAA,MAAM,CAACC,IAAP,CAAYF,GAAZ,EAAiBH,OAAjB,CAA0BM,GAAD,IAAS;EAChC,WAAK9B,OAAL,CAAa+B,KAAb,CAAmBD,GAAnB,IAA0BH,GAAG,CAACG,GAAD,CAA7B;EACD,KAFD;EAGD;;EAEDE,EAAAA,OAAO,GAAG;EACR,SAAKN,aAAL,CAAmB,CAACnB,OAAO,CAACT,MAAT,EAAiBS,OAAO,CAACV,OAAzB,EAAkCU,OAAO,CAACX,YAA1C,CAAnB;EAEA,SAAKI,OAAL,CAAaS,eAAb,CAA6B,OAA7B;EACA,SAAKT,OAAL,GAAe,IAAf;EACD;;EAtEe;;EAyElBD,WAAW,CAACgB,GAAZ,GAAkB;EAChBC,EAAAA,OAAO,EAAE;EACPiB,IAAAA,QAAQ,EAAE,UADH;EAEP1C,IAAAA,GAAG,EAAE,CAFE;EAGP2C,IAAAA,UAAU,EAAE,SAHL;EAIPC,IAAAA,UAAU,EAAE;EAJL,GADO;EAOhBlB,EAAAA,SAAS,EAAE;EACTE,IAAAA,GAAG,EAAE;EACH7B,MAAAA,IAAI,EAAE;EADH,KADI;EAIT4B,IAAAA,GAAG,EAAE;EACHkB,MAAAA,KAAK,EAAE;EADJ;EAJI,GAPK;EAehBvC,EAAAA,OAAO,EAAE;EACPwC,IAAAA,MAAM,EAAE;EACNC,MAAAA,OAAO,EAAE,CADH;EAENJ,MAAAA,UAAU,EAAE;EAFN,KADD;EAKPK,IAAAA,KAAK,EAAE;EACLC,MAAAA,eAAe,EAAE;EADZ;EALA,GAfO;EAwBhB1C,EAAAA,MAAM,EAAE;EACNuC,IAAAA,MAAM,EAAE;EACNC,MAAAA,OAAO,EAAE;EADH,KADF;EAINC,IAAAA,KAAK,EAAE;EACLL,MAAAA,UAAU,EAAE,QADP;EAELM,MAAAA,eAAe,EAAE;EAFZ;EAJD;EAxBQ,CAAlB;EAmCAzC,WAAW,CAACsB,KAAZ,GAAoB;EAClBxB,EAAAA,OAAO,EAAE,CADS;EAElBC,EAAAA,MAAM,EAAE;EAFU,CAApB;;EC/GA,IAAIrB,KAAK,GAAG,IAAZ;AACA,0BAAe,MAAM;EACnB,MAAIA,KAAK,KAAK,IAAd,EAAoB;EAClB,WAAOA,KAAP;EACD;;EAED,QAAMuB,OAAO,GAAGyC,QAAQ,CAACC,IAAT,IAAiBD,QAAQ,CAACE,eAA1C;EACA,QAAMC,CAAC,GAAGH,QAAQ,CAACI,aAAT,CAAuB,KAAvB,CAAV;EACAD,EAAAA,CAAC,CAACb,KAAF,CAAQe,OAAR,GAAkB,+CAAlB;EACA9C,EAAAA,OAAO,CAAC+C,WAAR,CAAoBH,CAApB;EAEA,QAAM;EAAEpD,IAAAA;EAAF,MAAYwD,MAAM,CAACC,gBAAP,CAAwBL,CAAxB,EAA2B,IAA3B,CAAlB,CAVmB;;EAYnBnE,EAAAA,KAAK,GAAGyE,IAAI,CAACC,KAAL,CAAW3E,SAAS,CAACgB,KAAD,CAApB,MAAiC,EAAzC;EAEAQ,EAAAA,OAAO,CAACoD,WAAR,CAAoBR,CAApB;EAEA,SAAOnE,KAAP;EACD,CAjBD;;ECAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACe,SAAS4E,cAAT,CAAwBrD,OAAxB,EAAiC+B,KAAjC,EAAyF;EAAA,MAAjDuB,MAAiD,uEAAxCN,MAAM,CAACC,gBAAP,CAAwBjD,OAAxB,EAAiC,IAAjC,CAAwC;EACtG,MAAIvB,KAAK,GAAGD,SAAS,CAAC8E,MAAM,CAACvB,KAAD,CAAP,CAArB,CADsG;;EAItG,MAAI,CAACwB,gBAAgB,EAAjB,IAAuBxB,KAAK,KAAK,OAArC,EAA8C;EAC5CtD,IAAAA,KAAK,IACHD,SAAS,CAAC8E,MAAM,CAACE,WAAR,CAAT,GACAhF,SAAS,CAAC8E,MAAM,CAACG,YAAR,CADT,GAEAjF,SAAS,CAAC8E,MAAM,CAACI,eAAR,CAFT,GAGAlF,SAAS,CAAC8E,MAAM,CAACK,gBAAR,CAJX;EAKD,GAND,MAMO,IAAI,CAACJ,gBAAgB,EAAjB,IAAuBxB,KAAK,KAAK,QAArC,EAA+C;EACpDtD,IAAAA,KAAK,IACHD,SAAS,CAAC8E,MAAM,CAACM,UAAR,CAAT,GACApF,SAAS,CAAC8E,MAAM,CAACO,aAAR,CADT,GAEArF,SAAS,CAAC8E,MAAM,CAACQ,cAAR,CAFT,GAGAtF,SAAS,CAAC8E,MAAM,CAACS,iBAAR,CAJX;EAKD;;EAED,SAAOtF,KAAP;EACD;;EChCD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASuF,SAAT,CAAmBC,KAAnB,EAA0B;EACxB,MAAIC,CAAC,GAAGD,KAAK,CAACE,MAAd;;EAEA,SAAOD,CAAP,EAAU;EACRA,IAAAA,CAAC,IAAI,CAAL;EACA,UAAME,CAAC,GAAGlB,IAAI,CAACmB,KAAL,CAAWnB,IAAI,CAACoB,MAAL,MAAiBJ,CAAC,GAAG,CAArB,CAAX,CAAV;EACA,UAAMK,IAAI,GAAGN,KAAK,CAACG,CAAD,CAAlB;EACAH,IAAAA,KAAK,CAACG,CAAD,CAAL,GAAWH,KAAK,CAACC,CAAD,CAAhB;EACAD,IAAAA,KAAK,CAACC,CAAD,CAAL,GAAWK,IAAX;EACD;;EAED,SAAON,KAAP;EACD;;EAED,MAAMO,QAAQ,GAAG;EACf;EACAC,EAAAA,OAAO,EAAE,KAFM;EAIf;EACAC,EAAAA,EAAE,EAAE,IALW;EAOf;EACAC,EAAAA,OAAO,EAAE,IARM;EAUf;EACAX,EAAAA,SAAS,EAAE,KAXI;EAaf;EACA;EACAlC,EAAAA,GAAG,EAAE;EAfU,CAAjB;EAkBA;EACA;EACA;EACA;EACA;EACA;;EACe,SAAS8C,MAAT,CAAgBC,GAAhB,EAAqBC,OAArB,EAA8B;EAC3C,QAAMC,IAAI,GAAG,EAAE,GAAGP,QAAL;EAAe,OAAGM;EAAlB,GAAb;EACA,QAAME,QAAQ,GAAGC,KAAK,CAACC,IAAN,CAAWL,GAAX,CAAjB;EACA,MAAIM,MAAM,GAAG,KAAb;;EAEA,MAAI,CAACN,GAAG,CAACV,MAAT,EAAiB;EACf,WAAO,EAAP;EACD;;EAED,MAAIY,IAAI,CAACf,SAAT,EAAoB;EAClB,WAAOA,SAAS,CAACa,GAAD,CAAhB;EACD,GAX0C;EAc3C;;;EACA,MAAI,OAAOE,IAAI,CAACL,EAAZ,KAAmB,UAAvB,EAAmC;EACjCG,IAAAA,GAAG,CAACO,IAAJ,CAAS,CAACpG,CAAD,EAAIC,CAAJ,KAAU;EACjB;EACA,UAAIkG,MAAJ,EAAY;EACV,eAAO,CAAP;EACD;;EAED,YAAME,IAAI,GAAGN,IAAI,CAACL,EAAL,CAAQ1F,CAAC,CAAC+F,IAAI,CAACjD,GAAN,CAAT,CAAb;EACA,YAAMwD,IAAI,GAAGP,IAAI,CAACL,EAAL,CAAQzF,CAAC,CAAC8F,IAAI,CAACjD,GAAN,CAAT,CAAb,CAPiB;;EAUjB,UAAIuD,IAAI,KAAKE,SAAT,IAAsBD,IAAI,KAAKC,SAAnC,EAA8C;EAC5CJ,QAAAA,MAAM,GAAG,IAAT;EACA,eAAO,CAAP;EACD;;EAED,UAAIE,IAAI,GAAGC,IAAP,IAAeD,IAAI,KAAK,WAAxB,IAAuCC,IAAI,KAAK,UAApD,EAAgE;EAC9D,eAAO,CAAC,CAAR;EACD;;EAED,UAAID,IAAI,GAAGC,IAAP,IAAeD,IAAI,KAAK,UAAxB,IAAsCC,IAAI,KAAK,WAAnD,EAAgE;EAC9D,eAAO,CAAP;EACD;;EAED,aAAO,CAAP;EACD,KAxBD;EAyBD,GA1BD,MA0BO,IAAI,OAAOP,IAAI,CAACJ,OAAZ,KAAwB,UAA5B,EAAwC;EAC7CE,IAAAA,GAAG,CAACO,IAAJ,CAASL,IAAI,CAACJ,OAAd;EACD,GA3C0C;;;EA8C3C,MAAIQ,MAAJ,EAAY;EACV,WAAOH,QAAP;EACD;;EAED,MAAID,IAAI,CAACN,OAAT,EAAkB;EAChBI,IAAAA,GAAG,CAACJ,OAAJ;EACD;;EAED,SAAOI,GAAP;EACD;;ECpGD,MAAMW,WAAW,GAAG,EAApB;EACA,MAAMC,SAAS,GAAG,eAAlB;EACA,IAAIC,KAAK,GAAG,CAAZ;;EAEA,SAASC,QAAT,GAAoB;EAClBD,EAAAA,KAAK,IAAI,CAAT;EACA,SAAOD,SAAS,GAAGC,KAAnB;EACD;;EAEM,SAASE,mBAAT,CAA6BvG,EAA7B,EAAiC;EACtC,MAAImG,WAAW,CAACnG,EAAD,CAAf,EAAqB;EACnBmG,IAAAA,WAAW,CAACnG,EAAD,CAAX,CAAgBW,OAAhB,CAAwB6F,mBAAxB,CAA4CJ,SAA5C,EAAuDD,WAAW,CAACnG,EAAD,CAAX,CAAgByG,QAAvE;EACAN,IAAAA,WAAW,CAACnG,EAAD,CAAX,GAAkB,IAAlB;EACA,WAAO,IAAP;EACD;;EAED,SAAO,KAAP;EACD;EAEM,SAAS0G,eAAT,CAAyB/F,OAAzB,EAAkCgG,QAAlC,EAA4C;EACjD,QAAM3G,EAAE,GAAGsG,QAAQ,EAAnB;;EACA,QAAMG,QAAQ,GAAIG,GAAD,IAAS;EACxB,QAAIA,GAAG,CAACC,aAAJ,KAAsBD,GAAG,CAACE,MAA9B,EAAsC;EACpCP,MAAAA,mBAAmB,CAACvG,EAAD,CAAnB;EACA2G,MAAAA,QAAQ,CAACC,GAAD,CAAR;EACD;EACF,GALD;;EAOAjG,EAAAA,OAAO,CAACoG,gBAAR,CAAyBX,SAAzB,EAAoCK,QAApC;EAEAN,EAAAA,WAAW,CAACnG,EAAD,CAAX,GAAkB;EAAEW,IAAAA,OAAF;EAAW8F,IAAAA;EAAX,GAAlB;EAEA,SAAOzG,EAAP;EACD;;ECjCc,SAASgH,QAAT,CAAkBpC,KAAlB,EAAyB;EACtC,SAAOf,IAAI,CAACoD,GAAL,CAAS,GAAGrC,KAAZ,CAAP;EACD;;ECFc,SAASsC,QAAT,CAAkBtC,KAAlB,EAAyB;EACtC,SAAOf,IAAI,CAACsD,GAAL,CAAS,GAAGvC,KAAZ,CAAP;EACD;;ECGD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACO,SAASwC,aAAT,CAAuBC,SAAvB,EAAkCC,WAAlC,EAA+CC,OAA/C,EAAwDC,SAAxD,EAAmE;EACxE,MAAIC,UAAU,GAAGJ,SAAS,GAAGC,WAA7B,CADwE;EAIxE;EACA;;EACA,MAAIzD,IAAI,CAAC6D,GAAL,CAAS7D,IAAI,CAACC,KAAL,CAAW2D,UAAX,IAAyBA,UAAlC,IAAgDD,SAApD,EAA+D;EAC7D;EACAC,IAAAA,UAAU,GAAG5D,IAAI,CAACC,KAAL,CAAW2D,UAAX,CAAb;EACD,GATuE;;;EAYxE,SAAO5D,IAAI,CAACsD,GAAL,CAAStD,IAAI,CAAC8D,IAAL,CAAUF,UAAV,CAAT,EAAgCF,OAAhC,CAAP;EACD;EAED;EACA;EACA;EACA;EACA;EACA;;EACO,SAASK,qBAAT,CAA+BC,SAA/B,EAA0CJ,UAA1C,EAAsDF,OAAtD,EAA+D;EACpE;EACA,MAAIE,UAAU,KAAK,CAAnB,EAAsB;EACpB,WAAOI,SAAP;EACD,GAJmE;EAOpE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;EACA,QAAMC,SAAS,GAAG,EAAlB,CA5BoE;;EA+BpE,OAAK,IAAI/C,CAAC,GAAG,CAAb,EAAgBA,CAAC,IAAIwC,OAAO,GAAGE,UAA/B,EAA2C1C,CAAC,EAA5C,EAAgD;EAC9C;EACA+C,IAAAA,SAAS,CAACC,IAAV,CAAef,QAAQ,CAACa,SAAS,CAACG,KAAV,CAAgBjD,CAAhB,EAAmBA,CAAC,GAAG0C,UAAvB,CAAD,CAAvB;EACD;;EAED,SAAOK,SAAP;EACD;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACO,SAASG,cAAT,CAAwBJ,SAAxB,EAAmCK,MAAnC,EAA2C;EAChD,QAAMC,WAAW,GAAGjB,QAAQ,CAACW,SAAD,CAA5B;;EACA,OAAK,IAAI9C,CAAC,GAAG,CAAR,EAAWqD,GAAG,GAAGP,SAAS,CAAC/C,MAAhC,EAAwCC,CAAC,GAAGqD,GAA5C,EAAiDrD,CAAC,EAAlD,EAAsD;EACpD,QAAI8C,SAAS,CAAC9C,CAAD,CAAT,IAAgBoD,WAAW,GAAGD,MAA9B,IAAwCL,SAAS,CAAC9C,CAAD,CAAT,IAAgBoD,WAAW,GAAGD,MAA1E,EAAkF;EAChF,aAAOnD,CAAP;EACD;EACF;;EAED,SAAO,CAAP;EACD;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACO,SAASsD,eAAT,OAAsF;EAAA,MAA7D;EAAEC,IAAAA,QAAF;EAAYT,IAAAA,SAAZ;EAAuBU,IAAAA,QAAvB;EAAiCC,IAAAA,KAAjC;EAAwChB,IAAAA,SAAxC;EAAmDU,IAAAA;EAAnD,GAA6D;EAC3F,QAAMO,IAAI,GAAGrB,aAAa,CAACkB,QAAQ,CAACnI,KAAV,EAAiBoI,QAAjB,EAA2BC,KAA3B,EAAkChB,SAAlC,CAA1B;EACA,QAAMkB,IAAI,GAAGd,qBAAqB,CAACC,SAAD,EAAYY,IAAZ,EAAkBD,KAAlB,CAAlC;EACA,QAAMG,gBAAgB,GAAGV,cAAc,CAACS,IAAD,EAAOR,MAAP,CAAvC,CAH2F;;EAM3F,QAAMjG,KAAK,GAAG,IAAI3C,KAAJ,CAAUiJ,QAAQ,GAAGI,gBAArB,EAAuCD,IAAI,CAACC,gBAAD,CAA3C,CAAd,CAN2F;EAS3F;EACA;;EACA,QAAMC,SAAS,GAAGF,IAAI,CAACC,gBAAD,CAAJ,GAAyBL,QAAQ,CAAClI,MAApD;;EACA,OAAK,IAAI2E,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG0D,IAApB,EAA0B1D,CAAC,EAA3B,EAA+B;EAC7B8C,IAAAA,SAAS,CAACc,gBAAgB,GAAG5D,CAApB,CAAT,GAAkC6D,SAAlC;EACD;;EAED,SAAO3G,KAAP;EACD;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACO,SAAS4G,oBAAT,CAA8BC,SAA9B,EAAyCC,cAAzC,EAAyD;EAC9D,QAAMC,MAAM,GAAG,EAAf,CAD8D;EAI9D;EACA;;EACAF,EAAAA,SAAS,CAAC3G,OAAV,CAAmB8G,QAAD,IAAc;EAC9B,QAAID,MAAM,CAACC,QAAQ,CAAC/I,GAAV,CAAV,EAA0B;EACxB;EACA8I,MAAAA,MAAM,CAACC,QAAQ,CAAC/I,GAAV,CAAN,CAAqB6H,IAArB,CAA0BkB,QAA1B;EACD,KAHD,MAGO;EACL;EACAD,MAAAA,MAAM,CAACC,QAAQ,CAAC/I,GAAV,CAAN,GAAuB,CAAC+I,QAAD,CAAvB;EACD;EACF,GARD,EAN8D;EAiB9D;EACA;;EACA,MAAIC,KAAK,GAAG,EAAZ;EACA,QAAMC,IAAI,GAAG,EAAb;EACA,QAAMC,YAAY,GAAG,EAArB;EACA7G,EAAAA,MAAM,CAACC,IAAP,CAAYwG,MAAZ,EAAoB7G,OAApB,CAA6BM,GAAD,IAAS;EACnC,UAAMqG,SAAS,GAAGE,MAAM,CAACvG,GAAD,CAAxB;EACA0G,IAAAA,IAAI,CAACpB,IAAL,CAAUe,SAAV;EACA,UAAMO,QAAQ,GAAGP,SAAS,CAACA,SAAS,CAAChE,MAAV,GAAmB,CAApB,CAA1B;EACA,UAAMwE,GAAG,GAAGD,QAAQ,CAACpJ,IAAT,GAAgBoJ,QAAQ,CAAClJ,KAArC;EACA,UAAMoJ,MAAM,GAAG1F,IAAI,CAACC,KAAL,CAAW,CAACiF,cAAc,GAAGO,GAAlB,IAAyB,CAApC,CAAf;EAEA,QAAIE,UAAU,GAAGV,SAAjB;EACA,QAAIW,OAAO,GAAG,KAAd;;EACA,QAAIF,MAAM,GAAG,CAAb,EAAgB;EACd,YAAMG,QAAQ,GAAG,EAAjB;EACAD,MAAAA,OAAO,GAAGX,SAAS,CAACa,KAAV,CAAiBC,CAAD,IAAO;EAC/B,cAAMC,OAAO,GAAG,IAAIhK,IAAJ,CAAS+J,CAAC,CAAC3J,IAAF,GAASsJ,MAAlB,EAA0BK,CAAC,CAAC1J,GAA5B,EAAiC0J,CAAC,CAACzJ,KAAnC,EAA0CyJ,CAAC,CAACxJ,MAA5C,EAAoDwJ,CAAC,CAAC5J,EAAtD,CAAhB,CAD+B;;EAI/B,cAAM8J,SAAS,GAAG,CAACZ,KAAK,CAACa,IAAN,CAAYH,CAAD,IAAO/J,IAAI,CAACQ,UAAL,CAAgBwJ,OAAhB,EAAyBD,CAAzB,CAAlB,CAAnB;EAEAF,QAAAA,QAAQ,CAAC3B,IAAT,CAAc8B,OAAd;EACA,eAAOC,SAAP;EACD,OARS,CAAV,CAFc;;EAad,UAAIL,OAAJ,EAAa;EACXD,QAAAA,UAAU,GAAGE,QAAb;EACD;EACF,KAzBkC;EA4BnC;EACA;;;EACA,QAAI,CAACD,OAAL,EAAc;EACZ,UAAIO,gBAAJ;EACA,YAAMC,UAAU,GAAGnB,SAAS,CAACiB,IAAV,CAAgBd,QAAD,IAChCC,KAAK,CAACa,IAAN,CAAYH,CAAD,IAAO;EAChB,cAAMvJ,UAAU,GAAGR,IAAI,CAACQ,UAAL,CAAgB4I,QAAhB,EAA0BW,CAA1B,CAAnB;;EACA,YAAIvJ,UAAJ,EAAgB;EACd2J,UAAAA,gBAAgB,GAAGJ,CAAnB;EACD;;EACD,eAAOvJ,UAAP;EACD,OAND,CADiB,CAAnB,CAFY;;EAaZ,UAAI4J,UAAJ,EAAgB;EACd,cAAMC,QAAQ,GAAGd,YAAY,CAACe,SAAb,CAAwBC,KAAD,IAAWA,KAAK,CAACC,QAAN,CAAeL,gBAAf,CAAlC,CAAjB;EACAZ,QAAAA,YAAY,CAACkB,MAAb,CAAoBJ,QAApB,EAA8B,CAA9B,EAAiCf,IAAI,CAACe,QAAD,CAArC;EACD;EACF;;EAEDhB,IAAAA,KAAK,GAAGA,KAAK,CAACqB,MAAN,CAAaf,UAAb,CAAR;EACAJ,IAAAA,YAAY,CAACrB,IAAb,CAAkByB,UAAlB;EACD,GAnDD,EAtB8D;EA4E9D;EACA;EACA;;EACA,SAAOJ,YAAY,CAChBoB,IADI,GAEJzE,IAFI,CAEC,CAACpG,CAAD,EAAIC,CAAJ,KAAUD,CAAC,CAACK,EAAF,GAAOJ,CAAC,CAACI,EAFpB,EAGJyK,GAHI,CAGCxB,QAAD,IAAc,IAAI3J,KAAJ,CAAU2J,QAAQ,CAAChJ,IAAnB,EAAyBgJ,QAAQ,CAAC/I,GAAlC,CAHd,CAAP;EAID;;ECpND;EACA;EACA;EACA;EACA;EACA;EACe,SAASwK,SAAT,CAAmBC,GAAnB,EAAwB;EACrC,SAAOA,GAAG,CAACC,OAAJ,CAAY,UAAZ,EAAwB,CAACD,GAAD,EAAME,EAAN,KAAc,IAAGA,EAAE,CAACC,WAAH,EAAiB,EAA1D,CAAP;EACD;;ECOD,SAASC,WAAT,CAAqBvL,CAArB,EAAwB;EACtB,SAAOoG,KAAK,CAACC,IAAN,CAAW,IAAImF,GAAJ,CAAQxL,CAAR,CAAX,CAAP;EACD;;;EAGD,IAAIQ,EAAE,GAAG,CAAT;;EAEA,MAAMiL,OAAN,SAAsBC,WAAtB,CAAkC;EAChC;EACF;EACA;EACA;EACA;EACA;EACA;EACE3L,EAAAA,WAAW,CAACoB,OAAD,EAAwB;EAAA,QAAd8E,OAAc,uEAAJ,EAAI;EACjC;EACA,SAAKA,OAAL,GAAe,EAAE,GAAGwF,OAAO,CAACxF,OAAb;EAAsB,SAAGA;EAAzB,KAAf;EAEA,SAAK0F,QAAL,GAAgB,EAAhB;EACA,SAAKC,KAAL,GAAaH,OAAO,CAACI,SAArB;EACA,SAAKC,UAAL,GAAkBL,OAAO,CAACI,SAA1B;EACA,SAAKE,SAAL,GAAiB,IAAjB;EACA,SAAKC,WAAL,GAAmB,KAAnB;EACA,SAAKC,aAAL,GAAqB,KAArB;EACA,SAAKC,YAAL,GAAoB,EAApB;EACA,SAAKC,eAAL,GAAuB,KAAvB;EACA,SAAKC,MAAL,GAAc,EAAd;;EAEA,UAAMC,EAAE,GAAG,KAAKC,iBAAL,CAAuBnL,OAAvB,CAAX;;EAEA,QAAI,CAACkL,EAAL,EAAS;EACP,YAAM,IAAIE,SAAJ,CAAc,kDAAd,CAAN;EACD;;EAED,SAAKpL,OAAL,GAAekL,EAAf;EACA,SAAK7L,EAAL,GAAU,aAAaA,EAAvB;EACAA,IAAAA,EAAE,IAAI,CAAN;;EAEA,SAAKgM,KAAL;;EACA,SAAKP,aAAL,GAAqB,IAArB;EACD;;EAEDO,EAAAA,KAAK,GAAG;EACN,SAAK5B,KAAL,GAAa,KAAK6B,SAAL,EAAb;EACA,SAAKC,WAAL,GAAmB,KAAK9B,KAAxB;EAEA,SAAK3E,OAAL,CAAa0G,KAAb,GAAqB,KAAKL,iBAAL,CAAuB,KAAKrG,OAAL,CAAa0G,KAApC,CAArB,CAJM;;EAON,SAAKxL,OAAL,CAAaK,SAAb,CAAuBG,GAAvB,CAA2B8J,OAAO,CAAC/J,OAAR,CAAgBZ,IAA3C,EAPM;;EAUN,SAAK8L,UAAL,CAAgB,KAAKhC,KAArB,EAVM;;;EAaN,SAAKiC,SAAL,GAAiB,KAAKC,kBAAL,EAAjB;EACA3I,IAAAA,MAAM,CAACoD,gBAAP,CAAwB,QAAxB,EAAkC,KAAKsF,SAAvC,EAdM;EAiBN;EACA;;EACA,QAAIjJ,QAAQ,CAACmJ,UAAT,KAAwB,UAA5B,EAAwC;EACtC,YAAMC,MAAM,GAAG,KAAKA,MAAL,CAAYC,IAAZ,CAAiB,IAAjB,CAAf;EACA9I,MAAAA,MAAM,CAACoD,gBAAP,CAAwB,MAAxB,EAAgC,SAAS2F,MAAT,GAAkB;EAChD/I,QAAAA,MAAM,CAAC6C,mBAAP,CAA2B,MAA3B,EAAmCkG,MAAnC;EACAF,QAAAA,MAAM;EACP,OAHD;EAID,KAzBK;;;EA4BN,UAAMG,YAAY,GAAGhJ,MAAM,CAACC,gBAAP,CAAwB,KAAKjD,OAA7B,EAAsC,IAAtC,CAArB;EACA,UAAMoI,cAAc,GAAGkC,OAAO,CAAC2B,OAAR,CAAgB,KAAKjM,OAArB,EAA8BR,KAArD,CA7BM;;EAgCN,SAAK0M,eAAL,CAAqBF,YAArB,EAhCM;EAmCN;;;EACA,SAAKG,WAAL,CAAiB/D,cAAjB,EApCM;;;EAuCN,SAAKgE,MAAL,CAAY,KAAKtH,OAAL,CAAa2F,KAAzB,EAAgC,KAAK3F,OAAL,CAAauH,WAA7C,EAvCM;EA0CN;EACA;EACA;;EACA,SAAKrM,OAAL,CAAasM,WAAb,CA7CM;;EA8CN,SAAKC,kBAAL,CAAwB,KAAK9C,KAA7B;EACA,SAAKzJ,OAAL,CAAa+B,KAAb,CAAmByK,UAAnB,GAAiC,UAAS,KAAK1H,OAAL,CAAa2H,KAAM,MAAK,KAAK3H,OAAL,CAAa4H,MAAO,EAAtF;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEf,EAAAA,kBAAkB,GAAG;EACnB,UAAMgB,cAAc,GAAG,KAAKC,aAAL,CAAmBd,IAAnB,CAAwB,IAAxB,CAAvB;;EACA,WAAO,KAAKhH,OAAL,CAAa+H,QAAb,GAAwB,KAAK/H,OAAL,CAAa+H,QAAb,CAAsBF,cAAtB,EAAsC,KAAK7H,OAAL,CAAagI,YAAnD,CAAxB,GAA2FH,cAAlG;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACExB,EAAAA,iBAAiB,CAAC4B,MAAD,EAAS;EACxB;EACA;EACA,QAAI,OAAOA,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,aAAO,KAAK/M,OAAL,CAAagN,aAAb,CAA2BD,MAA3B,CAAP;EACD,KALuB;;;EAQxB,QAAIA,MAAM,IAAIA,MAAM,CAACE,QAAjB,IAA6BF,MAAM,CAACE,QAAP,KAAoB,CAArD,EAAwD;EACtD,aAAOF,MAAP;EACD,KAVuB;;;EAaxB,QAAIA,MAAM,IAAIA,MAAM,CAACG,MAArB,EAA6B;EAC3B,aAAOH,MAAM,CAAC,CAAD,CAAb;EACD;;EAED,WAAO,IAAP;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEb,EAAAA,eAAe,CAAC5I,MAAD,EAAS;EACtB;EACA,QAAIA,MAAM,CAACrB,QAAP,KAAoB,QAAxB,EAAkC;EAChC,WAAKjC,OAAL,CAAa+B,KAAb,CAAmBE,QAAnB,GAA8B,UAA9B;EACD,KAJqB;;;EAOtB,QAAIqB,MAAM,CAAC6J,QAAP,KAAoB,QAAxB,EAAkC;EAChC,WAAKnN,OAAL,CAAa+B,KAAb,CAAmBoL,QAAnB,GAA8B,QAA9B;EACD;EACF;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;EACEC,EAAAA,OAAO,GAAsD;EAAA,QAArDC,QAAqD,uEAA1C,KAAK1C,UAAqC;EAAA,QAAzB2C,UAAyB,uEAAZ,KAAK7D,KAAO;;EAC3D,UAAM8D,GAAG,GAAG,KAAKC,gBAAL,CAAsBH,QAAtB,EAAgCC,UAAhC,CAAZ,CAD2D;;;EAI3D,SAAKG,oBAAL,CAA0BF,GAA1B,EAJ2D;;;EAO3D,SAAK5C,UAAL,GAAkB0C,QAAlB,CAP2D;EAU3D;;EACA,QAAI,OAAOA,QAAP,KAAoB,QAAxB,EAAkC;EAChC,WAAK5C,KAAL,GAAa4C,QAAb;EACD;;EAED,WAAOE,GAAP;EACD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACEC,EAAAA,gBAAgB,CAACH,QAAD,EAAW5D,KAAX,EAAkB;EAChC,QAAIiE,OAAO,GAAG,EAAd;EACA,UAAMC,MAAM,GAAG,EAAf,CAFgC;;EAKhC,QAAIN,QAAQ,KAAK/C,OAAO,CAACI,SAAzB,EAAoC;EAClCgD,MAAAA,OAAO,GAAGjE,KAAV,CADkC;EAIlC;EACD,KALD,MAKO;EACLA,MAAAA,KAAK,CAACjI,OAAN,CAAeoM,IAAD,IAAU;EACtB,YAAI,KAAKC,eAAL,CAAqBR,QAArB,EAA+BO,IAAI,CAAC5N,OAApC,CAAJ,EAAkD;EAChD0N,UAAAA,OAAO,CAACtG,IAAR,CAAawG,IAAb;EACD,SAFD,MAEO;EACLD,UAAAA,MAAM,CAACvG,IAAP,CAAYwG,IAAZ;EACD;EACF,OAND;EAOD;;EAED,WAAO;EACLF,MAAAA,OADK;EAELC,MAAAA;EAFK,KAAP;EAID;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACEE,EAAAA,eAAe,CAACR,QAAD,EAAWrN,OAAX,EAAoB;EACjC,QAAI,OAAOqN,QAAP,KAAoB,UAAxB,EAAoC;EAClC,aAAOA,QAAQ,CAACS,IAAT,CAAc9N,OAAd,EAAuBA,OAAvB,EAAgC,IAAhC,CAAP;EACD,KAHgC;;;EAMjC,UAAM+N,IAAI,GAAG/N,OAAO,CAACgO,YAAR,CAAqB,UAAU1D,OAAO,CAAC2D,oBAAvC,CAAb;EACA,UAAMpM,IAAI,GAAG,KAAKiD,OAAL,CAAaoJ,SAAb,GAAyBH,IAAI,CAACI,KAAL,CAAW,KAAKrJ,OAAL,CAAaoJ,SAAxB,CAAzB,GAA8DE,IAAI,CAACC,KAAL,CAAWN,IAAX,CAA3E;;EAEA,aAASO,YAAT,CAAsBjB,QAAtB,EAAgC;EAC9B,aAAOxL,IAAI,CAAC6H,QAAL,CAAc2D,QAAd,CAAP;EACD;;EAED,QAAIpI,KAAK,CAACsJ,OAAN,CAAclB,QAAd,CAAJ,EAA6B;EAC3B,UAAI,KAAKvI,OAAL,CAAa0J,UAAb,KAA4BlE,OAAO,CAACmE,UAAR,CAAmBC,GAAnD,EAAwD;EACtD,eAAOrB,QAAQ,CAACjE,IAAT,CAAckF,YAAd,CAAP;EACD;;EACD,aAAOjB,QAAQ,CAACrE,KAAT,CAAesF,YAAf,CAAP;EACD;;EAED,WAAOzM,IAAI,CAAC6H,QAAL,CAAc2D,QAAd,CAAP;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEI,EAAAA,oBAAoB,OAAsB;EAAA,QAArB;EAAEC,MAAAA,OAAF;EAAWC,MAAAA;EAAX,KAAqB;EACxCD,IAAAA,OAAO,CAAClM,OAAR,CAAiBoM,IAAD,IAAU;EACxBA,MAAAA,IAAI,CAACxN,IAAL;EACD,KAFD;EAIAuN,IAAAA,MAAM,CAACnM,OAAP,CAAgBoM,IAAD,IAAU;EACvBA,MAAAA,IAAI,CAAClN,IAAL;EACD,KAFD;EAGD;EAED;EACF;EACA;EACA;EACA;;;EACE+K,EAAAA,UAAU,CAAChC,KAAD,EAAQ;EAChBA,IAAAA,KAAK,CAACjI,OAAN,CAAeoM,IAAD,IAAU;EACtBA,MAAAA,IAAI,CAAChN,IAAL;EACD,KAFD;EAGD;EAED;EACF;EACA;EACA;EACA;;;EACE+N,EAAAA,aAAa,CAAClF,KAAD,EAAQ;EACnBA,IAAAA,KAAK,CAACjI,OAAN,CAAeoM,IAAD,IAAU;EACtBA,MAAAA,IAAI,CAAC5L,OAAL;EACD,KAFD;EAGD;EAED;EACF;EACA;EACA;;;EACE4M,EAAAA,gBAAgB,GAAG;EACjB,SAAKC,YAAL,GAAoB,KAAKC,iBAAL,GAAyB3K,MAA7C;EACD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACEoI,EAAAA,kBAAkB,CAAC9C,KAAD,EAAQ;EACxB,UAAM;EAAEgD,MAAAA,KAAF;EAASC,MAAAA;EAAT,QAAoB,KAAK5H,OAA/B;EACA,UAAMiK,aAAa,GAAG,KAAKjK,OAAL,CAAakK,aAAb,GAA6B,CAAC,WAAD,CAA7B,GAA6C,CAAC,KAAD,EAAQ,MAAR,CAAnE,CAFwB;EAKxB;;EACA,UAAMC,QAAQ,GAAGrN,MAAM,CAACC,IAAP,CAAY9B,WAAW,CAACgB,GAAZ,CAAgBjB,MAAhB,CAAuBuC,MAAnC,EAA2CyH,GAA3C,CAAgDoF,CAAD,IAAOnF,SAAS,CAACmF,CAAD,CAA/D,CAAjB;EACA,UAAMC,UAAU,GAAGJ,aAAa,CAACnF,MAAd,CAAqBqF,QAArB,EAA+BG,IAA/B,EAAnB;EAEA3F,IAAAA,KAAK,CAACjI,OAAN,CAAeoM,IAAD,IAAU;EACtBA,MAAAA,IAAI,CAAC5N,OAAL,CAAa+B,KAAb,CAAmBsN,kBAAnB,GAAwC5C,KAAK,GAAG,IAAhD;EACAmB,MAAAA,IAAI,CAAC5N,OAAL,CAAa+B,KAAb,CAAmBuN,wBAAnB,GAA8C5C,MAA9C;EACAkB,MAAAA,IAAI,CAAC5N,OAAL,CAAa+B,KAAb,CAAmBwN,kBAAnB,GAAwCJ,UAAxC;EACD,KAJD;EAKD;;EAED7D,EAAAA,SAAS,GAAG;EACV,WAAOrG,KAAK,CAACC,IAAN,CAAW,KAAKlF,OAAL,CAAawP,QAAxB,EACJpD,MADI,CACIlB,EAAD,IAAQA,EAAE,CAACuE,OAAH,CAAW,KAAK3K,OAAL,CAAa4K,YAAxB,CADX,EAEJ5F,GAFI,CAECoB,EAAD,IAAQ,IAAInL,WAAJ,CAAgBmL,EAAhB,EAAoB,KAAKpG,OAAL,CAAa7E,KAAjC,CAFR,CAAP;EAGD;EAED;EACF;EACA;EACA;EACA;;;EACE0P,EAAAA,cAAc,CAAClG,KAAD,EAAQ;EACpB,UAAM+F,QAAQ,GAAGvK,KAAK,CAACC,IAAN,CAAW,KAAKlF,OAAL,CAAawP,QAAxB,CAAjB;EACA,WAAO5K,MAAM,CAAC,KAAK6E,KAAL,CAAWG,MAAX,CAAkBH,KAAlB,CAAD,EAA2B;EACtC/E,MAAAA,EAAE,CAAC1E,OAAD,EAAU;EACV,eAAOwP,QAAQ,CAACI,OAAT,CAAiB5P,OAAjB,CAAP;EACD;;EAHqC,KAA3B,CAAb;EAKD;;EAED8O,EAAAA,iBAAiB,GAAG;EAClB,WAAO,KAAKrF,KAAL,CAAW2C,MAAX,CAAmBwB,IAAD,IAAUA,IAAI,CAAC1N,SAAjC,CAAP;EACD;;EAED2P,EAAAA,kBAAkB,GAAG;EACnB,WAAO,KAAKpG,KAAL,CAAW2C,MAAX,CAAmBwB,IAAD,IAAU,CAACA,IAAI,CAAC1N,SAAlC,CAAP;EACD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACE4P,EAAAA,cAAc,CAAC1H,cAAD,EAAiB2H,UAAjB,EAA6B;EACzC,QAAIC,IAAJ,CADyC;;EAIzC,QAAI,OAAO,KAAKlL,OAAL,CAAa6B,WAApB,KAAoC,UAAxC,EAAoD;EAClDqJ,MAAAA,IAAI,GAAG,KAAKlL,OAAL,CAAa6B,WAAb,CAAyByB,cAAzB,CAAP,CADkD;EAInD,KAJD,MAIO,IAAI,KAAKtD,OAAL,CAAa0G,KAAjB,EAAwB;EAC7BwE,MAAAA,IAAI,GAAG1F,OAAO,CAAC2B,OAAR,CAAgB,KAAKnH,OAAL,CAAa0G,KAA7B,EAAoChM,KAA3C,CAD6B;EAI9B,KAJM,MAIA,IAAI,KAAKsF,OAAL,CAAa6B,WAAjB,EAA8B;EACnCqJ,MAAAA,IAAI,GAAG,KAAKlL,OAAL,CAAa6B,WAApB,CADmC;EAIpC,KAJM,MAIA,IAAI,KAAK8C,KAAL,CAAWtF,MAAX,GAAoB,CAAxB,EAA2B;EAChC6L,MAAAA,IAAI,GAAG1F,OAAO,CAAC2B,OAAR,CAAgB,KAAKxC,KAAL,CAAW,CAAX,EAAczJ,OAA9B,EAAuC,IAAvC,EAA6CR,KAApD,CADgC;EAIjC,KAJM,MAIA;EACLwQ,MAAAA,IAAI,GAAG5H,cAAP;EACD,KAtBwC;;;EAyBzC,QAAI4H,IAAI,KAAK,CAAb,EAAgB;EACdA,MAAAA,IAAI,GAAG5H,cAAP;EACD;;EAED,WAAO4H,IAAI,GAAGD,UAAd;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACEE,EAAAA,cAAc,CAAC7H,cAAD,EAAiB;EAC7B,QAAI4H,IAAJ;;EACA,QAAI,OAAO,KAAKlL,OAAL,CAAaoL,WAApB,KAAoC,UAAxC,EAAoD;EAClDF,MAAAA,IAAI,GAAG,KAAKlL,OAAL,CAAaoL,WAAb,CAAyB9H,cAAzB,CAAP;EACD,KAFD,MAEO,IAAI,KAAKtD,OAAL,CAAa0G,KAAjB,EAAwB;EAC7BwE,MAAAA,IAAI,GAAG3M,cAAc,CAAC,KAAKyB,OAAL,CAAa0G,KAAd,EAAqB,YAArB,CAArB;EACD,KAFM,MAEA;EACLwE,MAAAA,IAAI,GAAG,KAAKlL,OAAL,CAAaoL,WAApB;EACD;;EAED,WAAOF,IAAP;EACD;EAED;EACF;EACA;EACA;EACA;;;EACE7D,EAAAA,WAAW,GAAuD;EAAA,QAAtD/D,cAAsD,uEAArCkC,OAAO,CAAC2B,OAAR,CAAgB,KAAKjM,OAArB,EAA8BR,KAAO;;EAChE,UAAM2Q,MAAM,GAAG,KAAKF,cAAL,CAAoB7H,cAApB,CAAf;;EACA,UAAMzB,WAAW,GAAG,KAAKmJ,cAAL,CAAoB1H,cAApB,EAAoC+H,MAApC,CAApB;;EACA,QAAIC,iBAAiB,GAAG,CAAChI,cAAc,GAAG+H,MAAlB,IAA4BxJ,WAApD,CAHgE;;EAMhE,QAAIzD,IAAI,CAAC6D,GAAL,CAAS7D,IAAI,CAACC,KAAL,CAAWiN,iBAAX,IAAgCA,iBAAzC,IAA8D,KAAKtL,OAAL,CAAauL,eAA/E,EAAgG;EAC9F;EACAD,MAAAA,iBAAiB,GAAGlN,IAAI,CAACC,KAAL,CAAWiN,iBAAX,CAApB;EACD;;EAED,SAAKE,IAAL,GAAYpN,IAAI,CAACoD,GAAL,CAASpD,IAAI,CAACmB,KAAL,CAAW+L,iBAAiB,IAAI,CAAhC,CAAT,EAA6C,CAA7C,CAAZ;EACA,SAAKhI,cAAL,GAAsBA,cAAtB;EACA,SAAKmI,QAAL,GAAgB5J,WAAhB;EACD;EAED;EACF;EACA;;;EACE6J,EAAAA,iBAAiB,GAAG;EAClB,SAAKxQ,OAAL,CAAa+B,KAAb,CAAmBtC,MAAnB,GAA4B,KAAKgR,iBAAL,KAA2B,IAAvD;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEA,EAAAA,iBAAiB,GAAG;EAClB,WAAOpK,QAAQ,CAAC,KAAKa,SAAN,CAAf;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEwJ,EAAAA,iBAAiB,CAACC,KAAD,EAAQ;EACvB,WAAOzN,IAAI,CAACsD,GAAL,CAASmK,KAAK,GAAG,KAAK7L,OAAL,CAAa8L,aAA9B,EAA6C,KAAK9L,OAAL,CAAa+L,gBAA1D,CAAP;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEC,EAAAA,SAAS,CAACC,IAAD,EAAkB;EAAA,QAAXC,IAAW,uEAAJ,EAAI;;EACzB,QAAI,KAAKnG,WAAT,EAAsB;EACpB;EACD;;EAEDmG,IAAAA,IAAI,CAACC,OAAL,GAAe,IAAf;EACA,SAAKC,IAAL,CAAUH,IAAV,EAAgBC,IAAhB;EACD;EAED;EACF;EACA;EACA;;;EACEG,EAAAA,UAAU,GAAG;EACX,QAAI/M,CAAC,GAAG,KAAKkM,IAAb;EACA,SAAKpJ,SAAL,GAAiB,EAAjB;;EACA,WAAO9C,CAAP,EAAU;EACRA,MAAAA,CAAC,IAAI,CAAL;EACA,WAAK8C,SAAL,CAAeE,IAAf,CAAoB,CAApB;EACD;EACF;EAED;EACF;EACA;EACA;EACA;;;EACEgK,EAAAA,OAAO,CAAC3H,KAAD,EAAQ;EACb,UAAM4H,aAAa,GAAG,KAAKC,iBAAL,CAAuB7H,KAAvB,CAAtB;;EAEA,QAAI/D,KAAK,GAAG,CAAZ;EACA+D,IAAAA,KAAK,CAACjI,OAAN,CAAc,CAACoM,IAAD,EAAOxJ,CAAP,KAAa;EACzB,eAAS4B,QAAT,GAAoB;EAClB4H,QAAAA,IAAI,CAAC9M,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBlB,OAAhB,CAAwB0C,KAAtC;EACD,OAHwB;EAMzB;;;EACA,UAAI5D,KAAK,CAACI,MAAN,CAAa6O,IAAI,CAACtM,KAAlB,EAAyB+P,aAAa,CAACjN,CAAD,CAAtC,KAA8C,CAACwJ,IAAI,CAACzN,QAAxD,EAAkE;EAChEyN,QAAAA,IAAI,CAAC9M,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBlB,OAAhB,CAAwBwC,MAAtC;EACA2D,QAAAA,QAAQ;EACR;EACD;;EAED4H,MAAAA,IAAI,CAACtM,KAAL,GAAa+P,aAAa,CAACjN,CAAD,CAA1B;EACAwJ,MAAAA,IAAI,CAACxM,KAAL,GAAarB,WAAW,CAACsB,KAAZ,CAAkBxB,OAA/B;EACA+N,MAAAA,IAAI,CAACzN,QAAL,GAAgB,KAAhB,CAfyB;EAkBzB;;EACA,YAAMmD,MAAM,GAAG,KAAKiO,sBAAL,CAA4B3D,IAA5B,EAAkC7N,WAAW,CAACgB,GAAZ,CAAgBlB,OAAhB,CAAwBwC,MAA1D,CAAf;EACAiB,MAAAA,MAAM,CAACd,eAAP,GAAyB,KAAKkO,iBAAL,CAAuBhL,KAAvB,IAAgC,IAAzD;;EAEA,WAAKuF,MAAL,CAAY7D,IAAZ,CAAiB;EACfwG,QAAAA,IADe;EAEftK,QAAAA,MAFe;EAGf0C,QAAAA;EAHe,OAAjB;;EAMAN,MAAAA,KAAK,IAAI,CAAT;EACD,KA7BD;EA8BD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACE4L,EAAAA,iBAAiB,CAAC7H,KAAD,EAAQ;EACvB;EACA;EACA,QAAI,KAAK3E,OAAL,CAAa0M,UAAjB,EAA6B;EAC3B,YAAMC,SAAS,GAAGhI,KAAK,CAACK,GAAN,CAAU,CAAC8D,IAAD,EAAOxJ,CAAP,KAAa;EACvC,cAAMuD,QAAQ,GAAG2C,OAAO,CAAC2B,OAAR,CAAgB2B,IAAI,CAAC5N,OAArB,EAA8B,IAA9B,CAAjB;;EACA,cAAMsB,KAAK,GAAG,KAAKoQ,gBAAL,CAAsB/J,QAAtB,CAAd;;EACA,eAAO,IAAIzI,IAAJ,CAASoC,KAAK,CAACzC,CAAf,EAAkByC,KAAK,CAACxC,CAAxB,EAA2B6I,QAAQ,CAACnI,KAApC,EAA2CmI,QAAQ,CAAClI,MAApD,EAA4D2E,CAA5D,CAAP;EACD,OAJiB,CAAlB;EAMA,aAAO,KAAKuN,uBAAL,CAA6BF,SAA7B,EAAwC,KAAKrJ,cAA7C,CAAP;EACD,KAXsB;EAcvB;;;EACA,WAAOqB,KAAK,CAACK,GAAN,CAAW8D,IAAD,IAAU,KAAK8D,gBAAL,CAAsBpH,OAAO,CAAC2B,OAAR,CAAgB2B,IAAI,CAAC5N,OAArB,EAA8B,IAA9B,CAAtB,CAApB,CAAP;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACE0R,EAAAA,gBAAgB,CAAC/J,QAAD,EAAW;EACzB,WAAOD,eAAe,CAAC;EACrBC,MAAAA,QADqB;EAErBT,MAAAA,SAAS,EAAE,KAAKA,SAFK;EAGrBU,MAAAA,QAAQ,EAAE,KAAK2I,QAHM;EAIrB1I,MAAAA,KAAK,EAAE,KAAKyI,IAJS;EAKrBzJ,MAAAA,SAAS,EAAE,KAAK/B,OAAL,CAAauL,eALH;EAMrB9I,MAAAA,MAAM,EAAE,KAAKzC,OAAL,CAAayC;EANA,KAAD,CAAtB;EAQD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACEoK,EAAAA,uBAAuB,CAACxJ,SAAD,EAAYC,cAAZ,EAA4B;EACjD,WAAOF,oBAAoB,CAACC,SAAD,EAAYC,cAAZ,CAA3B;EACD;EAED;EACF;EACA;EACA;EACA;;;EACEwJ,EAAAA,OAAO,GAAyC;EAAA,QAAxCtE,UAAwC,uEAA3B,KAAKuC,kBAAL,EAA2B;EAC9C,QAAInK,KAAK,GAAG,CAAZ;EACA4H,IAAAA,UAAU,CAAC9L,OAAX,CAAoBoM,IAAD,IAAU;EAC3B,eAAS5H,QAAT,GAAoB;EAClB4H,QAAAA,IAAI,CAAC9M,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBjB,MAAhB,CAAuByC,KAArC;EACD,OAH0B;EAM3B;EACA;EACA;EACA;EACA;;;EACA,UAAIqL,IAAI,CAACzN,QAAT,EAAmB;EACjByN,QAAAA,IAAI,CAAC9M,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBjB,MAAhB,CAAuBuC,MAArC;EACA2D,QAAAA,QAAQ;EACR;EACD;;EAED4H,MAAAA,IAAI,CAACxM,KAAL,GAAarB,WAAW,CAACsB,KAAZ,CAAkBvB,MAA/B;EACA8N,MAAAA,IAAI,CAACzN,QAAL,GAAgB,IAAhB;EAEA,YAAMmD,MAAM,GAAG,KAAKiO,sBAAL,CAA4B3D,IAA5B,EAAkC7N,WAAW,CAACgB,GAAZ,CAAgBjB,MAAhB,CAAuBuC,MAAzD,CAAf;EACAiB,MAAAA,MAAM,CAACd,eAAP,GAAyB,KAAKkO,iBAAL,CAAuBhL,KAAvB,IAAgC,IAAzD;;EAEA,WAAKuF,MAAL,CAAY7D,IAAZ,CAAiB;EACfwG,QAAAA,IADe;EAEftK,QAAAA,MAFe;EAGf0C,QAAAA;EAHe,OAAjB;;EAMAN,MAAAA,KAAK,IAAI,CAAT;EACD,KA9BD;EA+BD;EAED;EACF;EACA;EACA;;;EACEkH,EAAAA,aAAa,GAAG;EACd;EACA,QAAI,CAAC,KAAKhC,SAAN,IAAmB,KAAKC,WAA5B,EAAyC;EACvC;EACD;;EAED,SAAKgH,MAAL;EACD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;;;EACEN,EAAAA,sBAAsB,CAAC3D,IAAD,EAAOkE,WAAP,EAAoB;EACxC;EACA,UAAMxO,MAAM,GAAG,EAAE,GAAGwO;EAAL,KAAf;;EAEA,QAAI,KAAKhN,OAAL,CAAakK,aAAjB,EAAgC;EAC9B,YAAM+C,IAAI,GAAG,KAAKjN,OAAL,CAAa7E,KAAb,GAAqB,GAArB,GAA2B,EAAxC;EACA,YAAMpB,CAAC,GAAG,KAAKiG,OAAL,CAAakN,eAAb,GAA+B9O,IAAI,CAACC,KAAL,CAAWyK,IAAI,CAACtM,KAAL,CAAWzC,CAAtB,CAA/B,GAA0D+O,IAAI,CAACtM,KAAL,CAAWzC,CAA/E;EACA,YAAMC,CAAC,GAAG,KAAKgG,OAAL,CAAakN,eAAb,GAA+B9O,IAAI,CAACC,KAAL,CAAWyK,IAAI,CAACtM,KAAL,CAAWxC,CAAtB,CAA/B,GAA0D8O,IAAI,CAACtM,KAAL,CAAWxC,CAA/E;EACAwE,MAAAA,MAAM,CAAC2O,SAAP,GAAoB,aAAYF,IAAK,GAAElT,CAAE,OAAMC,CAAE,aAAY8O,IAAI,CAACxM,KAAM,GAAxE;EACD,KALD,MAKO;EACL,UAAI,KAAK0D,OAAL,CAAa7E,KAAjB,EAAwB;EACtBqD,QAAAA,MAAM,CAAClB,KAAP,GAAewL,IAAI,CAACtM,KAAL,CAAWzC,CAAX,GAAe,IAA9B;EACD,OAFD,MAEO;EACLyE,QAAAA,MAAM,CAAChE,IAAP,GAAcsO,IAAI,CAACtM,KAAL,CAAWzC,CAAX,GAAe,IAA7B;EACD;;EACDyE,MAAAA,MAAM,CAAC/D,GAAP,GAAaqO,IAAI,CAACtM,KAAL,CAAWxC,CAAX,GAAe,IAA5B;EACD;;EAED,WAAOwE,MAAP;EACD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACE4O,EAAAA,mBAAmB,CAAClS,OAAD,EAAUmS,YAAV,EAAwBC,IAAxB,EAA8B;EAC/C,UAAM/S,EAAE,GAAG0G,eAAe,CAAC/F,OAAD,EAAWiG,GAAD,IAAS;EAC3CkM,MAAAA,YAAY;EACZC,MAAAA,IAAI,CAAC,IAAD,EAAOnM,GAAP,CAAJ;EACD,KAHyB,CAA1B;;EAKA,SAAK8E,YAAL,CAAkB3D,IAAlB,CAAuB/H,EAAvB;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACEgT,EAAAA,sBAAsB,CAACtN,IAAD,EAAO;EAC3B,WAAQqN,IAAD,IAAU;EACfrN,MAAAA,IAAI,CAAC6I,IAAL,CAAU9M,QAAV,CAAmBiE,IAAI,CAACzB,MAAxB;;EACA,WAAK4O,mBAAL,CAAyBnN,IAAI,CAAC6I,IAAL,CAAU5N,OAAnC,EAA4C+E,IAAI,CAACiB,QAAjD,EAA2DoM,IAA3D;EACD,KAHD;EAID;EAED;EACF;EACA;EACA;EACA;;;EACEE,EAAAA,aAAa,GAAG;EACd,QAAI,KAAKtH,eAAT,EAA0B;EACxB,WAAKuH,eAAL;EACD;;EAED,UAAMC,QAAQ,GAAG,KAAK1N,OAAL,CAAa2H,KAAb,GAAqB,CAAtC;EACA,UAAMgG,QAAQ,GAAG,KAAKxH,MAAL,CAAY9G,MAAZ,GAAqB,CAAtC;;EAEA,QAAIsO,QAAQ,IAAID,QAAZ,IAAwB,KAAK1H,aAAjC,EAAgD;EAC9C,WAAK4H,iBAAL,CAAuB,KAAKzH,MAA5B;EACD,KAFD,MAEO,IAAIwH,QAAJ,EAAc;EACnB,WAAKE,iBAAL,CAAuB,KAAK1H,MAA5B;;EACA,WAAK6F,SAAL,CAAexG,OAAO,CAACsI,SAAR,CAAkBC,MAAjC,EAFmB;EAKnB;EACA;;EACD,KAPM,MAOA;EACL,WAAK/B,SAAL,CAAexG,OAAO,CAACsI,SAAR,CAAkBC,MAAjC;EACD,KAnBa;;;EAsBd,SAAK5H,MAAL,CAAY9G,MAAZ,GAAqB,CAArB;EACD;EAED;EACF;EACA;EACA;;;EACEuO,EAAAA,iBAAiB,CAAClN,WAAD,EAAc;EAC7B;EACA,SAAKwF,eAAL,GAAuB,IAAvB,CAF6B;;EAK7B,UAAM8H,SAAS,GAAGtN,WAAW,CAACsE,GAAZ,CAAiBnI,GAAD,IAAS,KAAK0Q,sBAAL,CAA4B1Q,GAA5B,CAAzB,CAAlB;EAEAoR,IAAAA,aAAQ,CAACD,SAAD,EAAY,KAAKE,iBAAL,CAAuBlH,IAAvB,CAA4B,IAA5B,CAAZ,CAAR;EACD;;EAEDyG,EAAAA,eAAe,GAAG;EAChB;EACA,SAAKxH,YAAL,CAAkBvJ,OAAlB,CAA0BoE,mBAA1B,EAFgB;;;EAKhB,SAAKmF,YAAL,CAAkB5G,MAAlB,GAA2B,CAA3B,CALgB;;EAQhB,SAAK6G,eAAL,GAAuB,KAAvB;EACD;EAED;EACF;EACA;EACA;EACA;;;EACE2H,EAAAA,iBAAiB,CAACM,OAAD,EAAU;EACzB,QAAIA,OAAO,CAAC9O,MAAZ,EAAoB;EAClB,YAAM+O,QAAQ,GAAGD,OAAO,CAACnJ,GAAR,CAAanI,GAAD,IAASA,GAAG,CAACiM,IAAJ,CAAS5N,OAA9B,CAAjB;;EAEAsK,MAAAA,OAAO,CAAC6I,gBAAR,CAAyBD,QAAzB,EAAmC,MAAM;EACvCD,QAAAA,OAAO,CAACzR,OAAR,CAAiBG,GAAD,IAAS;EACvBA,UAAAA,GAAG,CAACiM,IAAJ,CAAS9M,QAAT,CAAkBa,GAAG,CAAC2B,MAAtB;EACA3B,UAAAA,GAAG,CAACqE,QAAJ;EACD,SAHD;EAID,OALD;EAMD;EACF;;EAEDgN,EAAAA,iBAAiB,GAAG;EAClB,SAAKjI,YAAL,CAAkB5G,MAAlB,GAA2B,CAA3B;EACA,SAAK6G,eAAL,GAAuB,KAAvB;;EACA,SAAK8F,SAAL,CAAexG,OAAO,CAACsI,SAAR,CAAkBC,MAAjC;EACD;EAED;EACF;EACA;EACA;EACA;EACA;;;EACEzG,EAAAA,MAAM,CAACiB,QAAD,EAAW+F,WAAX,EAAwB;EAC5B,QAAI,CAAC,KAAKxI,SAAV,EAAqB;EACnB;EACD;;EAED,QAAI,CAACyC,QAAD,IAAcA,QAAQ,IAAIA,QAAQ,CAAClJ,MAAT,KAAoB,CAAlD,EAAsD;EACpDkJ,MAAAA,QAAQ,GAAG/C,OAAO,CAACI,SAAnB,CADoD;EAErD;;EAED,SAAK0C,OAAL,CAAaC,QAAb,EAT4B;;;EAY5B,SAAKuE,OAAL,GAZ4B;;;EAe5B,SAAKhD,gBAAL,GAf4B;;;EAkB5B,SAAKxJ,IAAL,CAAUgO,WAAV;EACD;EAED;EACF;EACA;EACA;;;EACEhO,EAAAA,IAAI,GAA8B;EAAA,QAA7BgO,WAA6B,uEAAf,KAAK5I,QAAU;;EAChC,QAAI,CAAC,KAAKI,SAAV,EAAqB;EACnB;EACD;;EAED,SAAKuG,UAAL;;EAEA,UAAM1H,KAAK,GAAG7E,MAAM,CAAC,KAAKkK,iBAAL,EAAD,EAA2BsE,WAA3B,CAApB;EACA,SAAK7H,WAAL,GAAmB9B,KAAnB;;EAEA,SAAK2H,OAAL,CAAa3H,KAAb,EAVgC;EAahC;;;EACA,SAAK6I,aAAL,GAdgC;;;EAiBhC,SAAK9B,iBAAL;;EAEA,SAAKhG,QAAL,GAAgB4I,WAAhB;EACD;EAED;EACF;EACA;EACA;;;EACEvB,EAAAA,MAAM,GAAuB;EAAA,QAAtBwB,YAAsB,uEAAP,KAAO;;EAC3B,QAAI,KAAKzI,SAAT,EAAoB;EAClB,UAAI,CAACyI,YAAL,EAAmB;EACjB;EACA,aAAKlH,WAAL;EACD,OAJiB;;;EAOlB,WAAK/G,IAAL;EACD;EACF;EAED;EACF;EACA;EACA;EACA;;;EACEyG,EAAAA,MAAM,GAAG;EACP,SAAKgG,MAAL,CAAY,IAAZ;EACD;EAED;EACF;EACA;EACA;EACA;;;EACErR,EAAAA,GAAG,CAAC8S,QAAD,EAAW;EACZ,UAAM7J,KAAK,GAAGW,WAAW,CAACkJ,QAAD,CAAX,CAAsBxJ,GAAtB,CAA2BoB,EAAD,IAAQ,IAAInL,WAAJ,CAAgBmL,EAAhB,EAAoB,KAAKpG,OAAL,CAAa7E,KAAjC,CAAlC,CAAd,CADY;;EAIZ,SAAKwL,UAAL,CAAgBhC,KAAhB,EAJY;;;EAOZ,SAAK0H,UAAL;;EAEA,UAAMoC,QAAQ,GAAG,KAAK5D,cAAL,CAAoBlG,KAApB,CAAjB;;EACA,UAAM8B,WAAW,GAAG3G,MAAM,CAAC2O,QAAD,EAAW,KAAK/I,QAAhB,CAA1B;;EACA,UAAMgJ,iBAAiB,GAAG,KAAKpG,OAAL,CAAa,KAAKzC,UAAlB,EAA8BY,WAA9B,CAA1B;;EAEA,UAAMkI,SAAS,GAAI7F,IAAD,IAAUnE,KAAK,CAACC,QAAN,CAAekE,IAAf,CAA5B;;EACA,UAAM8F,gBAAgB,GAAI9F,IAAD,IAAU;EACjCA,MAAAA,IAAI,CAACxM,KAAL,GAAarB,WAAW,CAACsB,KAAZ,CAAkBvB,MAA/B;EACA8N,MAAAA,IAAI,CAACzN,QAAL,GAAgB,IAAhB;EACAyN,MAAAA,IAAI,CAAC9M,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBjB,MAAhB,CAAuBuC,MAArC;EACAuL,MAAAA,IAAI,CAAC9M,QAAL,CAAcf,WAAW,CAACgB,GAAZ,CAAgBjB,MAAhB,CAAuByC,KAArC;EACD,KALD,CAdY;EAsBZ;;;EACA,UAAM8O,aAAa,GAAG,KAAKC,iBAAL,CAAuBkC,iBAAiB,CAAC9F,OAAzC,CAAtB;;EACA8F,IAAAA,iBAAiB,CAAC9F,OAAlB,CAA0BlM,OAA1B,CAAkC,CAACoM,IAAD,EAAOxJ,CAAP,KAAa;EAC7C,UAAIqP,SAAS,CAAC7F,IAAD,CAAb,EAAqB;EACnBA,QAAAA,IAAI,CAACtM,KAAL,GAAa+P,aAAa,CAACjN,CAAD,CAA1B;EACAsP,QAAAA,gBAAgB,CAAC9F,IAAD,CAAhB;EACAA,QAAAA,IAAI,CAAC9M,QAAL,CAAc,KAAKyQ,sBAAL,CAA4B3D,IAA5B,EAAkC,EAAlC,CAAd;EACD;EACF,KAND;EAQA4F,IAAAA,iBAAiB,CAAC7F,MAAlB,CAAyBnM,OAAzB,CAAkCoM,IAAD,IAAU;EACzC,UAAI6F,SAAS,CAAC7F,IAAD,CAAb,EAAqB;EACnB8F,QAAAA,gBAAgB,CAAC9F,IAAD,CAAhB;EACD;EACF,KAJD,EAhCY;;EAuCZ,SAAK5N,OAAL,CAAasM,WAAb,CAvCY;EAyCZ;;EACA,SAAKC,kBAAL,CAAwB9C,KAAxB,EA1CY;;EA6CZ,SAAKA,KAAL,GAAa,KAAKkG,cAAL,CAAoBlG,KAApB,CAAb,CA7CY;;EAgDZ,SAAK2C,MAAL,CAAY,KAAKzB,UAAjB;EACD;EAED;EACF;EACA;;;EACEgJ,EAAAA,OAAO,GAAG;EACR,SAAK/I,SAAL,GAAiB,KAAjB;EACD;EAED;EACF;EACA;EACA;;;EACEgJ,EAAAA,MAAM,GAAwB;EAAA,QAAvBC,cAAuB,uEAAN,IAAM;EAC5B,SAAKjJ,SAAL,GAAiB,IAAjB;;EACA,QAAIiJ,cAAJ,EAAoB;EAClB,WAAKhC,MAAL;EACD;EACF;EAED;EACF;EACA;EACA;EACA;EACA;;;EACEvR,EAAAA,MAAM,CAAC4S,QAAD,EAAW;EACf,QAAI,CAACA,QAAQ,CAAC/O,MAAd,EAAsB;EACpB;EACD;;EAED,UAAMmJ,UAAU,GAAGlD,WAAW,CAAC8I,QAAD,CAA9B;EAEA,UAAMY,QAAQ,GAAGxG,UAAU,CAACxD,GAAX,CAAgB9J,OAAD,IAAa,KAAK+T,gBAAL,CAAsB/T,OAAtB,CAA5B,EAA4DoM,MAA5D,CAAoEwB,IAAD,IAAU,CAAC,CAACA,IAA/E,CAAjB;;EAEA,UAAMoG,YAAY,GAAG,MAAM;EACzB,WAAKrF,aAAL,CAAmBmF,QAAnB,EADyB;;;EAIzBxG,MAAAA,UAAU,CAAC9L,OAAX,CAAoBxB,OAAD,IAAa;EAC9BA,QAAAA,OAAO,CAACiU,UAAR,CAAmB7Q,WAAnB,CAA+BpD,OAA/B;EACD,OAFD;;EAIA,WAAK8Q,SAAL,CAAexG,OAAO,CAACsI,SAAR,CAAkBsB,OAAjC,EAA0C;EAAE5G,QAAAA;EAAF,OAA1C;EACD,KATD,CATe;;;EAqBf,SAAKG,oBAAL,CAA0B;EACxBC,MAAAA,OAAO,EAAE,EADe;EAExBC,MAAAA,MAAM,EAAEmG;EAFgB,KAA1B;;EAKA,SAAKlC,OAAL,CAAakC,QAAb;;EAEA,SAAK1O,IAAL,GA5Be;EA+Bf;;EACA,SAAKqE,KAAL,GAAa,KAAKA,KAAL,CAAW2C,MAAX,CAAmBwB,IAAD,IAAU,CAACkG,QAAQ,CAACpK,QAAT,CAAkBkE,IAAlB,CAA7B,CAAb;;EACA,SAAKgB,gBAAL;;EAEA,SAAKuF,IAAL,CAAU7J,OAAO,CAACsI,SAAR,CAAkBC,MAA5B,EAAoCmB,YAApC;EACD;EAED;EACF;EACA;EACA;EACA;;;EACED,EAAAA,gBAAgB,CAAC/T,OAAD,EAAU;EACxB,WAAO,KAAKyJ,KAAL,CAAW2K,IAAX,CAAiBxG,IAAD,IAAUA,IAAI,CAAC5N,OAAL,KAAiBA,OAA3C,CAAP;EACD;EAED;EACF;EACA;EACA;;;EACEqU,EAAAA,UAAU,GAAG;EACX;EACA,SAAK1F,aAAL,CAAmB,KAAKlF,KAAxB;;EACA,SAAKqB,aAAL,GAAqB,KAArB,CAHW;;EAMX,SAAKrB,KAAL,GAAa,KAAK6B,SAAL,EAAb,CANW;;EASX,SAAKG,UAAL,CAAgB,KAAKhC,KAArB;;EAEA,SAAK0K,IAAL,CAAU7J,OAAO,CAACsI,SAAR,CAAkBC,MAA5B,EAAoC,MAAM;EACxC;EACA,WAAKtG,kBAAL,CAAwB,KAAK9C,KAA7B;EACA,WAAKqB,aAAL,GAAqB,IAArB;EACD,KAJD,EAXW;;EAkBX,SAAKsB,MAAL,CAAY,KAAKzB,UAAjB;EACD;EAED;EACF;EACA;;;EACE2J,EAAAA,OAAO,GAAG;EACR,SAAK/B,eAAL;;EACAvP,IAAAA,MAAM,CAAC6C,mBAAP,CAA2B,QAA3B,EAAqC,KAAK6F,SAA1C,EAFQ;;EAKR,SAAK1L,OAAL,CAAaK,SAAb,CAAuBC,MAAvB,CAA8B,SAA9B;EACA,SAAKN,OAAL,CAAaS,eAAb,CAA6B,OAA7B,EANQ;;EASR,SAAKkO,aAAL,CAAmB,KAAKlF,KAAxB;;EAEA,SAAKA,KAAL,CAAWtF,MAAX,GAAoB,CAApB;EACA,SAAKoH,WAAL,CAAiBpH,MAAjB,GAA0B,CAA1B;EACA,SAAK4G,YAAL,CAAkB5G,MAAlB,GAA2B,CAA3B,CAbQ;;EAgBR,SAAKW,OAAL,CAAa0G,KAAb,GAAqB,IAArB;EACA,SAAKxL,OAAL,GAAe,IAAf,CAjBQ;EAoBR;;EACA,SAAK6K,WAAL,GAAmB,IAAnB;EACA,SAAKD,SAAL,GAAiB,KAAjB;EACD;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;EACgB,SAAPqB,OAAO,CAACjM,OAAD,EAAkC;EAAA,QAAxBuU,cAAwB,uEAAP,KAAO;EAC9C;EACA,UAAMjR,MAAM,GAAGN,MAAM,CAACC,gBAAP,CAAwBjD,OAAxB,EAAiC,IAAjC,CAAf;EACA,QAAIR,KAAK,GAAG6D,cAAc,CAACrD,OAAD,EAAU,OAAV,EAAmBsD,MAAnB,CAA1B;EACA,QAAI7D,MAAM,GAAG4D,cAAc,CAACrD,OAAD,EAAU,QAAV,EAAoBsD,MAApB,CAA3B;;EAEA,QAAIiR,cAAJ,EAAoB;EAClB,YAAMC,UAAU,GAAGnR,cAAc,CAACrD,OAAD,EAAU,YAAV,EAAwBsD,MAAxB,CAAjC;EACA,YAAMmR,WAAW,GAAGpR,cAAc,CAACrD,OAAD,EAAU,aAAV,EAAyBsD,MAAzB,CAAlC;EACA,YAAMoR,SAAS,GAAGrR,cAAc,CAACrD,OAAD,EAAU,WAAV,EAAuBsD,MAAvB,CAAhC;EACA,YAAMqR,YAAY,GAAGtR,cAAc,CAACrD,OAAD,EAAU,cAAV,EAA0BsD,MAA1B,CAAnC;EACA9D,MAAAA,KAAK,IAAIgV,UAAU,GAAGC,WAAtB;EACAhV,MAAAA,MAAM,IAAIiV,SAAS,GAAGC,YAAtB;EACD;;EAED,WAAO;EACLnV,MAAAA,KADK;EAELC,MAAAA;EAFK,KAAP;EAID;EAED;EACF;EACA;EACA;EACA;EACA;EACA;;;EACyB,SAAhB0T,gBAAgB,CAACD,QAAD,EAAWlN,QAAX,EAAqB;EAC1C,UAAM4O,IAAI,GAAG,KAAb,CAD0C;;EAI1C,UAAM5D,IAAI,GAAGkC,QAAQ,CAACpJ,GAAT,CAAc9J,OAAD,IAAa;EACrC,YAAM;EAAE+B,QAAAA;EAAF,UAAY/B,OAAlB;EACA,YAAM6U,QAAQ,GAAG9S,KAAK,CAACsN,kBAAvB;EACA,YAAMyF,KAAK,GAAG/S,KAAK,CAACS,eAApB,CAHqC;;EAMrCT,MAAAA,KAAK,CAACsN,kBAAN,GAA2BuF,IAA3B;EACA7S,MAAAA,KAAK,CAACS,eAAN,GAAwBoS,IAAxB;EAEA,aAAO;EACLC,QAAAA,QADK;EAELC,QAAAA;EAFK,OAAP;EAID,KAbY,CAAb;EAeA9O,IAAAA,QAAQ,GAnBkC;;EAsB1CkN,IAAAA,QAAQ,CAAC,CAAD,CAAR,CAAY5G,WAAZ,CAtB0C;EAwB1C;;EACA4G,IAAAA,QAAQ,CAAC1R,OAAT,CAAiB,CAACxB,OAAD,EAAUoE,CAAV,KAAgB;EAC/BpE,MAAAA,OAAO,CAAC+B,KAAR,CAAcsN,kBAAd,GAAmC2B,IAAI,CAAC5M,CAAD,CAAJ,CAAQyQ,QAA3C;EACA7U,MAAAA,OAAO,CAAC+B,KAAR,CAAcS,eAAd,GAAgCwO,IAAI,CAAC5M,CAAD,CAAJ,CAAQ0Q,KAAxC;EACD,KAHD;EAID;;EArjC+B;;EAwjClCxK,OAAO,CAACvK,WAAR,GAAsBA,WAAtB;EAEAuK,OAAO,CAACI,SAAR,GAAoB,KAApB;EACAJ,OAAO,CAAC2D,oBAAR,GAA+B,QAA/B;EAEA;;EACA3D,OAAO,CAACsI,SAAR,GAAoB;EAClBC,EAAAA,MAAM,EAAE,gBADU;EAElBqB,EAAAA,OAAO,EAAE;EAFS,CAApB;EAKA;;EACA5J,OAAO,CAAC/J,OAAR,GAAkBA,OAAlB;EAEA;;EACA+J,OAAO,CAACmE,UAAR,GAAqB;EACnBC,EAAAA,GAAG,EAAE,KADc;EAEnBqG,EAAAA,GAAG,EAAE;EAFc,CAArB;;EAMAzK,OAAO,CAACxF,OAAR,GAAkB;EAChB;EACA2F,EAAAA,KAAK,EAAEH,OAAO,CAACI,SAFC;EAIhB;EACA+B,EAAAA,KAAK,EAAE,GALS;EAOhB;EACAC,EAAAA,MAAM,EAAE,gCARQ;EAUhB;EACAgD,EAAAA,YAAY,EAAE,GAXE;EAahB;EACA;EACAlE,EAAAA,KAAK,EAAE,IAfS;EAiBhB;EACA;EACA0E,EAAAA,WAAW,EAAE,CAnBG;EAqBhB;EACA;EACAvJ,EAAAA,WAAW,EAAE,CAvBG;EAyBhB;EACA;EACAuH,EAAAA,SAAS,EAAE,IA3BK;EA6BhB;EACA;EACA3G,EAAAA,MAAM,EAAE,CA/BQ;EAiChB;EACA;EACA8I,EAAAA,eAAe,EAAE,IAnCD;EAqChB;EACA;EACAhE,EAAAA,WAAW,EAAE,IAvCG;EAyChB;EACA;EACAQ,YAAAA,UA3CgB;EA6ChB;EACAC,EAAAA,YAAY,EAAE,GA9CE;EAgDhB;EACA8D,EAAAA,aAAa,EAAE,EAjDC;EAmDhB;EACAC,EAAAA,gBAAgB,EAAE,GApDF;EAsDhB;EACA7B,EAAAA,aAAa,EAAE,IAvDC;EAyDhB;EACA;EACA;EACAR,EAAAA,UAAU,EAAElE,OAAO,CAACmE,UAAR,CAAmBC,GA5Df;EA8DhB;EACA8C,EAAAA,UAAU,EAAE,KA/DI;EAiEhB;EACAvR,EAAAA,KAAK,EAAE,KAlES;EAoEhB;EACA;EACA+R,EAAAA,eAAe,EAAE;EAtED,CAAlB;EAyEA1H,OAAO,CAAC3L,KAAR,GAAgBA,KAAhB;EACA2L,OAAO,CAACpL,IAAR,GAAeA,IAAf;;EAGAoL,OAAO,CAAC0K,QAAR,GAAmBpQ,MAAnB;EACA0F,OAAO,CAAC2K,eAAR,GAA0BxO,aAA1B;EACA6D,OAAO,CAAC4K,uBAAR,GAAkCjO,qBAAlC;EACAqD,OAAO,CAAC6K,gBAAR,GAA2B7N,cAA3B;EACAgD,OAAO,CAAC8K,sBAAR,GAAiClN,oBAAjC;;;;;;;;"} \ No newline at end of file diff --git a/docs/dist/shuffle.min.js b/docs/dist/shuffle.min.js index 176b713..3c0e8fc 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="undefined"!=typeof globalThis?globalThis:t||self).Shuffle=e()}(this,(function(){"use strict";function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var i=0;i=e?l():o=setTimeout(l,e-t)),s};function l(){o=0,r=+new Date,s=t.apply(i,n),i=null,n=null}};function p(){}function m(t){return parseFloat(t)||0}var v=function(){function e(i,n){t(this,e),this.x=m(i),this.y=m(n)}return i(e,null,[{key:"equals",value:function(t,e){return t.x===e.x&&t.y===e.y}}]),e}(),y=function(){function e(i,n,s,o,r){t(this,e),this.id=r,this.left=i,this.top=n,this.width=s,this.height=o}return i(e,null,[{key:"intersects",value:function(t,e){return t.left2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=m(i[e]);return b()||"width"!==e?b()||"height"!==e||(n+=m(i.paddingTop)+m(i.paddingBottom)+m(i.borderTopWidth)+m(i.borderBottomWidth)):n+=m(i.paddingLeft)+m(i.paddingRight)+m(i.borderLeftWidth)+m(i.borderRightWidth),n}var S={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function k(t,e){var i=Object.assign({},S,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 w={},C="transitionend",L=0;function D(t){return!!w[t]&&(w[t].element.removeEventListener(C,w[t].listener),w[t]=null,!0)}function z(t,e){var i=C+(L+=1),n=function(t){t.currentTarget===t.target&&(D(i),e(t))};return t.addEventListener(C,n),w[i]={element:t,listener:n},i}function M(t){return Math.max.apply(Math,t)}function A(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 O(t,e){var i={};t.forEach((function(t){i[t.top]?i[t.top].push(t):i[t.top]=[t]}));var n=[],s=[],o=[];return Object.keys(i).forEach((function(t){var r=i[t];s.push(r);var l,a=r[r.length-1],u=a.left+a.width,h=Math.round((e-u)/2),f=r,c=!1;if(h>0){var d=[];(c=r.every((function(t){var e=new y(t.left+h,t.top,t.width,t.height,t.id),i=!n.some((function(t){return y.intersects(e,t)}));return d.push(e),i})))&&(f=d)}if(!c&&r.some((function(t){return n.some((function(e){var i=y.intersects(t,e);return i&&(l=e),i}))}))){var p=o.findIndex((function(t){return t.includes(l)}));o.splice(p,1,s[p])}n=n.concat(f),o.push(f)})),[].concat.apply([],o).sort((function(t,e){return t.id-e.id})).map((function(t){return new v(t.left,t.top)}))}function R(t){return Array.from(new Set(t))}var N=0,B=function(e){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&s(t,e)}(o,e);var n=r(o);function o(e){var i,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,o),(i=n.call(this)).options=Object.assign({},o.options,s),i.options.delimeter&&(i.options.delimiter=i.options.delimeter),i.lastSort={},i.group=o.ALL_ITEMS,i.lastFilter=o.ALL_ITEMS,i.isEnabled=!0,i.isDestroyed=!1,i.isInitialized=!1,i._transitions=[],i.isTransitioning=!1,i._queue=[];var r=i._getElementOption(e);if(!r)throw new TypeError("Shuffle needs to be initialized with an element.");return i.element=r,i.id="shuffle_"+N,N+=1,i._init(),i.isInitialized=!0,i}return i(o,[{key:"_init",value:function(){if(this.items=this._getItems(),this.sortedItems=this.items,this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(o.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){var t=this.layout.bind(this);window.addEventListener("load",(function e(){window.removeEventListener("load",e),t()}))}var e=window.getComputedStyle(this.element,null),i=o.getSize(this.element).width;this._validateStyles(e),this._setColumns(i),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition="height ".concat(this.options.speed,"ms ").concat(this.options.easing)}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(t,e){var i=this,n=[],s=[];return t===o.ALL_ITEMS?n=e:e.forEach((function(e){i._doesPassFilter(t,e.element)?n.push(e):s.push(e)})),{visible:n,hidden:s}}},{key:"_doesPassFilter",value:function(t,e){if("function"==typeof t)return t.call(e,e,this);var i=e.getAttribute("data-"+o.FILTER_ATTRIBUTE_KEY),n=this.options.delimiter?i.split(this.options.delimiter):JSON.parse(i);function s(t){return n.includes(t)}return Array.isArray(t)?this.options.filterMode===o.FilterMode.ANY?t.some(s):t.every(s):n.includes(t)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach((function(t){t.show()})),i.forEach((function(t){t.hide()}))}},{key:"_initItems",value:function(t){t.forEach((function(t){t.init()}))}},{key:"_disposeItems",value:function(t){t.forEach((function(t){t.dispose()}))}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"setItemTransitions",value:function(t){var e=this.options,i=e.speed,n=e.easing,s=this.options.useTransforms?["transform"]:["top","left"],o=Object.keys(E.Css.HIDDEN.before).map((function(t){return t.replace(/([A-Z])/g,(function(t,e){return"-".concat(e.toLowerCase())}))})),r=s.concat(o).join();t.forEach((function(t){t.element.style.transitionDuration=i+"ms",t.element.style.transitionTimingFunction=n,t.element.style.transitionProperty=r}))}},{key:"_getItems",value:function(){var t=this;return Array.from(this.element.children).filter((function(e){return c(e,t.options.itemSelector)})).map((function(e){return new E(e,t.options.isRTL)}))}},{key:"_mergeNewItems",value:function(t){var e=Array.from(this.element.children);return k(this.items.concat(t),{by:function(t){return e.indexOf(t)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter((function(t){return t.isVisible}))}},{key:"_getConcealedItems",value:function(){return this.items.filter((function(t){return!t.isVisible}))}},{key:"_getColumnSize",value:function(t,e){var i;return 0===(i="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?o.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?o.getSize(this.items[0].element,!0).width:t)&&(i=t),i+e}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?T(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o.getSize(this.element).width,e=this._getGutterSize(t),i=this._getColumnSize(t,e),n=(t+e)/i;Math.abs(Math.round(n)-n)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(t){var e=this,i=this._getNextPositions(t),n=0;t.forEach((function(t,s){function o(){t.applyCss(E.Css.VISIBLE.after)}if(v.equals(t.point,i[s])&&!t.isHidden)return t.applyCss(E.Css.VISIBLE.before),void o();t.point=i[s],t.scale=E.Scale.VISIBLE,t.isHidden=!1;var r=e.getStylesForTransition(t,E.Css.VISIBLE.before);r.transitionDelay=e._getStaggerAmount(n)+"ms",e._queue.push({item:t,styles:r,callback:o}),n+=1}))}},{key:"_getNextPositions",value:function(t){var e=this;if(this.options.isCentered){var i=t.map((function(t,i){var n=o.getSize(t.element,!0),s=e._getItemPosition(n);return new y(s.x,s.y,n.width,n.height,i)}));return this.getTransformedPositions(i,this.containerWidth)}return t.map((function(t){return e._getItemPosition(o.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=A(e.width,n,s,o),a=F(i,l,s),u=x(a,r),h=new v(n*u,a[u]),f=a[u]+e.height,c=0;c0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach((function(e){function n(){e.applyCss(E.Css.HIDDEN.after)}if(e.isHidden)return e.applyCss(E.Css.HIDDEN.before),void n();e.scale=E.Scale.HIDDEN,e.isHidden=!0;var s=t.getStylesForTransition(e,E.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1}))}},{key:"_handleResize",value:function(){this.isEnabled&&!this.isDestroyed&&this.update()}},{key:"getStylesForTransition",value:function(t,e){var i=Object.assign({},e);if(this.options.useTransforms){var n=this.options.isRTL?"-":"",s=this.options.roundTransforms?Math.round(t.point.x):t.point.x,o=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform="translate(".concat(n).concat(s,"px, ").concat(o,"px) scale(").concat(t.scale,")")}else this.options.isRTL?i.right=t.point.x+"px":i.left=t.point.x+"px",i.top=t.point.y+"px";return i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=z(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(o.EventType.LAYOUT)):this._dispatch(o.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=p);var n=t&&t.length;if(!n)return i(null,[]);var s=!1,o=new Array(n);function r(t){return function(e,r){if(!s){if(e)return i(e,o),void(s=!0);o[t]=r,--n||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,r(i))}:function(t,e){t(r(e))})}(t.map((function(t){return e._getTransitionFunction(t)})),this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(D),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}));o._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(o.EventType.LAYOUT)}},{key:"filter",value:function(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=o.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=k(this._getFilteredItems(),t);this.sortedItems=e,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=R(t).map((function(t){return new E(t,e.options.isRTL)}));this._initItems(i),this._resetCols();var n=k(this._mergeNewItems(i),this.lastSort),s=this._filter(this.lastFilter,n),o=function(t){return i.includes(t)},r=function(t){t.scale=E.Scale.HIDDEN,t.isHidden=!0,t.applyCss(E.Css.HIDDEN.before),t.applyCss(E.Css.HIDDEN.after)},l=this._getNextPositions(s.visible);s.visible.forEach((function(t,i){o(t)&&(t.point=l[i],r(t),t.applyCss(e.getStylesForTransition(t,{})))})),s.hidden.forEach((function(t){o(t)&&r(t)})),this.element.offsetWidth,this.setItemTransitions(i),this.items=this._mergeNewItems(i),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}},{key:"remove",value:function(t){var e=this;if(t.length){var i=R(t),n=i.map((function(t){return e.getItemByElement(t)})).filter((function(t){return!!t}));this._toggleFilterClasses({visible:[],hidden:n}),this._shrink(n),this.sort(),this.items=this.items.filter((function(t){return!n.includes(t)})),this._updateItemCount(),this.once(o.EventType.LAYOUT,(function(){e._disposeItems(n),i.forEach((function(t){t.parentNode.removeChild(t)})),e._dispatch(o.EventType.REMOVED,{collection:i})}))}}},{key:"getItemByElement",value:function(t){return this.items.find((function(e){return e.element===t}))}},{key:"resetItems",value:function(){var t=this;this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(o.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.sortedItems.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(t,"width",i),s=T(t,"height",i);if(e){var o=T(t,"marginLeft",i),r=T(t,"marginRight",i),l=T(t,"marginTop",i),a=T(t,"marginBottom",i);n+=o+r,s+=l+a}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}))}}]),o}(u);return B.ShuffleItem=E,B.ALL_ITEMS="all",B.FILTER_ATTRIBUTE_KEY="groups",B.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},B.Classes=g,B.FilterMode={ANY:"any",ALL:"all"},B.options={group:B.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:d,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:B.FilterMode.ANY,isCentered:!1,isRTL:!1,roundTransforms:!0},B.Point=v,B.Rect=y,B.__sorter=k,B.__getColumnSpan=A,B.__getAvailablePositions=F,B.__getShortColumn=x,B.__getCenteredPositions=O,B})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Shuffle=e()}(this,(function(){"use strict";var t={exports:{}};function e(){}e.prototype={on:function(t,e,i){var s=this.e||(this.e={});return(s[t]||(s[t]=[])).push({fn:e,ctx:i}),this},once:function(t,e,i){var s=this;function n(){s.off(t,n),e.apply(i,arguments)}return n._=e,this.on(t,n,i)},emit:function(t){for(var e=[].slice.call(arguments,1),i=((this.e||(this.e={}))[t]||[]).slice(),s=0,n=i.length;s=e?h():o=setTimeout(h,e-t)),n};function h(){o=0,r=+new Date,n=t.apply(i,s),i=null,s=null}};function n(){}function o(t){return parseFloat(t)||0}class r{constructor(t,e){this.x=o(t),this.y=o(e)}static equals(t,e){return t.x===e.x&&t.y===e.y}}class h{constructor(t,e,i,s,n){this.id=n,this.left=t,this.top=e,this.width=i,this.height=s}static intersects(t,e){return t.left{this.element.classList.add(t)}))}removeClasses(t){t.forEach((t=>{this.element.classList.remove(t)}))}applyCss(t){Object.keys(t).forEach((e=>{this.element.style[e]=t[e]}))}dispose(){this.removeClasses([l.HIDDEN,l.VISIBLE,l.SHUFFLE_ITEM]),this.element.removeAttribute("style"),this.element=null}}d.Css={INITIAL:{position:"absolute",top:0,visibility:"visible",willChange:"transform"},DIRECTION:{ltr:{left:0},rtl:{right:0}},VISIBLE:{before:{opacity:1,visibility:"visible"},after:{transitionDelay:""}},HIDDEN:{before:{opacity:0},after:{visibility:"hidden",transitionDelay:""}}},d.Scale={VISIBLE:1,HIDDEN:.001};let u=null;var m=()=>{if(null!==u)return u;const t=document.body||document.documentElement,e=document.createElement("div");e.style.cssText="width:10px;padding:2px;box-sizing:border-box;",t.appendChild(e);const{width:i}=window.getComputedStyle(e,null);return u=10===Math.round(o(i)),t.removeChild(e),u};function c(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),s=o(i[e]);return m()||"width"!==e?m()||"height"!==e||(s+=o(i.paddingTop)+o(i.paddingBottom)+o(i.borderTopWidth)+o(i.borderBottomWidth)):s+=o(i.paddingLeft)+o(i.paddingRight)+o(i.borderLeftWidth)+o(i.borderRightWidth),s}const p={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function f(t,e){const i={...p,...e},s=Array.from(t);let n=!1;return t.length?i.randomize?function(t){let e=t.length;for(;e;){e-=1;const i=Math.floor(Math.random()*(e+1)),s=t[i];t[i]=t[e],t[e]=s}return t}(t):("function"==typeof i.by?t.sort(((t,e)=>{if(n)return 0;const s=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===s&&void 0===o?(n=!0,0):so||"sortLast"===s||"sortFirst"===o?1:0})):"function"==typeof i.compare&&t.sort(i.compare),n?s:(i.reverse&&t.reverse(),t)):[]}const g={},_="transitionend";let y=0;function I(t){return!!g[t]&&(g[t].element.removeEventListener(_,g[t].listener),g[t]=null,!0)}function E(t,e){const i=(y+=1,_+y),s=t=>{t.currentTarget===t.target&&(I(i),e(t))};return t.addEventListener(_,s),g[i]={element:t,listener:s},i}function T(t){return Math.max(...t)}function v(t,e,i,s){let n=t/e;return Math.abs(Math.round(n)-n)=i-e&&t[s]<=i+e)return s;return 0}function C(t,e){const i={};t.forEach((t=>{i[t.top]?i[t.top].push(t):i[t.top]=[t]}));let s=[];const n=[],o=[];return Object.keys(i).forEach((t=>{const r=i[t];n.push(r);const l=r[r.length-1],a=l.left+l.width,d=Math.round((e-a)/2);let u=r,m=!1;if(d>0){const t=[];m=r.every((e=>{const i=new h(e.left+d,e.top,e.width,e.height,e.id),n=!s.some((t=>h.intersects(i,t)));return t.push(i),n})),m&&(u=t)}if(!m){let t;if(r.some((e=>s.some((i=>{const s=h.intersects(e,i);return s&&(t=i),s}))))){const e=o.findIndex((e=>e.includes(t)));o.splice(e,1,n[e])}}s=s.concat(u),o.push(u)})),o.flat().sort(((t,e)=>t.id-e.id)).map((t=>new r(t.left,t.top)))}function L(t){return Array.from(new Set(t))}let w=0;class D extends i{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),this.options={...D.options,...e},this.lastSort={},this.group=D.ALL_ITEMS,this.lastFilter=D.ALL_ITEMS,this.isEnabled=!0,this.isDestroyed=!1,this.isInitialized=!1,this._transitions=[],this.isTransitioning=!1,this._queue=[];const i=this._getElementOption(t);if(!i)throw new TypeError("Shuffle needs to be initialized with an element.");this.element=i,this.id="shuffle_"+w,w+=1,this._init(),this.isInitialized=!0}_init(){if(this.items=this._getItems(),this.sortedItems=this.items,this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(D.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){const t=this.layout.bind(this);window.addEventListener("load",(function e(){window.removeEventListener("load",e),t()}))}const t=window.getComputedStyle(this.element,null),e=D.getSize(this.element).width;this._validateStyles(t),this._setColumns(e),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}`}_getResizeFunction(){const t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}_getElementOption(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}_validateStyles(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}_filter(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items;const i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}_getFilteredSets(t,e){let i=[];const s=[];return t===D.ALL_ITEMS?i=e:e.forEach((e=>{this._doesPassFilter(t,e.element)?i.push(e):s.push(e)})),{visible:i,hidden:s}}_doesPassFilter(t,e){if("function"==typeof t)return t.call(e,e,this);const i=e.getAttribute("data-"+D.FILTER_ATTRIBUTE_KEY),s=this.options.delimiter?i.split(this.options.delimiter):JSON.parse(i);function n(t){return s.includes(t)}return Array.isArray(t)?this.options.filterMode===D.FilterMode.ANY?t.some(n):t.every(n):s.includes(t)}_toggleFilterClasses(t){let{visible:e,hidden:i}=t;e.forEach((t=>{t.show()})),i.forEach((t=>{t.hide()}))}_initItems(t){t.forEach((t=>{t.init()}))}_disposeItems(t){t.forEach((t=>{t.dispose()}))}_updateItemCount(){this.visibleItems=this._getFilteredItems().length}setItemTransitions(t){const{speed:e,easing:i}=this.options,s=this.options.useTransforms?["transform"]:["top","left"],n=Object.keys(d.Css.HIDDEN.before).map((t=>t.replace(/([A-Z])/g,((t,e)=>`-${e.toLowerCase()}`)))),o=s.concat(n).join();t.forEach((t=>{t.element.style.transitionDuration=e+"ms",t.element.style.transitionTimingFunction=i,t.element.style.transitionProperty=o}))}_getItems(){return Array.from(this.element.children).filter((t=>t.matches(this.options.itemSelector))).map((t=>new d(t,this.options.isRTL)))}_mergeNewItems(t){const e=Array.from(this.element.children);return f(this.items.concat(t),{by:t=>e.indexOf(t)})}_getFilteredItems(){return this.items.filter((t=>t.isVisible))}_getConcealedItems(){return this.items.filter((t=>!t.isVisible))}_getColumnSize(t,e){let i;return i="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?D.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?D.getSize(this.items[0].element,!0).width:t,0===i&&(i=t),i+e}_getGutterSize(t){let e;return e="function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?c(this.options.sizer,"marginLeft"):this.options.gutterWidth,e}_setColumns(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:D.getSize(this.element).width;const e=this._getGutterSize(t),i=this._getColumnSize(t,e);let s=(t+e)/i;Math.abs(Math.round(s)-s)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}_resetCols(){let t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}_layout(t){const e=this._getNextPositions(t);let i=0;t.forEach(((t,s)=>{function n(){t.applyCss(d.Css.VISIBLE.after)}if(r.equals(t.point,e[s])&&!t.isHidden)return t.applyCss(d.Css.VISIBLE.before),void n();t.point=e[s],t.scale=d.Scale.VISIBLE,t.isHidden=!1;const o=this.getStylesForTransition(t,d.Css.VISIBLE.before);o.transitionDelay=this._getStaggerAmount(i)+"ms",this._queue.push({item:t,styles:o,callback:n}),i+=1}))}_getNextPositions(t){if(this.options.isCentered){const e=t.map(((t,e)=>{const i=D.getSize(t.element,!0),s=this._getItemPosition(i);return new h(s.x,s.y,i.width,i.height,e)}));return this.getTransformedPositions(e,this.containerWidth)}return t.map((t=>this._getItemPosition(D.getSize(t.element,!0))))}_getItemPosition(t){return function(t){let{itemSize:e,positions:i,gridSize:s,total:n,threshold:o,buffer:h}=t;const l=v(e.width,s,n,o),a=S(i,l,n),d=b(a,h),u=new r(s*d,a[d]),m=a[d]+e.height;for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),e=0;t.forEach((t=>{function i(){t.applyCss(d.Css.HIDDEN.after)}if(t.isHidden)return t.applyCss(d.Css.HIDDEN.before),void i();t.scale=d.Scale.HIDDEN,t.isHidden=!0;const s=this.getStylesForTransition(t,d.Css.HIDDEN.before);s.transitionDelay=this._getStaggerAmount(e)+"ms",this._queue.push({item:t,styles:s,callback:i}),e+=1}))}_handleResize(){this.isEnabled&&!this.isDestroyed&&this.update()}getStylesForTransition(t,e){const i={...e};if(this.options.useTransforms){const e=this.options.isRTL?"-":"",s=this.options.roundTransforms?Math.round(t.point.x):t.point.x,n=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform=`translate(${e}${s}px, ${n}px) scale(${t.scale})`}else this.options.isRTL?i.right=t.point.x+"px":i.left=t.point.x+"px",i.top=t.point.y+"px";return i}_whenTransitionDone(t,e,i){const s=E(t,(t=>{e(),i(null,t)}));this._transitions.push(s)}_getTransitionFunction(t){return e=>{t.item.applyCss(t.styles),this._whenTransitionDone(t.item.element,t.callback,e)}}_processQueue(){this.isTransitioning&&this._cancelMovement();const 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(D.EventType.LAYOUT)):this._dispatch(D.EventType.LAYOUT),this._queue.length=0}_startTransitions(t){this.isTransitioning=!0;!function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=n);var s=t&&t.length;if(!s)return i(null,[]);var o=!1,r=new Array(s);function h(t){return function(e,n){if(!o){if(e)return i(e,r),void(o=!0);r[t]=n,--s||i(null,r)}}}t.forEach(e?function(t,i){t.call(e,h(i))}:function(t,e){t(h(e))})}(t.map((t=>this._getTransitionFunction(t))),this._movementFinished.bind(this))}_cancelMovement(){this._transitions.forEach(I),this._transitions.length=0,this.isTransitioning=!1}_styleImmediately(t){if(t.length){const e=t.map((t=>t.item.element));D._skipTransitions(e,(()=>{t.forEach((t=>{t.item.applyCss(t.styles),t.callback()}))}))}}_movementFinished(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(D.EventType.LAYOUT)}filter(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=D.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}sort(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(!this.isEnabled)return;this._resetCols();const e=f(this._getFilteredItems(),t);this.sortedItems=e,this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}update(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isEnabled&&(t||this._setColumns(),this.sort())}layout(){this.update(!0)}add(t){const e=L(t).map((t=>new d(t,this.options.isRTL)));this._initItems(e),this._resetCols();const i=f(this._mergeNewItems(e),this.lastSort),s=this._filter(this.lastFilter,i),n=t=>e.includes(t),o=t=>{t.scale=d.Scale.HIDDEN,t.isHidden=!0,t.applyCss(d.Css.HIDDEN.before),t.applyCss(d.Css.HIDDEN.after)},r=this._getNextPositions(s.visible);s.visible.forEach(((t,e)=>{n(t)&&(t.point=r[e],o(t),t.applyCss(this.getStylesForTransition(t,{})))})),s.hidden.forEach((t=>{n(t)&&o(t)})),this.element.offsetWidth,this.setItemTransitions(e),this.items=this._mergeNewItems(e),this.filter(this.lastFilter)}disable(){this.isEnabled=!1}enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}remove(t){if(!t.length)return;const e=L(t),i=e.map((t=>this.getItemByElement(t))).filter((t=>!!t));this._toggleFilterClasses({visible:[],hidden:i}),this._shrink(i),this.sort(),this.items=this.items.filter((t=>!i.includes(t))),this._updateItemCount(),this.once(D.EventType.LAYOUT,(()=>{this._disposeItems(i),e.forEach((t=>{t.parentNode.removeChild(t)})),this._dispatch(D.EventType.REMOVED,{collection:e})}))}getItemByElement(t){return this.items.find((e=>e.element===t))}resetItems(){this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(D.EventType.LAYOUT,(()=>{this.setItemTransitions(this.items),this.isInitialized=!0})),this.filter(this.lastFilter)}destroy(){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.sortedItems.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}static getSize(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const i=window.getComputedStyle(t,null);let s=c(t,"width",i),n=c(t,"height",i);if(e){s+=c(t,"marginLeft",i)+c(t,"marginRight",i),n+=c(t,"marginTop",i)+c(t,"marginBottom",i)}return{width:s,height:n}}static _skipTransitions(t,e){const i=t.map((t=>{const{style:e}=t,i=e.transitionDuration,s=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:s}}));e(),t[0].offsetWidth,t.forEach(((t,e)=>{t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay}))}}return D.ShuffleItem=d,D.ALL_ITEMS="all",D.FILTER_ATTRIBUTE_KEY="groups",D.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},D.Classes=l,D.FilterMode={ANY:"any",ALL:"all"},D.options={group:D.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:s,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:D.FilterMode.ANY,isCentered:!1,isRTL:!1,roundTransforms:!0},D.Point=r,D.Rect=h,D.__sorter=f,D.__getColumnSpan=v,D.__getAvailablePositions=S,D.__getShortColumn=b,D.__getCenteredPositions=C,D})); //# sourceMappingURL=shuffle.min.js.map diff --git a/docs/dist/shuffle.min.js.map b/docs/dist/shuffle.min.js.map index 1f02f4f..3073ede 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;\nmodule.exports.TinyEmitter = 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, isRTL) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Set correct direction of item\n */\n this.isRTL = isRTL;\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.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr);\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 visibility: 'visible',\n willChange: 'transform',\n },\n DIRECTION: {\n ltr: {\n left: 0,\n },\n rtl: {\n right: 0,\n },\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","import getNumber from './get-number';\n\nlet value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n const { width } = window.getComputedStyle(e, null);\n // Fix for issue #314\n value = Math.round(getNumber(width)) === 10;\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft)\n + getNumber(styles.paddingRight)\n + getNumber(styles.borderLeftWidth)\n + getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop)\n + getNumber(styles.paddingBottom)\n + getNumber(styles.borderTopWidth)\n + getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n // eslint-disable-next-line prefer-object-spread\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 { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn, getCenteredPositions } 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 // eslint-disable-next-line prefer-object-spread\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 this.sortedItems = this.items;\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 ? this.options.throttle(resizeFunction, this.options.throttleTime) : 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\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n 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 ? attr.split(this.options.delimiter) : 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, this.options.isRTL));\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) < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 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 // eslint-disable-next-line prefer-object-spread\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const sign = this.options.isRTL ? '-' : '';\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(${sign}${x}px, ${y}px) scale(${item.scale})`;\n } else {\n if (this.options.isRTL) {\n styles.right = item.point.x + 'px';\n } else {\n styles.left = item.point.x + 'px';\n }\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 {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\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(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [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 this.sortedItems = items;\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, this.options.isRTL));\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.map((element) => this.getItemByElement(element)).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.sortedItems.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 // Attempt to align grid items to right.\n isRTL: 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","throttleit","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isRTL","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","DIRECTION","rtl","ltr","scale","Scale","point","classes","forEach","className","_this","_this2","obj","Object","keys","key","_this3","style","removeClasses","position","visibility","willChange","right","before","opacity","after","transitionDelay","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","Math","round","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","reverse","by","compare","randomize","sorter","arr","options","opts","assign","original","Array","from","revert","array","n","floor","random","temp","sort","valA","valB","undefined","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","intersectingRect","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","_getItems","sortedItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","shuffle","itemPositions","_getNextPositions","equals","_this4","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","itemSize","_this5","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_getConcealedItems","_this6","update","styleObject","sign","roundTransforms","transform","itemCallback","done","_this7","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","parallel","_this8","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","sortOptions","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","_this9","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","_this10","getItemByElement","_disposeItems","REMOVED","find","_this11","includeMargins","marginLeft","marginRight","marginTop","marginBottom","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"6hDAAA,SAASA,KAKTA,EAAEC,UAAY,CACZC,GAAI,SAAUC,EAAMC,EAAUC,GAC5B,IAAIC,EAAIC,KAAKD,IAAMC,KAAKD,EAAI,IAO5B,OALCA,EAAEH,KAAUG,EAAEH,GAAQ,KAAKK,KAAK,CAC/BC,GAAIL,EACJC,IAAKA,IAGAE,MAGTG,KAAM,SAAUP,EAAMC,EAAUC,GAC9B,IAAIM,EAAOJ,KACX,SAASK,IACPD,EAAKE,IAAIV,EAAMS,GACfR,EAASU,MAAMT,EAAKU,WAItB,OADAH,EAASI,EAAIZ,EACNG,KAAKL,GAAGC,EAAMS,EAAUP,IAGjCY,KAAM,SAAUd,GAMd,IALA,IAAIe,EAAO,GAAGC,MAAMC,KAAKL,UAAW,GAChCM,IAAWd,KAAKD,IAAMC,KAAKD,EAAI,KAAKH,IAAS,IAAIgB,QACjDG,EAAI,EACJC,EAAMF,EAAOG,OAETF,EAAIC,EAAKD,IACfD,EAAOC,GAAGb,GAAGK,MAAMO,EAAOC,GAAGjB,IAAKa,GAGpC,OAAOX,MAGTM,IAAK,SAAUV,EAAMC,GACnB,IAAIE,EAAIC,KAAKD,IAAMC,KAAKD,EAAI,IACxBmB,EAAOnB,EAAEH,GACTuB,EAAa,GAEjB,GAAID,GAAQrB,EACV,IAAK,IAAIkB,EAAI,EAAGC,EAAME,EAAKD,OAAQF,EAAIC,EAAKD,IACtCG,EAAKH,GAAGb,KAAOL,GAAYqB,EAAKH,GAAGb,GAAGO,IAAMZ,GAC9CsB,EAAWlB,KAAKiB,EAAKH,IAY3B,OAJCI,EAAiB,OACdpB,EAAEH,GAAQuB,SACHpB,EAAEH,GAENI,iBAIMP,wBACYA,kBChEzB2B,EAA2B,oBAAZC,QAA0BA,QAAQ3B,UAAY,GAC7D4B,EAASF,EAAMG,SACdH,EAAMI,iBACNJ,EAAMK,uBACNL,EAAMM,oBACNN,EAAMO,mBACNP,EAAMQ,iBAEXJ,EAWA,SAAeK,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,OC5BTM,EAUA,SAAmBC,EAAMC,GACvB,IAAIvC,EAAKwC,EAAMC,EAAKC,EAChBC,EAAO,EAEX,OAAO,WACL3C,EAAME,KACNsC,EAAO9B,UACP,IAAIkC,EAAQ,IAAIC,KAASF,EAIzB,OAHKD,IACCE,GAASL,EAAMxB,IACd2B,EAAYI,WAAW/B,EAAMwB,EAAOK,IACpCH,GAGT,SAAS1B,IACP2B,EAAY,EACZC,GAAQ,IAAIE,KACZJ,EAAMH,EAAK7B,MAAMT,EAAKwC,GACtBxC,EAAM,KACNwC,EAAO,OCUX,SAASO,KClCM,SAASC,EAAUC,UACzBC,WAAWD,IAAU,MCJxBE,wBAMQC,EAAGC,kBACRD,EAAIJ,EAAUI,QACdC,EAAIL,EAAUK,wCASrB,SAAcC,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,2CAShB,SAAkBJ,EAAGC,UAEjBD,EAAEM,KAAOL,EAAEK,KAAOL,EAAEO,OAASP,EAAEK,KAAON,EAAEM,KAAON,EAAEQ,OAC9CR,EAAEO,IAAMN,EAAEM,IAAMN,EAAEQ,QAAUR,EAAEM,IAAMP,EAAEO,IAAMP,EAAES,kBCpCxC,CACbC,KAAM,UACNC,aAAc,eACdC,QAAS,wBACTC,OAAQ,wBCDNR,EAAK,EAEHS,wBACQC,EAASC,aACnBX,GAAM,OACDA,GAAKA,OACLU,QAAUA,OAKVC,MAAQA,OAKRC,WAAY,OAQZC,UAAW,gCAGlB,gBACOD,WAAY,OACZF,QAAQI,UAAUC,OAAOC,EAAQR,aACjCE,QAAQI,UAAUG,IAAID,EAAQT,cAC9BG,QAAQQ,gBAAgB,mCAG/B,gBACON,WAAY,OACZF,QAAQI,UAAUC,OAAOC,EAAQT,cACjCG,QAAQI,UAAUG,IAAID,EAAQR,aAC9BE,QAAQS,aAAa,eAAe,uBAG3C,gBACOC,WAAW,CAACJ,EAAQV,aAAcU,EAAQT,eAC1Cc,SAASZ,EAAYa,IAAIC,cACzBF,SAAS9E,KAAKoE,MAAQF,EAAYa,IAAIE,UAAUC,IAAMhB,EAAYa,IAAIE,UAAUE,UAChFC,MAAQlB,EAAYmB,MAAMrB,aAC1BsB,MAAQ,IAAIrC,4BAGnB,SAAWsC,cACTA,EAAQC,SAAQ,SAACC,GACfC,EAAKvB,QAAQI,UAAUG,IAAIe,mCAI/B,SAAcF,cACZA,EAAQC,SAAQ,SAACC,GACfE,EAAKxB,QAAQI,UAAUC,OAAOiB,8BAIlC,SAASG,cACPC,OAAOC,KAAKF,GAAKJ,SAAQ,SAACO,GACxBC,EAAK7B,QAAQ8B,MAAMF,GAAOH,EAAIG,6BAIlC,gBACOG,cAAc,CACjBzB,EAAQR,OACRQ,EAAQT,QACRS,EAAQV,oBAGLI,QAAQQ,gBAAgB,cACxBR,QAAU,cAInBD,EAAYa,IAAM,CAChBC,QAAS,CACPmB,SAAU,WACVxC,IAAK,EACLyC,WAAY,UACZC,WAAY,aAEdpB,UAAW,CACTE,IAAK,CACHzB,KAAM,GAERwB,IAAK,CACHoB,MAAO,IAGXtC,QAAS,CACPuC,OAAQ,CACNC,QAAS,EACTJ,WAAY,WAEdK,MAAO,CACLC,gBAAiB,KAGrBzC,OAAQ,CACNsC,OAAQ,CACNC,QAAS,GAEXC,MAAO,CACLL,WAAY,SACZM,gBAAiB,MAKvBxC,EAAYmB,MAAQ,CAClBrB,QAAS,EACTC,OAAQ,MCrHV,IAAIlB,EAAQ,qBAEI,OAAVA,SACKA,MAGHoB,EAAUwC,SAASC,MAAQD,SAASE,gBACpC9G,EAAI4G,SAASG,cAAc,OACjC/G,EAAEkG,MAAMc,QAAU,gDAClB5C,EAAQ6C,YAAYjH,OAEZ6D,EAAUqD,OAAOC,iBAAiBnH,EAAG,MAArC6D,aAERb,EAAyC,KAAjCoE,KAAKC,MAAMtE,EAAUc,IAE7BO,EAAQkD,YAAYtH,GAEbgD,GCNM,SAASuE,EACtBnD,EAAS8B,OACTsB,yDAASN,OAAOC,iBAAiB/C,EAAS,MAEtCpB,EAAQD,EAAUyE,EAAOtB,WAGxBuB,KAAgC,UAAVvB,EAKfuB,KAAgC,WAAVvB,IAChClD,GAASD,EAAUyE,EAAOE,YACtB3E,EAAUyE,EAAOG,eACjB5E,EAAUyE,EAAOI,gBACjB7E,EAAUyE,EAAOK,oBARrB7E,GAASD,EAAUyE,EAAOM,aACtB/E,EAAUyE,EAAOO,cACjBhF,EAAUyE,EAAOQ,iBACjBjF,EAAUyE,EAAOS,kBAQhBjF,ECXT,IAAMkF,EAAW,CAEfC,SAAS,EAGTC,GAAI,KAGJC,QAAS,KAGTC,WAAW,EAIXtC,IAAK,WASQ,SAASuC,EAAOC,EAAKC,OAE5BC,EAAO5C,OAAO6C,OAAO,GAAIT,EAAUO,GACnCG,EAAWC,MAAMC,KAAKN,GACxBO,GAAS,SAERP,EAAItH,OAILwH,EAAKJ,UAhDX,SAAmBU,WACbC,EAAID,EAAM9H,OAEP+H,GAAG,CACRA,GAAK,MACCjI,EAAIoG,KAAK8B,MAAM9B,KAAK+B,UAAYF,EAAI,IACpCG,EAAOJ,EAAMhI,GACnBgI,EAAMhI,GAAKgI,EAAMC,GACjBD,EAAMC,GAAKG,SAGNJ,EAsCEV,CAAUE,IAKI,mBAAZE,EAAKN,GACdI,EAAIa,MAAK,SAAChG,EAAGC,MAEPyF,SACK,MAGHO,EAAOZ,EAAKN,GAAG/E,EAAEqF,EAAK1C,MACtBuD,EAAOb,EAAKN,GAAG9E,EAAEoF,EAAK1C,kBAGfwD,IAATF,QAA+BE,IAATD,GACxBR,GAAS,EACF,GAGLO,EAAOC,GAAiB,cAATD,GAAiC,aAATC,GACjC,EAGND,EAAOC,GAAiB,aAATD,GAAgC,cAATC,EACjC,EAGF,KAEwB,mBAAjBb,EAAKL,SACrBG,EAAIa,KAAKX,EAAKL,SAIZU,EACKH,GAGLF,EAAKP,SACPK,EAAIL,UAGCK,IAhDE,GCpDX,IAAMiB,EAAc,GACdC,EAAY,gBACdC,EAAQ,EAOL,SAASC,EAAoBlG,WAC9B+F,EAAY/F,KACd+F,EAAY/F,GAAIU,QAAQyF,oBAAoBH,EAAWD,EAAY/F,GAAIpD,UACvEmJ,EAAY/F,GAAM,MACX,GAMJ,SAASoG,EAAgB1F,EAAStE,OACjC4D,EAdCgG,GADPC,GAAS,GAgBHrJ,EAAW,SAACyJ,GACZA,EAAIC,gBAAkBD,EAAIE,SAC5BL,EAAoBlG,GACpB5D,EAASiK,YAIb3F,EAAQ8F,iBAAiBR,EAAWpJ,GAEpCmJ,EAAY/F,GAAM,CAAEU,QAAAA,EAAS9D,SAAAA,GAEtBoD,EChCM,SAASyG,EAASnB,UACxB5B,KAAKgD,IAAI5J,MAAM4G,KAAM4B,GCYvB,SAASqB,EAAcC,EAAWC,EAAaC,EAASC,OACzDC,EAAaJ,EAAYC,SAKzBnD,KAAKuD,IAAIvD,KAAKC,MAAMqD,GAAcA,GAAcD,IAElDC,EAAatD,KAAKC,MAAMqD,IAInBtD,KAAKwD,IAAIxD,KAAKyD,KAAKH,GAAaF,GASlC,SAASM,EAAsBC,EAAWL,EAAYF,MAExC,IAAfE,SACKK,UAyBHC,EAAY,GAGThK,EAAI,EAAGA,GAAKwJ,EAAUE,EAAY1J,IAEzCgK,EAAU9K,KAAKiK,EAASY,EAAUlK,MAAMG,EAAGA,EAAI0J,YAG1CM,EAWF,SAASC,EAAeF,EAAWG,WCjFTlC,EDkFzBmC,GClFyBnC,EDkFF+B,ECjFtB3D,KAAKwD,IAAIpK,MAAM4G,KAAM4B,IDkFnBhI,EAAI,EAAGC,EAAM8J,EAAU7J,OAAQF,EAAIC,EAAKD,OAC3C+J,EAAU/J,IAAMmK,EAAcD,GAAUH,EAAU/J,IAAMmK,EAAcD,SACjElK,SAIJ,EA0CF,SAASoK,EAAqBC,EAAWC,OACxCC,EAAS,GAKfF,EAAU5F,SAAQ,SAAC+F,GACbD,EAAOC,EAAS5H,KAElB2H,EAAOC,EAAS5H,KAAK1D,KAAKsL,GAG1BD,EAAOC,EAAS5H,KAAO,CAAC4H,UAOxBC,EAAQ,GACNC,EAAO,GACPC,EAAe,UACrB7F,OAAOC,KAAKwF,GAAQ9F,SAAQ,SAACO,OACrBqF,EAAYE,EAAOvF,GACzB0F,EAAKxL,KAAKmL,OA6BJO,EA5BAC,EAAWR,EAAUA,EAAUnK,OAAS,GACxC4K,EAAMD,EAASlI,KAAOkI,EAAShI,MAC/BkI,EAAS3E,KAAKC,OAAOiE,EAAiBQ,GAAO,GAE/CE,EAAaX,EACbY,GAAU,KACVF,EAAS,EAAG,KACRG,EAAW,IACjBD,EAAUZ,EAAUc,OAAM,SAACC,OACnBC,EAAU,IAAI9I,EAAK6I,EAAEzI,KAAOoI,EAAQK,EAAExI,IAAKwI,EAAEvI,MAAOuI,EAAEtI,OAAQsI,EAAE1I,IAGhE4I,GAAab,EAAMc,MAAK,SAACH,UAAM7I,EAAKiJ,WAAWH,EAASD,aAE9DF,EAAShM,KAAKmM,GACPC,QAKPN,EAAaE,OAOZD,GAEgBZ,EAAUkB,MAAK,SAACf,UAAaC,EAAMc,MAAK,SAACH,OACpDI,EAAajJ,EAAKiJ,WAAWhB,EAAUY,UACzCI,IACFZ,EAAmBQ,GAEdI,QAIO,KACRC,EAAWd,EAAae,WAAU,SAACC,UAAUA,EAAMC,SAAShB,MAClED,EAAakB,OAAOJ,EAAU,EAAGf,EAAKe,IAI1ChB,EAAQA,EAAMqB,OAAOd,GACrBL,EAAazL,KAAK8L,MAOb,GAAGc,OAAOtM,MAAM,GAAImL,GACxBtC,MAAK,SAAChG,EAAGC,UAAOD,EAAEK,GAAKJ,EAAEI,MACzBqJ,KAAI,SAACvB,UAAa,IAAItI,EAAMsI,EAAS7H,KAAM6H,EAAS5H,QElMzD,SAASoJ,EAAY7J,UACZ0F,MAAMC,KAAK,IAAImE,IAAI9J,IAI5B,IAAIO,EAAK,EAEHwJ,gUAQQ9I,SAASqE,yDAAU,8BAGxBA,QAAU3C,OAAO6C,OAAO,GAAIuE,EAAQzE,QAASA,GAI9C9C,EAAK8C,QAAQ0E,cACV1E,QAAQ2E,UAAYzH,EAAK8C,QAAQ0E,aAGnCE,SAAW,KACXC,MAAQJ,EAAQK,YAChBC,WAAaN,EAAQK,YACrBE,WAAY,IACZC,aAAc,IACdC,eAAgB,IAChBC,aAAe,KACfC,iBAAkB,IAClBC,OAAS,OAERhM,EAAK6D,EAAKoI,kBAAkB3J,OAE7BtC,QACG,IAAIkM,UAAU,6DAGjB5J,QAAUtC,IACV4B,GAAK,WAAaA,EACvBA,GAAM,IAEDuK,UACAN,eAAgB,mCAGvB,mBACOhB,MAAQ1M,KAAKiO,iBACbC,YAAclO,KAAK0M,WAEnBlE,QAAQ2F,MAAQnO,KAAK8N,kBAAkB9N,KAAKwI,QAAQ2F,YAGpDhK,QAAQI,UAAUG,IAAIuI,EAAQxI,QAAQX,WAGtCsK,WAAWpO,KAAK0M,YAGhB2B,UAAYrO,KAAKsO,qBACtBrH,OAAOgD,iBAAiB,SAAUjK,KAAKqO,WAKX,aAAxB1H,SAAS4H,WAA2B,KAChCC,EAASxO,KAAKwO,OAAOC,KAAKzO,MAChCiH,OAAOgD,iBAAiB,QAAQ,SAASyE,IACvCzH,OAAO2C,oBAAoB,OAAQ8E,GACnCF,WAKEG,EAAe1H,OAAOC,iBAAiBlH,KAAKmE,QAAS,MACrDkH,EAAiB4B,EAAQ2B,QAAQ5O,KAAKmE,SAASP,WAGhDiL,gBAAgBF,QAIhBG,YAAYzD,QAGZ0D,OAAO/O,KAAKwI,QAAQ6E,MAAOrN,KAAKwI,QAAQwG,kBAMxC7K,QAAQ8K,iBACRC,mBAAmBlP,KAAK0M,YACxBvI,QAAQ8B,MAAMkJ,4BAAuBnP,KAAKwI,QAAQ4G,oBAAWpP,KAAKwI,QAAQ6G,0CAQjF,eACQC,EAAiBtP,KAAKuP,cAAcd,KAAKzO,aACxCA,KAAKwI,QAAQgH,SAAWxP,KAAKwI,QAAQgH,SAASF,EAAgBtP,KAAKwI,QAAQiH,cAAgBH,mCASpG,SAAkBI,SAGM,iBAAXA,EACF1P,KAAKmE,QAAQwL,cAAcD,GAIhCA,GAAUA,EAAO3N,UAAgC,IAApB2N,EAAO3N,SAC/B2N,EAILA,GAAUA,EAAOE,OACZF,EAAO,GAGT,oCAQT,SAAgBnI,GAEU,WAApBA,EAAOpB,gBACJhC,QAAQ8B,MAAME,SAAW,YAIR,WAApBoB,EAAOsI,gBACJ1L,QAAQ8B,MAAM4J,SAAW,iCAalC,eAAQC,yDAAW9P,KAAKuN,WAAYwC,yDAAa/P,KAAK0M,MAC9CsD,EAAMhQ,KAAKiQ,iBAAiBH,EAAUC,eAGvCG,qBAAqBF,QAGrBzC,WAAauC,EAIM,iBAAbA,SACJzC,MAAQyC,GAGRE,kCAUT,SAAiBF,EAAUpD,cACrByD,EAAU,GACRC,EAAS,UAGXN,IAAa7C,EAAQK,UACvB6C,EAAUzD,EAKVA,EAAMlH,SAAQ,SAAC6K,GACT1K,EAAK2K,gBAAgBR,EAAUO,EAAKlM,SACtCgM,EAAQlQ,KAAKoQ,GAEbD,EAAOnQ,KAAKoQ,MAKX,CACLF,QAAAA,EACAC,OAAAA,kCAWJ,SAAgBN,EAAU3L,MACA,mBAAb2L,SACFA,EAASjP,KAAKsD,EAASA,EAASnE,UAInCuQ,EAAOpM,EAAQqM,aAAa,QAAUvD,EAAQwD,sBAC9C3K,EAAO9F,KAAKwI,QAAQ2E,UAAYoD,EAAKG,MAAM1Q,KAAKwI,QAAQ2E,WAAawD,KAAKC,MAAML,YAE7EM,EAAaf,UACbhK,EAAK6G,SAASmD,UAGnBlH,MAAMkI,QAAQhB,GACZ9P,KAAKwI,QAAQuI,aAAe9D,EAAQ+D,WAAWC,IAC1CnB,EAASxD,KAAKuE,GAEhBf,EAAS5D,MAAM2E,GAGjB/K,EAAK6G,SAASmD,uCAQvB,gBAAuBK,IAAAA,QAASC,IAAAA,OAC9BD,EAAQ3K,SAAQ,SAAC6K,GACfA,EAAKa,UAGPd,EAAO5K,SAAQ,SAAC6K,GACdA,EAAKc,oCAST,SAAWzE,GACTA,EAAMlH,SAAQ,SAAC6K,GACbA,EAAKe,uCAST,SAAc1E,GACZA,EAAMlH,SAAQ,SAAC6K,GACbA,EAAKgB,6CAQT,gBACOC,aAAetR,KAAKuR,oBAAoBtQ,yCAU/C,SAAmByL,SACS1M,KAAKwI,QAAvB4G,IAAAA,MAAOC,IAAAA,OACTmC,EAAgBxR,KAAKwI,QAAQiJ,cAAgB,CAAC,aAAe,CAAC,MAAO,QAIrEC,EAAW7L,OAAOC,KAAK5B,EAAYa,IAAId,OAAOsC,QAAQuG,KAAI,SAAC6E,UAAgBA,ECtTxEC,QAAQ,YAAY,SAACC,EAAKC,oBAAWA,EAAGC,qBDuT3CC,EAAaR,EAAc3E,OAAO6E,GAAUO,OAElDvF,EAAMlH,SAAQ,SAAC6K,GACbA,EAAKlM,QAAQ8B,MAAMiM,mBAAqB9C,EAAQ,KAChDiB,EAAKlM,QAAQ8B,MAAMkM,yBAA2B9C,EAC9CgB,EAAKlM,QAAQ8B,MAAMmM,mBAAqBJ,8BAI5C,6BACSpJ,MAAMC,KAAK7I,KAAKmE,QAAQkO,UAC5BtD,QAAO,SAAClN,UAAON,EAAQM,EAAImE,EAAKwC,QAAQ8J,iBACxCxF,KAAI,SAACjL,UAAO,IAAIqC,EAAYrC,EAAImE,EAAKwC,QAAQpE,wCAQlD,SAAesI,OACP2F,EAAWzJ,MAAMC,KAAK7I,KAAKmE,QAAQkO,iBAClC/J,EAAOtI,KAAK0M,MAAMG,OAAOH,GAAQ,CACtCvE,YAAGhE,UACMkO,EAASE,QAAQpO,uCAK9B,kBACSnE,KAAK0M,MAAMqC,QAAO,SAACsB,UAASA,EAAKhM,+CAG1C,kBACSrE,KAAK0M,MAAMqC,QAAO,SAACsB,UAAUA,EAAKhM,2CAU3C,SAAegH,EAAgBmH,OACzBC,SAwBS,KApBXA,EADsC,mBAA7BzS,KAAKwI,QAAQ8B,YACftK,KAAKwI,QAAQ8B,YAAYe,GAGvBrL,KAAKwI,QAAQ2F,MACflB,EAAQ2B,QAAQ5O,KAAKwI,QAAQ2F,OAAOvK,MAGlC5D,KAAKwI,QAAQ8B,YACftK,KAAKwI,QAAQ8B,YAGXtK,KAAK0M,MAAMzL,OAAS,EACtBgM,EAAQ2B,QAAQ5O,KAAK0M,MAAM,GAAGvI,SAAS,GAAMP,MAI7CyH,KAKPoH,EAAOpH,GAGFoH,EAAOD,gCAShB,SAAenH,SAE2B,mBAA7BrL,KAAKwI,QAAQkK,YACf1S,KAAKwI,QAAQkK,YAAYrH,GACvBrL,KAAKwI,QAAQ2F,MACf7G,EAAetH,KAAKwI,QAAQ2F,MAAO,cAEnCnO,KAAKwI,QAAQkK,uCAWxB,eAAYrH,yDAAiB4B,EAAQ2B,QAAQ5O,KAAKmE,SAASP,MACnD+O,EAAS3S,KAAK4S,eAAevH,GAC7Bf,EAActK,KAAK6S,eAAexH,EAAgBsH,GACpDG,GAAqBzH,EAAiBsH,GAAUrI,EAGhDnD,KAAKuD,IAAIvD,KAAKC,MAAM0L,GAAqBA,GAAqB9S,KAAKwI,QAAQuK,kBAE7ED,EAAoB3L,KAAKC,MAAM0L,SAG5BE,KAAO7L,KAAKgD,IAAIhD,KAAK8B,MAAM6J,GAAqB,GAAI,QACpDzH,eAAiBA,OACjB4H,SAAW3I,mCAMlB,gBACOnG,QAAQ8B,MAAMpC,OAAS7D,KAAKkT,oBAAsB,sCAQzD,kBACShJ,EAASlK,KAAK8K,4CAQvB,SAAkBqI,UACThM,KAAKwD,IAAIwI,EAAQnT,KAAKwI,QAAQ4K,cAAepT,KAAKwI,QAAQ6K,2CAQnE,SAAUzT,OAAMe,yDAAO,GACjBX,KAAKyN,cAIT9M,EAAK2S,QAAUtT,UACVU,KAAKd,EAAMe,8BAOlB,eACMI,EAAIf,KAAKgT,cACRlI,UAAY,GACV/J,GACLA,GAAK,OACA+J,UAAU7K,KAAK,0BASxB,SAAQyM,cACA6G,EAAgBvT,KAAKwT,kBAAkB9G,GAEzChD,EAAQ,EACZgD,EAAMlH,SAAQ,SAAC6K,EAAMtP,YACVlB,IACPwQ,EAAKvL,SAASZ,EAAYa,IAAIf,QAAQyC,UAKpCxD,EAAMwQ,OAAOpD,EAAK/K,MAAOiO,EAAcxS,MAAQsP,EAAK/L,gBACtD+L,EAAKvL,SAASZ,EAAYa,IAAIf,QAAQuC,aACtC1G,IAIFwQ,EAAK/K,MAAQiO,EAAcxS,GAC3BsP,EAAKjL,MAAQlB,EAAYmB,MAAMrB,QAC/BqM,EAAK/L,UAAW,MAIViD,EAASmM,EAAKC,uBAAuBtD,EAAMnM,EAAYa,IAAIf,QAAQuC,QACzEgB,EAAOb,gBAAkBgN,EAAKE,kBAAkBlK,GAAS,KAEzDgK,EAAK7F,OAAO5N,KAAK,CACfoQ,KAAAA,EACA9I,OAAAA,EACA1H,SAAAA,IAGF6J,GAAS,sCAWb,SAAkBgD,iBAGZ1M,KAAKwI,QAAQqL,WAAY,KACrBC,EAAYpH,EAAMI,KAAI,SAACuD,EAAMtP,OAC3BgT,EAAW9G,EAAQ2B,QAAQyB,EAAKlM,SAAS,GACzCmB,EAAQ0O,EAAKC,iBAAiBF,UAC7B,IAAIzQ,EAAKgC,EAAMpC,EAAGoC,EAAMnC,EAAG4Q,EAASnQ,MAAOmQ,EAASlQ,OAAQ9C,aAG9Df,KAAKkU,wBAAwBJ,EAAW9T,KAAKqL,uBAK/CqB,EAAMI,KAAI,SAACuD,UAAS2D,EAAKC,iBAAiBhH,EAAQ2B,QAAQyB,EAAKlM,SAAS,uCASjF,SAAiB4P,UFxcZ,oBACLA,IAAAA,SAAUjJ,IAAAA,UAAWqJ,IAAAA,SAAUC,IAAAA,MAAO5J,IAAAA,UAAWS,IAAAA,OAE3CoJ,EAAOjK,EAAc2J,EAASnQ,MAAOuQ,EAAUC,EAAO5J,GACtD8J,EAAOzJ,EAAsBC,EAAWuJ,EAAMD,GAC9CG,EAAmBvJ,EAAesJ,EAAMrJ,GAGxC3F,EAAQ,IAAIrC,EAAMkR,EAAWI,EAAkBD,EAAKC,IAKpDC,EAAYF,EAAKC,GAAoBR,EAASlQ,OAC3C9C,EAAI,EAAGA,EAAIsT,EAAMtT,IACxB+J,EAAUyJ,EAAmBxT,GAAKyT,SAG7BlP,EEubEmP,CAAgB,CACrBV,SAAAA,EACAjJ,UAAW9K,KAAK8K,UAChBqJ,SAAUnU,KAAKiT,SACfmB,MAAOpU,KAAKgT,KACZxI,UAAWxK,KAAKwI,QAAQuK,gBACxB9H,OAAQjL,KAAKwI,QAAQyC,gDAWzB,SAAwBG,EAAWC,UAC1BF,EAAqBC,EAAWC,0BAQzC,sBAAQ0E,yDAAa/P,KAAK0U,qBACpBhL,EAAQ,EACZqG,EAAWvK,SAAQ,SAAC6K,YACTxQ,IACPwQ,EAAKvL,SAASZ,EAAYa,IAAId,OAAOwC,UASnC4J,EAAK/L,gBACP+L,EAAKvL,SAASZ,EAAYa,IAAId,OAAOsC,aACrC1G,IAIFwQ,EAAKjL,MAAQlB,EAAYmB,MAAMpB,OAC/BoM,EAAK/L,UAAW,MAEViD,EAASoN,EAAKhB,uBAAuBtD,EAAMnM,EAAYa,IAAId,OAAOsC,QACxEgB,EAAOb,gBAAkBiO,EAAKf,kBAAkBlK,GAAS,KAEzDiL,EAAK9G,OAAO5N,KAAK,CACfoQ,KAAAA,EACA9I,OAAAA,EACA1H,SAAAA,IAGF6J,GAAS,kCAQb,WAEO1J,KAAKwN,YAAaxN,KAAKyN,kBAIvBmH,+CAWP,SAAuBvE,EAAMwE,OAGrBtN,EAAS1B,OAAO6C,OAAO,GAAImM,MAE7B7U,KAAKwI,QAAQiJ,cAAe,KACxBqD,EAAO9U,KAAKwI,QAAQpE,MAAQ,IAAM,GAClClB,EAAIlD,KAAKwI,QAAQuM,gBAAkB5N,KAAKC,MAAMiJ,EAAK/K,MAAMpC,GAAKmN,EAAK/K,MAAMpC,EACzEC,EAAInD,KAAKwI,QAAQuM,gBAAkB5N,KAAKC,MAAMiJ,EAAK/K,MAAMnC,GAAKkN,EAAK/K,MAAMnC,EAC/EoE,EAAOyN,8BAAyBF,UAAO5R,iBAAQC,uBAAckN,EAAKjL,gBAE9DpF,KAAKwI,QAAQpE,MACfmD,EAAOjB,MAAQ+J,EAAK/K,MAAMpC,EAAI,KAE9BqE,EAAO7D,KAAO2M,EAAK/K,MAAMpC,EAAI,KAE/BqE,EAAO5D,IAAM0M,EAAK/K,MAAMnC,EAAI,YAGvBoE,qCAUT,SAAoBpD,EAAS8Q,EAAcC,OACnCzR,EAAKoG,EAAgB1F,GAAS,SAAC2F,GACnCmL,IACAC,EAAK,KAAMpL,WAGR6D,aAAa1N,KAAKwD,yCASzB,SAAuBgF,qBACd,SAACyM,GACNzM,EAAK4H,KAAKvL,SAAS2D,EAAKlB,QACxB4N,EAAKC,oBAAoB3M,EAAK4H,KAAKlM,QAASsE,EAAK5I,SAAUqV,iCAS/D,WACMlV,KAAK4N,sBACFyH,sBAGDC,EAAWtV,KAAKwI,QAAQ4G,MAAQ,EAChCmG,EAAWvV,KAAK6N,OAAO5M,OAAS,EAElCsU,GAAYD,GAAYtV,KAAK0N,mBAC1B8H,kBAAkBxV,KAAK6N,QACnB0H,QACJE,kBAAkBzV,KAAK6N,aACvB6H,UAAUzI,EAAQ0I,UAAUC,cAM5BF,UAAUzI,EAAQ0I,UAAUC,aAI9B/H,OAAO5M,OAAS,mCAOvB,SAAkBuI,mBAEXoE,iBAAkB,EbxtBV,SAAkBiI,EAAKC,EAASjW,GAC1CA,IACoB,mBAAZiW,GACTjW,EAAWiW,EACXA,EAAU,MAEVjW,EAAWgD,GAIf,IAAIkT,EAAUF,GAAOA,EAAI5U,OACzB,IAAK8U,EAAS,OAAOlW,EAAS,KAAM,IAEpC,IAAImW,GAAW,EACXC,EAAU,IAAIrN,MAAMmN,GAQxB,SAASG,EAAUnV,GACjB,OAAO,SAAUoV,EAAKC,GACpB,IAAIJ,EAAJ,CAEA,GAAIG,EAGF,OAFAtW,EAASsW,EAAKF,QACdD,GAAW,GAIbC,EAAQlV,GAAKqV,IAENL,GAASlW,EAAS,KAAMoW,KAlBnCJ,EAAIrQ,QAAQsQ,EAAU,SAAU5V,EAAIa,GAClCb,EAAGW,KAAKiV,EAASI,EAAUnV,KACzB,SAAUb,EAAIa,GAChBb,EAAGgW,EAAUnV,Ma0sBbsV,CAFkB7M,EAAYsD,KAAI,SAAClH,UAAQ0Q,EAAKC,uBAAuB3Q,MAEnD5F,KAAKwW,kBAAkB/H,KAAKzO,sCAGlD,gBAEO2N,aAAanI,QAAQmE,QAGrBgE,aAAa1M,OAAS,OAGtB2M,iBAAkB,mCAQzB,SAAkB6I,MACZA,EAAQxV,OAAQ,KACZyV,EAAWD,EAAQ3J,KAAI,SAAClH,UAAQA,EAAIyK,KAAKlM,WAE/C8I,EAAQ0J,iBAAiBD,GAAU,WACjCD,EAAQjR,SAAQ,SAACI,GACfA,EAAIyK,KAAKvL,SAASc,EAAI2B,QACtB3B,EAAI/F,mDAMZ,gBACO8N,aAAa1M,OAAS,OACtB2M,iBAAkB,OAClB8H,UAAUzI,EAAQ0I,UAAUC,8BASnC,SAAO9F,EAAU8G,GACV5W,KAAKwN,cAILsC,GAAaA,GAAgC,IAApBA,EAAS7O,UACrC6O,EAAW7C,EAAQK,gBAGhBuJ,QAAQ/G,QAGRgH,eAGAC,wBAGA3N,KAAKwN,wBAOZ,eAAKA,yDAAc5W,KAAKoN,YACjBpN,KAAKwN,gBAILwJ,iBAECtK,EAAQpE,EAAOtI,KAAKuR,oBAAqBqF,QAC1C1I,YAAcxB,OAEduK,QAAQvK,QAIRwK,qBAGAC,yBAEA/J,SAAWwJ,yBAOlB,eAAOQ,0DACDpX,KAAKwN,YACF4J,QAEEtI,mBAIF1F,8BAST,gBACOwL,QAAO,sBAQd,SAAIyC,cACI3K,EAAQK,EAAYsK,GAAUvK,KAAI,SAACjL,UAAO,IAAIqC,EAAYrC,EAAIyV,EAAK9O,QAAQpE,eAG5EgK,WAAW1B,QAGXsK,iBAGC9I,EAAc5F,EADHtI,KAAKuX,eAAe7K,GACA1M,KAAKoN,UACpCoK,EAAoBxX,KAAK6W,QAAQ7W,KAAKuN,WAAYW,GAElDuJ,EAAY,SAACpH,UAAS3D,EAAMC,SAAS0D,IACrCqH,EAAmB,SAACrH,GACxBA,EAAKjL,MAAQlB,EAAYmB,MAAMpB,OAC/BoM,EAAK/L,UAAW,EAChB+L,EAAKvL,SAASZ,EAAYa,IAAId,OAAOsC,QACrC8J,EAAKvL,SAASZ,EAAYa,IAAId,OAAOwC,QAKjC8M,EAAgBvT,KAAKwT,kBAAkBgE,EAAkBrH,SAC/DqH,EAAkBrH,QAAQ3K,SAAQ,SAAC6K,EAAMtP,GACnC0W,EAAUpH,KACZA,EAAK/K,MAAQiO,EAAcxS,GAC3B2W,EAAiBrH,GACjBA,EAAKvL,SAASwS,EAAK3D,uBAAuBtD,EAAM,SAIpDmH,EAAkBpH,OAAO5K,SAAQ,SAAC6K,GAC5BoH,EAAUpH,IACZqH,EAAiBrH,WAKhBlM,QAAQ8K,iBAGRC,mBAAmBxC,QAGnBA,MAAQ1M,KAAKuX,eAAe7K,QAG5BqC,OAAO/O,KAAKuN,mCAMnB,gBACOC,WAAY,wBAOnB,eAAOmK,kEACAnK,WAAY,EACbmK,QACG/C,+BAUT,SAAO8B,iBACAA,EAASzV,YAIR8O,EAAahD,EAAY2J,GAEzBkB,EAAW7H,EAAWjD,KAAI,SAAC3I,UAAY0T,EAAKC,iBAAiB3T,MAAU4K,QAAO,SAACsB,WAAWA,UAc3FH,qBAAqB,CACxBC,QAAS,GACTC,OAAQwH,SAGLd,QAAQc,QAERxO,YAIAsD,MAAQ1M,KAAK0M,MAAMqC,QAAO,SAACsB,UAAUuH,EAASjL,SAAS0D,WACvD0G,wBAEA5W,KAAK8M,EAAQ0I,UAAUC,QA1BP,WACnBiC,EAAKE,cAAcH,GAGnB7H,EAAWvK,SAAQ,SAACrB,GAClBA,EAAQlC,WAAWoF,YAAYlD,MAGjC0T,EAAKnC,UAAUzI,EAAQ0I,UAAUqC,QAAS,CAAEjI,WAAAA,wCA0BhD,SAAiB5L,UACRnE,KAAK0M,MAAMuL,MAAK,SAAC5H,UAASA,EAAKlM,UAAYA,+BAOpD,2BAEO4T,cAAc/X,KAAK0M,YACnBgB,eAAgB,OAGhBhB,MAAQ1M,KAAKiO,iBAGbG,WAAWpO,KAAK0M,YAEhBvM,KAAK8M,EAAQ0I,UAAUC,QAAQ,WAElCsC,EAAKhJ,mBAAmBgJ,EAAKxL,OAC7BwL,EAAKxK,eAAgB,UAIlBqB,OAAO/O,KAAKuN,mCAMnB,gBACO8H,kBACLpO,OAAO2C,oBAAoB,SAAU5J,KAAKqO,gBAGrClK,QAAQI,UAAUC,OAAO,gBACzBL,QAAQQ,gBAAgB,cAGxBoT,cAAc/X,KAAK0M,YAEnBA,MAAMzL,OAAS,OACfiN,YAAYjN,OAAS,OACrB0M,aAAa1M,OAAS,OAGtBuH,QAAQ2F,MAAQ,UAChBhK,QAAU,UAIVsJ,aAAc,OACdD,WAAY,2BAyBnB,SAAerJ,OAASgU,0DAEhB5Q,EAASN,OAAOC,iBAAiB/C,EAAS,MAC5CP,EAAQ0D,EAAenD,EAAS,QAASoD,GACzC1D,EAASyD,EAAenD,EAAS,SAAUoD,MAE3C4Q,EAAgB,KACZC,EAAa9Q,EAAenD,EAAS,aAAcoD,GACnD8Q,EAAc/Q,EAAenD,EAAS,cAAeoD,GACrD+Q,EAAYhR,EAAenD,EAAS,YAAaoD,GACjDgR,EAAejR,EAAenD,EAAS,eAAgBoD,GAC7D3D,GAASwU,EAAaC,EACtBxU,GAAUyU,EAAYC,QAGjB,CACL3U,MAAAA,EACAC,OAAAA,mCAWJ,SAAwB6S,EAAU7W,OAI1Bc,EAAO+V,EAAS5J,KAAI,SAAC3I,OACjB8B,EAAU9B,EAAV8B,MACFuS,EAAWvS,EAAMiM,mBACjBuG,EAAQxS,EAAMS,uBAGpBT,EAAMiM,mBATK,MAUXjM,EAAMS,gBAVK,MAYJ,CACL8R,SAAAA,EACAC,MAAAA,MAIJ5Y,IAGA6W,EAAS,GAAGzH,YAGZyH,EAASlR,SAAQ,SAACrB,EAASpD,GACzBoD,EAAQ8B,MAAMiM,mBAAqBvR,EAAKI,GAAGyX,SAC3CrU,EAAQ8B,MAAMS,gBAAkB/F,EAAKI,GAAG0X,gBA3jCxBC,UAgkCtBzL,EAAQ/I,YAAcA,EAEtB+I,EAAQK,UAAY,MACpBL,EAAQwD,qBAAuB,SAG/BxD,EAAQ0I,UAAY,CAClBC,OAAQ,iBACRoC,QAAS,mBAIX/K,EAAQxI,QAAUA,EAGlBwI,EAAQ+D,WAAa,CACnBC,IAAK,MACL0H,IAAK,OAIP1L,EAAQzE,QAAU,CAEhB6E,MAAOJ,EAAQK,UAGf8B,MAAO,IAGPC,OAAQ,iCAGRiD,aAAc,IAIdnE,MAAO,KAIPuE,YAAa,EAIbpI,YAAa,EAIb6C,UAAW,KAIXlC,OAAQ,EAIR8H,gBAAiB,IAIjB/D,YAAa,KAIbQ,SAAAA,EAGAC,aAAc,IAGd2D,cAAe,GAGfC,iBAAkB,IAGlB5B,eAAe,EAKfV,WAAY9D,EAAQ+D,WAAWC,IAG/B4C,YAAY,EAGZzP,OAAO,EAIP2Q,iBAAiB,GAGnB9H,EAAQhK,MAAQA,EAChBgK,EAAQ3J,KAAOA,EAGf2J,EAAQ2L,SAAWtQ,EACnB2E,EAAQ4L,gBAAkBzO,EAC1B6C,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/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;\nmodule.exports.TinyEmitter = E;\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 && a.top < b.top + b.height && b.top < a.top + a.height\n );\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, isRTL) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Set correct direction of item\n */\n this.isRTL = isRTL;\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.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr);\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([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n visibility: 'visible',\n willChange: 'transform',\n },\n DIRECTION: {\n ltr: {\n left: 0,\n },\n rtl: {\n right: 0,\n },\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","import getNumber from './get-number';\n\nlet value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n const { width } = window.getComputedStyle(e, null);\n // Fix for issue #314\n value = Math.round(getNumber(width)) === 10;\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(element, style, styles = window.getComputedStyle(element, null)) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value +=\n getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value +=\n 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/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n const opts = { ...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(...array);\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({ itemSize, positions, gridSize, total, threshold, buffer }) {\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) =>\n rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }),\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 centeredRows\n .flat()\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(...array);\n}\n","import TinyEmitter from 'tiny-emitter';\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 { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn, getCenteredPositions } 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 = { ...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 this.sortedItems = this.items;\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 ? this.options.throttle(resizeFunction, this.options.throttleTime) : 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\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n 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 ? attr.split(this.options.delimiter) : 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) => el.matches(this.options.itemSelector))\n .map((el) => new ShuffleItem(el, this.options.isRTL));\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) < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 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 = { ...styleObject };\n\n if (this.options.useTransforms) {\n const sign = this.options.isRTL ? '-' : '';\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(${sign}${x}px, ${y}px) scale(${item.scale})`;\n } else {\n if (this.options.isRTL) {\n styles.right = item.point.x + 'px';\n } else {\n styles.left = item.point.x + 'px';\n }\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 {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\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(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [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 this.sortedItems = items;\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, this.options.isRTL));\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.map((element) => this.getItemByElement(element)).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.sortedItems.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 // Attempt to align grid items to right.\n isRTL: 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","throttleit","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","constructor","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isRTL","isVisible","isHidden","show","classList","remove","Classes","add","removeAttribute","hide","setAttribute","init","addClasses","applyCss","Css","INITIAL","DIRECTION","rtl","ltr","scale","Scale","point","classes","forEach","className","removeClasses","obj","Object","keys","key","style","dispose","position","visibility","willChange","right","before","opacity","after","transitionDelay","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","Math","round","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","reverse","by","compare","randomize","sorter","arr","options","opts","original","Array","from","revert","array","n","floor","random","temp","sort","valA","valB","undefined","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","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","flat","map","arrayUnique","Set","Shuffle","TinyEmitter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sortedItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","_filter","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimiter","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","_disposeItems","_updateItemCount","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","_mergeNewItems","indexOf","_getConcealedItems","_getColumnSize","gutterSize","size","_getGutterSize","gutterWidth","gutter","calculatedColumns","columnThreshold","cols","colWidth","_setContainerSize","_getContainerSize","_getStaggerAmount","index","staggerAmount","staggerAmountMax","_dispatch","shuffle","_resetCols","_layout","itemPositions","_getNextPositions","equals","getStylesForTransition","isCentered","itemsData","itemSize","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_shrink","update","styleObject","sign","roundTransforms","transform","_whenTransitionDone","itemCallback","done","_getTransitionFunction","_processQueue","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","parallel","_movementFinished","objects","elements","_skipTransitions","sortOptions","isOnlyLayout","newItems","allSortedItemsSet","isNewItem","applyHiddenState","disable","enable","isUpdateLayout","oldItems","getItemByElement","parentNode","REMOVED","find","resetItems","destroy","includeMargins","duration","delay","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index a9177a0..900e261 100644 --- a/docs/index.html +++ b/docs/index.html @@ -214,7 +214,6 @@ prism: true

Dependencies

Shuffle's dependencies are bundled with the dist file.

-

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

@@ -230,27 +229,28 @@ prism: true
  • Chrome
  • Firefox
  • Edge
  • -
  • IE 11
  • Safari
  • -

    Depending on what browsers you support, you may need to polyfill features used by Shuffle.

    +

    If you still need to support IE 11, you can use Shuffle v5.

    -
    +
    -

    Be Social

    -
    +

    Share

    +
    + + Buy Me A Coffee + + - -
    @@ -268,12 +268,5 @@ prism: true
    diff --git a/docs/js/animated-favicon.js b/docs/js/animated-favicon.js index ca33f46..1ef33e4 100644 --- a/docs/js/animated-favicon.js +++ b/docs/js/animated-favicon.js @@ -1,151 +1,140 @@ -'use strict'; - -var Sprite = function (context, img, size) { - this.ctx = context; - this.img = img; - this.width = size; - this.height = size; - this.frameWidth = size; - this.frameHeight = size; -}; - -// Assuming horizontal sprite -Sprite.prototype.getFrame = function (frame) { - return { - x: frame * this.frameWidth, - y: 0, - }; -}; - -Sprite.prototype.clearCanvas = function () { - this.ctx.clearRect(0, 0, this.width, this.height); -}; - -Sprite.prototype.drawFrame = function (frameNumber) { - var frame = this.getFrame(frameNumber); - - // Clear out the last frame - this.clearCanvas(); - - // Draw to the context. This method is really confusing... - this.ctx.drawImage( - this.img, - frame.x, - frame.y, - this.width, - this.height, - 0, - 0, - this.width, - this.height - ); -}; - -var Favicon = function (src, numFrames, framesPerAnimation, animationDelay) { - - // Variables based on params - this.src = src; - this.numFrames = numFrames; - this.framesPerAnimation = framesPerAnimation; - this.animationDelay = animationDelay; - - // Elements - this.canvas = document.createElement('canvas'); - this.img = document.createElement('img'); - this.html = document.documentElement; - - // Calculations - this.size = window.devicePixelRatio > 1 ? 32 : 16; - - // If it's not a data url, pick apart the filename and add @2x for retina - if (!this.src.match(/data:/) && window.devicePixelRatio > 1) { - var dot = this.src.lastIndexOf('.'); - this.src = this.src.substring(0, dot) + '@2x' + this.src.substring(dot); +class Sprite { + constructor(context, img, size) { + this.ctx = context; + this.img = img; + this.width = size; + this.height = size; + this.frameWidth = size; + this.frameHeight = size; } - this.currentFrame = 0; + // Assuming horizontal sprite + getFrame(frame) { + return { + x: frame * this.frameWidth, + y: 0, + }; + } + + clearCanvas() { + this.ctx.clearRect(0, 0, this.width, this.height); + } + + drawFrame(frameNumber) { + var frame = this.getFrame(frameNumber); - // Chrome chokes on this. It looks like it can handle 4 frames per second - this.fps = 24; + // Clear out the last frame + this.clearCanvas(); - // No #favicon element, stop - if (!document.getElementById('favicon')) { - return; + // Draw to the context. This method is really confusing... + this.ctx.drawImage(this.img, frame.x, frame.y, this.width, this.height, 0, 0, this.width, this.height); } +} + +class Favicon { + constructor(src, numFrames, framesPerAnimation, animationDelay) { + // Variables based on params + this.src = src; + this.numFrames = numFrames; + this.framesPerAnimation = framesPerAnimation; + this.animationDelay = animationDelay; + + // Elements + this.canvas = document.createElement('canvas'); + this.img = document.createElement('img'); + this.html = document.documentElement; + + // Calculations + this.size = window.devicePixelRatio > 1 ? 32 : 16; + + // If it's not a data url, pick apart the filename and add @2x for retina + if (!this.src.match(/data:/) && window.devicePixelRatio > 1) { + var dot = this.src.lastIndexOf('.'); + this.src = this.src.substring(0, dot) + '@2x' + this.src.substring(dot); + } - // Save context - this.ctx = this.canvas.getContext('2d'); + this.currentFrame = 0; - // Set canvas dimensions based on device DPI - this.canvas.height = this.canvas.width = this.size; + // Chrome chokes on this. It looks like it can handle 4 frames per second + this.fps = 24; - // Create a new sprite 32x32 size with 32x32 sprites - this.sprite = new Sprite(this.ctx, this.img, this.size); + // No #favicon element, stop + if (!document.getElementById('favicon')) { + return; + } - // Bind the image load handler - this.img.onload = this.onSpriteLoaded.bind(this); + // Save context + this.ctx = this.canvas.getContext('2d'); - // Trigger image to load - this.img.src = this.src; -}; + // Set canvas dimensions based on device DPI + this.canvas.height = this.canvas.width = this.size; -Favicon.prototype.getData = function () { - return this.canvas.toDataURL('image/png'); -}; + // Create a new sprite 32x32 size with 32x32 sprites + this.sprite = new Sprite(this.ctx, this.img, this.size); -// Clone the current #favicon and replace it with a new element -// which has the updated data URI href -Favicon.prototype.setFavicon = function () { - var data = this.getData(); - var originalFavicon = document.getElementById('favicon'); - var clone = originalFavicon.cloneNode(true); + // Bind the image load handler + this.img.onload = this.onSpriteLoaded.bind(this); - clone.setAttribute('href', data); - originalFavicon.parentNode.replaceChild(clone, originalFavicon); -}; + // Trigger image to load + this.img.src = this.src; + } -// Request Animation Frame Loop -Favicon.prototype.loop = function (timestamp) { - // If not enough time has elapse since the last call - // immediately call the next rAF - if (timestamp - this.lastExecuted < this.timeToElapse) { - return requestAnimationFrame(this.loop.bind(this)); + getData() { + return this.canvas.toDataURL('image/png'); } - // Increment current frame - this.currentFrame += 1; - if (this.currentFrame === this.numFrames) { - this.currentFrame = 0; + // Clone the current #favicon and replace it with a new element + // which has the updated data URI href + setFavicon() { + var data = this.getData(); + var originalFavicon = document.getElementById('favicon'); + var clone = originalFavicon.cloneNode(true); + + clone.setAttribute('href', data); + originalFavicon.parentNode.replaceChild(clone, originalFavicon); } - // Completed an animation state - this.timeToElapse = this.currentFrame % this.framesPerAnimation === 0 ? - this.animationDelay : - 1000 / this.fps; + // Request Animation Frame Loop + loop(timestamp) { + // If not enough time has elapse since the last call + // immediately call the next rAF + if (timestamp - this.lastExecuted < this.timeToElapse) { + return requestAnimationFrame(this.loop.bind(this)); + } - // Draw current frame from sprite - this.sprite.drawFrame(this.currentFrame); + // Increment current frame + this.currentFrame += 1; + if (this.currentFrame === this.numFrames) { + this.currentFrame = 0; + } - // Swap - this.setFavicon(); + // Completed an animation state + this.timeToElapse = this.currentFrame % this.framesPerAnimation === 0 ? this.animationDelay : 1000 / this.fps; - // Set a timeout to draw again - this.lastExecuted = timestamp; + // Draw current frame from sprite + this.sprite.drawFrame(this.currentFrame); - // Continue loop - return requestAnimationFrame(this.loop.bind(this)); -}; + // Swap + this.setFavicon(); -// Sprite loaded -Favicon.prototype.onSpriteLoaded = function () { - // Draw the first frame when the image loads - this.sprite.drawFrame(this.currentFrame); + // Set a timeout to draw again + this.lastExecuted = timestamp; - // Swap - this.setFavicon(); + // Continue loop + return requestAnimationFrame(this.loop.bind(this)); + } - // Start loop - requestAnimationFrame(this.loop.bind(this)); -}; + // Sprite loaded + onSpriteLoaded() { + // Draw the first frame when the image loads + this.sprite.drawFrame(this.currentFrame); + + // Swap + this.setFavicon(); + + // Start loop + requestAnimationFrame(this.loop.bind(this)); + } +} new Favicon(window.site_url + '/img/favicon-sprite.png', 21, 7, 3000 * 1); diff --git a/docs/js/demos/adding-removing.js b/docs/js/demos/adding-removing.js index 5c95a24..c8eb722 100644 --- a/docs/js/demos/adding-removing.js +++ b/docs/js/demos/adding-removing.js @@ -2,263 +2,262 @@ var Shuffle = window.Shuffle; -var Demo = function (element) { - this.element = element; - this.initShuffle(); - this.setupEvents(); -}; - -// Column width and gutter width options can be functions -Demo.prototype.initShuffle = function () { - this.shuffle = new Shuffle(this.element, { - itemSelector: '.box', - speed: 250, - easing: 'ease', - columnWidth: function (containerWidth) { - // .box's have a width of 18% - return 0.18 * containerWidth; - }, - - gutterWidth: function (containerWidth) { - // .box's have a margin-left of 2.5% - return 0.025 * containerWidth; - }, - }); -}; - -Demo.prototype.setupEvents = function () { - document.querySelector('#append').addEventListener('click', this.onAppendBoxes.bind(this)); - document.querySelector('#prepend').addEventListener('click', this.onPrependBoxes.bind(this)); - document.querySelector('#randomize').addEventListener('click', this.onRandomize.bind(this)); - document.querySelector('#remove').addEventListener('click', this.onRemoveClick.bind(this)); - document.querySelector('#sorter').addEventListener('change', this.onSortChange.bind(this)); - document.querySelector('#filterer').addEventListener('change', this.onFilterChange.bind(this)); - this.shuffle.element.addEventListener('click', this.onContainerClick.bind(this)); - - // Show off some shuffle events - this.shuffle.on(Shuffle.EventType.REMOVED, function (data) { - console.log(data); - }); -}; - -/** - * Generate random DOM elements. - * @param {number} itemsToCreate Number of items to create. - * @return {Array.} Array of elements. - */ -Demo.prototype._generateBoxes = function (itemsToCreate) { - // Creating random elements. You could use an ajax request or clone elements instead. - var items = []; - var modifierClasses = ['w2', 'h2', 'w3']; - var i = 0; - - for (i = 0; i < itemsToCreate; i++) { - var random = Math.random(); - var box = document.createElement('div'); - box.className = 'box'; - box.style.backgroundColor = this.getRandomColor(); - box.setAttribute('data-reviews', this.getRandomInt(1, 150)); - - // Randomly add a class - if (random > 0.8) { - var randomClass = Math.floor(Math.random() * 3); - box.className = box.className + ' ' + modifierClasses[randomClass]; +class Demo { + constructor(element) { + this.element = element; + this.initShuffle(); + this.setupEvents(); + } + + // Column width and gutter width options can be functions + initShuffle() { + this.shuffle = new Shuffle(this.element, { + itemSelector: '.box', + speed: 250, + easing: 'ease', + columnWidth: function (containerWidth) { + // .box's have a width of 18% + return 0.18 * containerWidth; + }, + + gutterWidth: function (containerWidth) { + // .box's have a margin-left of 2.5% + return 0.025 * containerWidth; + }, + }); + } + + setupEvents() { + document.querySelector('#append').addEventListener('click', this.onAppendBoxes.bind(this)); + document.querySelector('#prepend').addEventListener('click', this.onPrependBoxes.bind(this)); + document.querySelector('#randomize').addEventListener('click', this.onRandomize.bind(this)); + document.querySelector('#remove').addEventListener('click', this.onRemoveClick.bind(this)); + document.querySelector('#sorter').addEventListener('change', this.onSortChange.bind(this)); + document.querySelector('#filterer').addEventListener('change', this.onFilterChange.bind(this)); + this.shuffle.element.addEventListener('click', this.onContainerClick.bind(this)); + + // Show off some shuffle events + this.shuffle.on(Shuffle.EventType.REMOVED, function (data) { + console.log(data); + }); + } + + /** + * Generate random DOM elements. + * @param {number} itemsToCreate Number of items to create. + * @return {Array.} Array of elements. + */ + _generateBoxes(itemsToCreate) { + // Creating random elements. You could use an ajax request or clone elements instead. + var items = []; + var modifierClasses = ['w2', 'h2', 'w3']; + var i = 0; + + for (i = 0; i < itemsToCreate; i++) { + var random = Math.random(); + var box = document.createElement('div'); + box.className = 'box'; + box.style.backgroundColor = this.getRandomColor(); + box.setAttribute('data-reviews', this.getRandomInt(1, 150)); + + // Randomly add a class + if (random > 0.8) { + var randomClass = Math.floor(Math.random() * 3); + box.className = box.className + ' ' + modifierClasses[randomClass]; + } + + items.push(box); } - items.push(box); + return items; + } + + /** + * Return an array of elements which have already been added to the DOM. + * @return {Array.} + */ + _getArrayOfElementsToAdd() { + return this._generateBoxes(5); + } + + /** + * Create an HTML string to insert. This could, for example, come from an XHR request. + * @return {string} A mock HTML string. + */ + _getHtmlMarkupToAdd() { + var fragment = document.createDocumentFragment(); + this._generateBoxes(5).forEach(function (item) { + fragment.appendChild(item); + }); + + var dummy = document.createElement('div'); + dummy.appendChild(fragment); + return dummy.innerHTML; } - return items; -}; - -/** - * Return an array of elements which have already been added to the DOM. - * @return {Array.} - */ -Demo.prototype._getArrayOfElementsToAdd = function () { - return this._generateBoxes(5); -}; - -/** - * Create an HTML string to insert. This could, for example, come from an XHR request. - * @return {string} A mock HTML string. - */ -Demo.prototype._getHtmlMarkupToAdd = function () { - var fragment = document.createDocumentFragment(); - this._generateBoxes(5).forEach(function (item) { - fragment.appendChild(item); - }); - - var dummy = document.createElement('div'); - dummy.appendChild(fragment); - return dummy.innerHTML; -}; - -/** - * Create some DOM elements, append them to the shuffle container, then notify - * shuffle about the new items. You could also insert the HTML as a string. - */ -Demo.prototype.onAppendBoxes = function () { - var elements = this._getArrayOfElementsToAdd(); - - elements.forEach(function (element) { - this.shuffle.element.appendChild(element); - }, this); - - // Tell shuffle items have been appended. - // It expects an array of elements as the parameter. - this.shuffle.add(elements); -}; - -/** - * Show that you can prepend elements by inserting before other elements. You - * can either insert a string like in this method or prepend real elements like - * the `onAppendBoxes` method. - */ -Demo.prototype.onPrependBoxes = function () { - var markup = this._getHtmlMarkupToAdd(); - - // Prepend HTML string. - this.element.insertAdjacentHTML('afterbegin', markup); - - // Get the first 5 children of the container (we are inserting 5 items). - var items = Array.prototype.slice.call(this.element.children, 0, 5); - - // Notify the instance. - this.shuffle.add(items); -}; - -Demo.prototype.getRandomInt = function (min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -}; - -Demo.prototype.getRandomColor = function () { - return '#' + Math.random().toString(16).slice(2, 8); -}; - -// Randomly choose some elements to remove -Demo.prototype.onRemoveClick = function () { - var total = this.shuffle.visibleItems; - - // None left - if (!total) { - return; + /** + * Create some DOM elements, append them to the shuffle container, then notify + * shuffle about the new items. You could also insert the HTML as a string. + */ + onAppendBoxes() { + var elements = this._getArrayOfElementsToAdd(); + + elements.forEach(function (element) { + this.shuffle.element.appendChild(element); + }, this); + + // Tell shuffle items have been appended. + // It expects an array of elements as the parameter. + this.shuffle.add(elements); } - var numberToRemove = Math.min(3, total); - var indiciesToRemove = []; + /** + * Show that you can prepend elements by inserting before other elements. You + * can either insert a string like in this method or prepend real elements like + * the `onAppendBoxes` method. + */ + onPrependBoxes() { + var markup = this._getHtmlMarkupToAdd(); + + // Prepend HTML string. + this.element.insertAdjacentHTML('afterbegin', markup); + + // Get the first 5 children of the container (we are inserting 5 items). + var items = Array.prototype.slice.call(this.element.children, 0, 5); + + // Notify the instance. + this.shuffle.add(items); + } - // This has the possibility to choose the same index for more than - // one in the array, meaning sometimes less than 3 will be removed - for (var i = 0; i < numberToRemove; i++) { - indiciesToRemove.push(this.getRandomInt(0, total - 1)); + getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; } - // Make an array of elements to remove. - var collection = indiciesToRemove.map(function (index) { - return this.shuffle.items[index].element; - }, this); - - // Tell shuffle to remove them - this.shuffle.remove(collection); -}; - -Demo.prototype.onRandomize = function () { - var label = document.getElementById('sorter').querySelector('label.btn.active'); - if (label) { - var radio = label.querySelector('input'); - radio.checked = false; - label.classList.remove('active'); + getRandomColor() { + return '#' + Math.random().toString(16).slice(2, 8); } - this.sortBy('random'); -}; + // Randomly choose some elements to remove + onRemoveClick() { + var total = this.shuffle.visibleItems; -Demo.prototype.toggleActiveClasses = function (event) { - // Add and remove `active` class from buttons. - var buttons = Array.from(event.currentTarget.children); - buttons.forEach(function (button) { - if (button.querySelector('input').value === event.target.value) { - button.classList.add('active'); - } else { - button.classList.remove('active'); + // None left + if (!total) { + return; } - }); -} -Demo.prototype.onSortChange = function (evt) { - this.toggleActiveClasses(evt); - this.sortBy(evt.target.value); -}; + var numberToRemove = Math.min(3, total); + var indiciesToRemove = []; -Demo.prototype.sortBy = function (value) { - var sortOptions; + // This has the possibility to choose the same index for more than + // one in the array, meaning sometimes less than 3 will be removed + for (var i = 0; i < numberToRemove; i++) { + indiciesToRemove.push(this.getRandomInt(0, total - 1)); + } - if (value === 'most-reviews') { - sortOptions = { - reverse: true, - by: this.getReviews, - }; + // Make an array of elements to remove. + var collection = indiciesToRemove.map(function (index) { + return this.shuffle.items[index].element; + }, this); - } else if (value === 'least-reviews') { - sortOptions = { - by: this.getReviews, - }; + // Tell shuffle to remove them + this.shuffle.remove(collection); + } - } else if (value === 'random') { - sortOptions = { randomize: true }; + onRandomize() { + var label = document.getElementById('sorter').querySelector('label.btn.active'); + if (label) { + var radio = label.querySelector('input'); + radio.checked = false; + label.classList.remove('active'); + } - } else { - sortOptions = {}; + this.sortBy('random'); } - // Filter elements - this.shuffle.sort(sortOptions); -}; + toggleActiveClasses(event) { + // Add and remove `active` class from buttons. + var buttons = Array.from(event.currentTarget.children); + buttons.forEach(function (button) { + if (button.querySelector('input').value === event.target.value) { + button.classList.add('active'); + } else { + button.classList.remove('active'); + } + }); + } -Demo.prototype.getReviews = function (element) { - return parseInt(element.getAttribute('data-reviews'), 10); -} + onSortChange(evt) { + this.toggleActiveClasses(evt); + this.sortBy(evt.target.value); + } + + sortBy(value) { + var sortOptions; + + if (value === 'most-reviews') { + sortOptions = { + reverse: true, + by: this.getReviews, + }; + } else if (value === 'least-reviews') { + sortOptions = { + by: this.getReviews, + }; + } else if (value === 'random') { + sortOptions = { randomize: true }; + } else { + sortOptions = {}; + } -Demo.prototype.onFilterChange = function (event) { - this.toggleActiveClasses(event); - this.filterBy(event.target.value); -}; - -Demo.prototype.filterBy = function (value) { - var filterBy; - var _this = this; - - if (value === 'none') { - filterBy = Shuffle.ALL_ITEMS; - } else if (value === 'odd-reviews') { - filterBy = function (element) { - return _this.getReviews(element) % 2 === 1; - }; - } else { - filterBy = function (element) { - return _this.getReviews(element) % 2 === 0; - }; + // Filter elements + this.shuffle.sort(sortOptions); } - this.shuffle.filter(filterBy); -}; - -/** - * Remove a shuffle item when it's clicked. - * @param {Object} event Event object. - */ -Demo.prototype.onContainerClick = function (event) { - // Bail in older browsers. https://caniuse.com/#feat=element-closest - if (typeof event.target.closest !== 'function') { - return; + getReviews(element) { + return parseInt(element.getAttribute('data-reviews'), 10); } - var element = event.target.closest('.box'); - if (element !== null) { - this.shuffle.remove([element]); + onFilterChange(event) { + this.toggleActiveClasses(event); + this.filterBy(event.target.value); } -}; + + filterBy(value) { + var filterBy; + var _this = this; + + if (value === 'none') { + filterBy = Shuffle.ALL_ITEMS; + } else if (value === 'odd-reviews') { + filterBy = function (element) { + return _this.getReviews(element) % 2 === 1; + }; + } else { + filterBy = function (element) { + return _this.getReviews(element) % 2 === 0; + }; + } + + this.shuffle.filter(filterBy); + } + + /** + * Remove a shuffle item when it's clicked. + * @param {Object} event Event object. + */ + onContainerClick(event) { + // Bail in older browsers. https://caniuse.com/#feat=element-closest + if (typeof event.target.closest !== 'function') { + return; + } + + var element = event.target.closest('.box'); + if (element !== null) { + this.shuffle.remove([element]); + } + } +} document.addEventListener('DOMContentLoaded', function () { window.demo = new Demo(document.getElementById('my-shuffle')); diff --git a/docs/js/demos/ajax.js b/docs/js/demos/ajax.js index 10e1c91..a72be30 100644 --- a/docs/js/demos/ajax.js +++ b/docs/js/demos/ajax.js @@ -6,8 +6,6 @@ var loadMoreButton = document.getElementById('load-more-button'); var shuffleInstance; // Fetch first page of results from the API. -// You should probably polyfill `fetch` if you're going to copy this demo. -// https://github.com/github/fetch fetch('https://reqres.in/api/users?page=' + currentPage) .then(function (response) { return response.json(); diff --git a/docs/js/demos/animate-in.js b/docs/js/demos/animate-in.js index 511c23f..1329619 100644 --- a/docs/js/demos/animate-in.js +++ b/docs/js/demos/animate-in.js @@ -1,56 +1,56 @@ -'use strict'; - var Shuffle = window.Shuffle; -var Demo = function () { - this.element = document.getElementById('grid'); - this.gridItems = this.element.querySelectorAll('.picture-item'); - var sizer = this.element.querySelector('.my-sizer-element'); - - this.shuffle = new Shuffle(this.element, { - itemSelector: '.picture-item', - sizer: sizer, - }); +class Demo { + constructor() { + this.element = document.getElementById('grid'); + this.gridItems = this.element.querySelectorAll('.picture-item'); + var sizer = this.element.querySelector('.my-sizer-element'); + + this.shuffle = new Shuffle(this.element, { + itemSelector: '.picture-item', + sizer: sizer, + }); + + var callback = this.showItemsInViewport.bind(this); + this.observer = new IntersectionObserver(callback, { + threshold: 0.5, + }); + + // Loop through each grid item and add it to the viewport watcher. + for (var i = 0; i < this.gridItems.length; i++) { + this.observer.observe(this.gridItems[i]); + } - var callback = this.showItemsInViewport.bind(this); - this.observer = new window.IntersectionObserver(callback, { - threshold: 0.5, - }); + // Add the transition class to the items after ones that are in the viewport + // have received the `in` class. + setTimeout(() => { + this.addTransitionToItems(); + }, 100); + } - // Loop through each grid item and add it to the viewport watcher. - for (var i = 0; i < this.gridItems.length; i++) { - this.observer.observe(this.gridItems[i]); + /** + * Add the `in` class to the element after it comes into view. + */ + showItemsInViewport(changes) { + changes.forEach(function (change) { + if (change.isIntersecting) { + change.target.classList.add('in'); + } + }); } - // Add the transition class to the items after ones that are in the viewport - // have received the `in` class. - setTimeout(function () { - this.addTransitionToItems(); - }.bind(this), 100); -}; - -/** - * Add the `in` class to the element after it comes into view. - */ -Demo.prototype.showItemsInViewport = function (changes) { - changes.forEach(function (change) { - if (change.isIntersecting) { - change.target.classList.add('in'); + /** + * Only the items out of the viewport should transition. This way, the first + * visible ones will snap into place. + */ + addTransitionToItems() { + for (var i = 0; i < this.gridItems.length; i++) { + var inner = this.gridItems[i].querySelector('.picture-item__inner'); + inner.classList.add('picture-item__inner--transition'); } - }); -}; - -/** - * Only the items out of the viewport should transition. This way, the first - * visible ones will snap into place. - */ -Demo.prototype.addTransitionToItems = function () { - for (var i = 0; i < this.gridItems.length; i++) { - var inner = this.gridItems[i].querySelector('.picture-item__inner'); - inner.classList.add('picture-item__inner--transition'); } -}; +} -document.addEventListener('DOMContentLoaded', function () { +document.addEventListener('DOMContentLoaded', () => { window.demo = new Demo(); }); diff --git a/docs/js/demos/compound-filters.js b/docs/js/demos/compound-filters.js index 96b9cf8..72c66c5 100644 --- a/docs/js/demos/compound-filters.js +++ b/docs/js/demos/compound-filters.js @@ -2,139 +2,135 @@ var Shuffle = window.Shuffle; -var Demo = function (element) { - this.shapes = Array.from(document.querySelectorAll('.js-shapes input')); - this.colors = Array.from(document.querySelectorAll('.js-colors button')); - - this.shuffle = new Shuffle(element, { - easing: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)', // easeOutQuart - sizer: '.the-sizer', - }); - - this.filters = { - shapes: [], - colors: [], - }; - - this._bindEventListeners(); -}; - -/** - * Bind event listeners for when the filters change. - */ -Demo.prototype._bindEventListeners = function () { - this._onShapeChange = this._handleShapeChange.bind(this); - this._onColorChange = this._handleColorChange.bind(this); - - this.shapes.forEach(function (input) { - input.addEventListener('change', this._onShapeChange); - }, this); - - this.colors.forEach(function (button) { - button.addEventListener('click', this._onColorChange); - }, this); -}; - -/** - * Get the values of each checked input. - * @return {Array.} - */ -Demo.prototype._getCurrentShapeFilters = function () { - return this.shapes.filter(function (input) { - return input.checked; - }).map(function (input) { - return input.value; - }); -}; - -/** - * Get the values of each `active` button. - * @return {Array.} - */ -Demo.prototype._getCurrentColorFilters = function () { - return this.colors.filter(function (button) { - return button.classList.contains('active'); - }).map(function (button) { - return button.getAttribute('data-value'); - }); -}; - -/** - * A shape input check state changed, update the current filters and filte.r - */ -Demo.prototype._handleShapeChange = function () { - this.filters.shapes = this._getCurrentShapeFilters(); - this.filter(); -}; - -/** - * A color button was clicked. Update filters and display. - * @param {Event} evt Click event object. - */ -Demo.prototype._handleColorChange = function (evt) { - var button = evt.currentTarget; - - // Treat these buttons like radio buttons where only 1 can be selected. - if (button.classList.contains('active')) { - button.classList.remove('active'); - } else { - this.colors.forEach(function (btn) { - btn.classList.remove('active'); +class Demo { + constructor(element) { + this.shapes = Array.from(document.querySelectorAll('.js-shapes input')); + this.colors = Array.from(document.querySelectorAll('.js-colors button')); + + this.shuffle = new Shuffle(element, { + easing: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)', + sizer: '.the-sizer', }); - button.classList.add('active'); + this.filters = { + shapes: [], + colors: [], + }; + + this._bindEventListeners(); } - this.filters.colors = this._getCurrentColorFilters(); - this.filter(); -}; - -/** - * Filter shuffle based on the current state of filters. - */ -Demo.prototype.filter = function () { - if (this.hasActiveFilters()) { - this.shuffle.filter(this.itemPassesFilters.bind(this)); - } else { - this.shuffle.filter(Shuffle.ALL_ITEMS); + /** + * Bind event listeners for when the filters change. + */ + _bindEventListeners() { + this._onShapeChange = this._handleShapeChange.bind(this); + this._onColorChange = this._handleColorChange.bind(this); + + this.shapes.forEach((input) => { + input.addEventListener('change', this._onShapeChange); + }, this); + + this.colors.forEach((button) => { + button.addEventListener('click', this._onColorChange); + }, this); } -}; - -/** - * If any of the arrays in the `filters` property have a length of more than zero, - * that means there is an active filter. - * @return {boolean} - */ -Demo.prototype.hasActiveFilters = function () { - return Object.keys(this.filters).some(function (key) { - return this.filters[key].length > 0; - }, this); -}; - -/** - * Determine whether an element passes the current filters. - * @param {Element} element Element to test. - * @return {boolean} Whether it satisfies all current filters. - */ -Demo.prototype.itemPassesFilters = function (element) { - var shapes = this.filters.shapes; - var colors = this.filters.colors; - var shape = element.getAttribute('data-shape'); - var color = element.getAttribute('data-color'); - - // If there are active shape filters and this shape is not in that array. - if (shapes.length > 0 && !shapes.includes(shape)) { - return false; + + /** + * Get the values of each checked input. + * @return {Array.} + */ + _getCurrentShapeFilters() { + return this.shapes.filter((input) => input.checked).map((input) => input.value); } - // If there are active color filters and this color is not in that array. - if (colors.length > 0 && !colors.includes(color)) { - return false; + /** + * Get the values of each `active` button. + * @return {Array.} + */ + _getCurrentColorFilters() { + return this.colors + .filter((button) => button.classList.contains('active')) + .map((button) => button.getAttribute('data-value')); } - return true; -}; + /** + * A shape input check state changed, update the current filters and filte.r + */ + _handleShapeChange() { + this.filters.shapes = this._getCurrentShapeFilters(); + this.filter(); + } + + /** + * A color button was clicked. Update filters and display. + * @param {Event} evt Click event object. + */ + _handleColorChange(evt) { + var button = evt.currentTarget; + + // Treat these buttons like radio buttons where only 1 can be selected. + if (button.classList.contains('active')) { + button.classList.remove('active'); + } else { + this.colors.forEach((btn) => { + btn.classList.remove('active'); + }); + + button.classList.add('active'); + } + + this.filters.colors = this._getCurrentColorFilters(); + this.filter(); + } + + /** + * Filter shuffle based on the current state of filters. + */ + filter() { + if (this.hasActiveFilters()) { + this.shuffle.filter(this.itemPassesFilters.bind(this)); + } else { + this.shuffle.filter(Shuffle.ALL_ITEMS); + } + } + + /** + * If any of the arrays in the `filters` property have a length of more than zero, + * that means there is an active filter. + * @return {boolean} + */ + hasActiveFilters() { + return Object.keys(this.filters).some((key) => { + return this.filters[key].length > 0; + }, this); + } + + /** + * Determine whether an element passes the current filters. + * @param {Element} element Element to test. + * @return {boolean} Whether it satisfies all current filters. + */ + itemPassesFilters(element) { + var shapes = this.filters.shapes; + var colors = this.filters.colors; + var shape = element.getAttribute('data-shape'); + var color = element.getAttribute('data-color'); + + // If there are active shape filters and this shape is not in that array. + if (shapes.length > 0 && !shapes.includes(shape)) { + return false; + } + + // If there are active color filters and this color is not in that array. + if (colors.length > 0 && !colors.includes(color)) { + return false; + } + + return true; + } +} -document.addEventListener('DOMContentLoaded', function () { +document.addEventListener('DOMContentLoaded', () => { window.demo = new Demo(document.querySelector('.js-shuffle')); }); diff --git a/docs/js/demos/homepage.js b/docs/js/demos/homepage.js index 0528d2e..9fe975a 100644 --- a/docs/js/demos/homepage.js +++ b/docs/js/demos/homepage.js @@ -2,194 +2,194 @@ var Shuffle = window.Shuffle; -var Demo = function (element) { - this.element = element; +class Demo { + constructor(element) { + this.element = element; - this.shuffle = new Shuffle(element, { - itemSelector: '.picture-item', - sizer: element.querySelector('.my-sizer-element'), - }); + this.shuffle = new Shuffle(element, { + itemSelector: '.picture-item', + sizer: element.querySelector('.my-sizer-element'), + }); - // Log events. - this.addShuffleEventListeners(); + // Log events. + this.addShuffleEventListeners(); - this._activeFilters = []; + this._activeFilters = []; - this.addFilterButtons(); - this.addSorting(); - this.addSearchFilter(); + this.addFilterButtons(); + this.addSorting(); + this.addSearchFilter(); - this.mode = 'exclusive'; -}; - -Demo.prototype.toggleMode = function () { - if (this.mode === 'additive') { this.mode = 'exclusive'; - } else { - this.mode = 'additive'; } -}; - -/** - * Shuffle uses the CustomEvent constructor to dispatch events. You can listen - * for them like you normally would (with jQuery for example). - */ -Demo.prototype.addShuffleEventListeners = function () { - this.shuffle.on(Shuffle.EventType.LAYOUT, function (data) { - console.log('layout. data:', data); - }); - - this.shuffle.on(Shuffle.EventType.REMOVED, function (data) { - console.log('removed. data:', data); - }); -}; - -Demo.prototype.addFilterButtons = function () { - var options = document.querySelector('.filter-options'); - - if (!options) { - return; + + toggleMode() { + if (this.mode === 'additive') { + this.mode = 'exclusive'; + } else { + this.mode = 'additive'; + } } - var filterButtons = Array.from(options.children); + /** + * Shuffle uses the CustomEvent constructor to dispatch events. You can listen + * for them like you normally would (with jQuery for example). + */ + addShuffleEventListeners() { + this.shuffle.on(Shuffle.EventType.LAYOUT, (data) => { + console.log('layout. data:', data); + }); + + this.shuffle.on(Shuffle.EventType.REMOVED, (data) => { + console.log('removed. data:', data); + }); + } - filterButtons.forEach(function (button) { - button.addEventListener('click', this._handleFilterClick.bind(this), false); - }, this); -}; + addFilterButtons() { + var options = document.querySelector('.filter-options'); -Demo.prototype._handleFilterClick = function (evt) { - var btn = evt.currentTarget; - var isActive = btn.classList.contains('active'); - var btnGroup = btn.getAttribute('data-group'); + if (!options) { + return; + } - // You don't need _both_ of these modes. This is only for the demo. + var filterButtons = Array.from(options.children); - // For this custom 'additive' mode in the demo, clicking on filter buttons - // doesn't remove any other filters. - if (this.mode === 'additive') { - // If this button is already active, remove it from the list of filters. - if (isActive) { - this._activeFilters.splice(this._activeFilters.indexOf(btnGroup)); - } else { - this._activeFilters.push(btnGroup); - } + filterButtons.forEach((button) => { + button.addEventListener('click', this._handleFilterClick.bind(this), false); + }, this); + } - btn.classList.toggle('active'); + _handleFilterClick(evt) { + var btn = evt.currentTarget; + var isActive = btn.classList.contains('active'); + var btnGroup = btn.getAttribute('data-group'); + + // You don't need _both_ of these modes. This is only for the demo. + // For this custom 'additive' mode in the demo, clicking on filter buttons + // doesn't remove any other filters. + if (this.mode === 'additive') { + // If this button is already active, remove it from the list of filters. + if (isActive) { + this._activeFilters.splice(this._activeFilters.indexOf(btnGroup)); + } else { + this._activeFilters.push(btnGroup); + } - // Filter elements - this.shuffle.filter(this._activeFilters); + btn.classList.toggle('active'); - // 'exclusive' mode lets only one filter button be active at a time. - } else { - this._removeActiveClassFromChildren(btn.parentNode); + // Filter elements + this.shuffle.filter(this._activeFilters); - var filterGroup; - if (isActive) { - btn.classList.remove('active'); - filterGroup = Shuffle.ALL_ITEMS; + // 'exclusive' mode lets only one filter button be active at a time. } else { - btn.classList.add('active'); - filterGroup = btnGroup; - } - - this.shuffle.filter(filterGroup); - } -}; + this._removeActiveClassFromChildren(btn.parentNode); + + var filterGroup; + if (isActive) { + btn.classList.remove('active'); + filterGroup = Shuffle.ALL_ITEMS; + } else { + btn.classList.add('active'); + filterGroup = btnGroup; + } -Demo.prototype._removeActiveClassFromChildren = function (parent) { - var children = parent.children; - for (var i = children.length - 1; i >= 0; i--) { - children[i].classList.remove('active'); + this.shuffle.filter(filterGroup); + } } -}; - -Demo.prototype.addSorting = function () { - var buttonGroup = document.querySelector('.sort-options'); - if (!buttonGroup) { - return; + _removeActiveClassFromChildren(parent) { + var children = parent.children; + for (var i = children.length - 1; i >= 0; i--) { + children[i].classList.remove('active'); + } } - buttonGroup.addEventListener('change', this._handleSortChange.bind(this)); -}; + addSorting() { + var buttonGroup = document.querySelector('.sort-options'); -Demo.prototype._handleSortChange = function (evt) { - // Add and remove `active` class from buttons. - var buttons = Array.from(evt.currentTarget.children); - buttons.forEach(function (button) { - if (button.querySelector('input').value === evt.target.value) { - button.classList.add('active'); - } else { - button.classList.remove('active'); + if (!buttonGroup) { + return; } - }); - // Create the sort options to give to Shuffle. - var value = evt.target.value; - var options = {}; - - function sortByDate(element) { - return Date.parse(element.getAttribute('data-date-created')); + buttonGroup.addEventListener('change', this._handleSortChange.bind(this)); } - function sortByTitle(element) { - return element.getAttribute('data-title').toLowerCase(); - } + _handleSortChange(evt) { + // Add and remove `active` class from buttons. + var buttons = Array.from(evt.currentTarget.children); + buttons.forEach((button) => { + if (button.querySelector('input').value === evt.target.value) { + button.classList.add('active'); + } else { + button.classList.remove('active'); + } + }); - if (value === 'date-created') { - options = { - reverse: true, - by: sortByDate, - }; - } else if (value === 'title') { - options = { - by: sortByTitle, - }; - } + // Create the sort options to give to Shuffle. + var value = evt.target.value; + var options = {}; - this.shuffle.sort(options); -}; + function sortByDate(element) { + return Date.parse(element.getAttribute('data-date-created')); + } -// Advanced filtering -Demo.prototype.addSearchFilter = function () { - var searchInput = document.querySelector('.js-shuffle-search'); + function sortByTitle(element) { + return element.getAttribute('data-title').toLowerCase(); + } - if (!searchInput) { - return; - } + if (value === 'date-created') { + options = { + reverse: true, + by: sortByDate, + }; + } else if (value === 'title') { + options = { + by: sortByTitle, + }; + } - searchInput.addEventListener('input', this._handleSearchKeyup.bind(this)); -}; + this.shuffle.sort(options); + } -/** - * Filter the shuffle instance by items with a title that matches the search input. - * @param {Event} evt Event object. - */ -Demo.prototype._handleSearchKeyup = function (evt) { - var searchText = evt.target.value.toLowerCase(); + // Advanced filtering + addSearchFilter() { + var searchInput = document.querySelector('.js-shuffle-search'); - this.shuffle.filter(function (element, shuffle) { + if (!searchInput) { + return; + } - // If there is a current filter applied, ignore elements that don't match it. - if (shuffle.group !== Shuffle.ALL_ITEMS) { - // Get the item's groups. - var groups = JSON.parse(element.getAttribute('data-groups')); - var isElementInCurrentGroup = groups.indexOf(shuffle.group) !== -1; + searchInput.addEventListener('input', this._handleSearchKeyup.bind(this)); + } - // Only search elements in the current group - if (!isElementInCurrentGroup) { - return false; + /** + * Filter the shuffle instance by items with a title that matches the search input. + * @param {Event} evt Event object. + */ + _handleSearchKeyup(evt) { + var searchText = evt.target.value.toLowerCase(); + + this.shuffle.filter((element, shuffle) => { + // If there is a current filter applied, ignore elements that don't match it. + if (shuffle.group !== Shuffle.ALL_ITEMS) { + // Get the item's groups. + var groups = JSON.parse(element.getAttribute('data-groups')); + var isElementInCurrentGroup = groups.indexOf(shuffle.group) !== -1; + + // Only search elements in the current group + if (!isElementInCurrentGroup) { + return false; + } } - } - var titleElement = element.querySelector('.picture-item__title'); - var titleText = titleElement.textContent.toLowerCase().trim(); + var titleElement = element.querySelector('.picture-item__title'); + var titleText = titleElement.textContent.toLowerCase().trim(); - return titleText.indexOf(searchText) !== -1; - }); -}; + return titleText.indexOf(searchText) !== -1; + }); + } +} -document.addEventListener('DOMContentLoaded', function () { +document.addEventListener('DOMContentLoaded', () => { window.demo = new Demo(document.getElementById('grid')); }); diff --git a/docs/js/demos/react.js b/docs/js/demos/react.js index 2caf955..77759d8 100644 --- a/docs/js/demos/react.js +++ b/docs/js/demos/react.js @@ -25,7 +25,8 @@ class PhotoGrid extends Component { // use that here while waiting on a network request. const grayPixel = 'data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=='; const blackPixel = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='; - const greenPixel = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mO02Vz4HwAE9AJhcLBN6AAAAABJRU5ErkJggg=='; + const greenPixel = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mO02Vz4HwAE9AJhcLBN6AAAAABJRU5ErkJggg=='; this.state = { photos: [ @@ -47,12 +48,42 @@ class PhotoGrid extends Component { return new Promise((resolve) => { setTimeout(() => { resolve([ - { id: 4, username: '@stickermule', name: 'Sticker Mule', src: 'https://images.unsplash.com/photo-1484244233201-29892afe6a2c?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=14d236624576109b51e85bd5d7ebfbfc' }, - { id: 5, username: '@prostoroman', name: 'Roman Logov', src: 'https://images.unsplash.com/photo-1465414829459-d228b58caf6e?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=7a7080fc0699869b1921cb1e7047c5b3' }, - { id: 6, username: '@richienolan', name: 'Richard Nolan', src: 'https://images.unsplash.com/photo-1478033394151-c931d5a4bdd6?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=3c74d594a86e26c5a319f4e17b36146e' }, - { id: 7, username: '@wexor', name: 'Wexor Tmg', src: 'https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=11ff283143c782980861a442a957da8e' }, - { id: 8, username: '@dnevozhai', name: 'Denys Nevozhai', src: 'https://images.unsplash.com/photo-1465447142348-e9952c393450?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=ea06c0f0700ec469fdcb32e0d4c2928e' }, - { id: 9, username: '@aronvandepol', name: 'Aron Van de Pol', src: 'https://images.unsplash.com/photo-1469719847081-4757697d117a?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=9a568bc48e42d3bb60c97c0eb3dc20ac' }, + { + id: 4, + username: '@stickermule', + name: 'Sticker Mule', + src: 'https://images.unsplash.com/photo-1484244233201-29892afe6a2c?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=14d236624576109b51e85bd5d7ebfbfc', + }, + { + id: 5, + username: '@prostoroman', + name: 'Roman Logov', + src: 'https://images.unsplash.com/photo-1465414829459-d228b58caf6e?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=7a7080fc0699869b1921cb1e7047c5b3', + }, + { + id: 6, + username: '@richienolan', + name: 'Richard Nolan', + src: 'https://images.unsplash.com/photo-1478033394151-c931d5a4bdd6?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=3c74d594a86e26c5a319f4e17b36146e', + }, + { + id: 7, + username: '@wexor', + name: 'Wexor Tmg', + src: 'https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=11ff283143c782980861a442a957da8e', + }, + { + id: 8, + username: '@dnevozhai', + name: 'Denys Nevozhai', + src: 'https://images.unsplash.com/photo-1465447142348-e9952c393450?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=ea06c0f0700ec469fdcb32e0d4c2928e', + }, + { + id: 9, + username: '@aronvandepol', + name: 'Aron Van de Pol', + src: 'https://images.unsplash.com/photo-1469719847081-4757697d117a?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=9a568bc48e42d3bb60c97c0eb3dc20ac', + }, ]); }, 300); }); @@ -64,18 +95,23 @@ class PhotoGrid extends Component { * @return {Promise} Loaded images. */ _whenPhotosLoaded(photos) { - return Promise.all(photos.map(photo => new Promise((resolve) => { - const image = document.createElement('img'); - image.src = photo.src; - - if (image.naturalWidth > 0 || image.complete) { - resolve(photo); - } else { - image.onload = () => { - resolve(photo); - }; - } - }))); + return Promise.all( + photos.map( + (photo) => + new Promise((resolve) => { + const image = document.createElement('img'); + image.src = photo.src; + + if (image.naturalWidth > 0 || image.complete) { + resolve(photo); + } else { + image.onload = () => { + resolve(photo); + }; + } + }), + ), + ); } componentDidMount() { @@ -108,7 +144,9 @@ class PhotoGrid extends Component { render() { return (
    - {this.state.photos.map(image => )} + {this.state.photos.map((image) => ( + + ))}
    ); @@ -130,7 +168,7 @@ function PhotoItem({ id, username, src, name }) { - ) + ); } /** diff --git a/docs/js/faq.js b/docs/js/faq.js index 3e1ea42..3a63f28 100644 --- a/docs/js/faq.js +++ b/docs/js/faq.js @@ -1,7 +1,5 @@ -(function () { - 'use strict'; - - var Questions = function () { +class Questions { + constructor() { this.searchInput = document.querySelector('#search'); this.questions = document.querySelectorAll('.js-question'); @@ -15,9 +13,9 @@ window.addEventListener('resize', this.onWindowResize.bind(this)); this.setHeights(); - }; + } - Questions.prototype._handleInput = function (evt) { + _handleInput(evt) { var val = evt.target.value.toLowerCase(); // Filter elements based on if their string exists in the product model @@ -32,27 +30,26 @@ el.classList.remove('question--collapsed'); } } - }; + } - Questions.prototype.setHeights = function () { + setHeights() { var elements = Array.from(this.questions); - elements.forEach(function (element) { + elements.forEach((element) => { element.style.height = ''; }); - var heights = elements.map(function (element) { + var heights = elements.map((element) => { return element.firstElementChild.offsetHeight; }); - elements.forEach(function (element, i) { + elements.forEach((element, i) => { element.style.height = heights[i] + 'px'; }); - }; - - Questions.prototype.onWindowResize = function () { + } + onWindowResize() { this.setHeights(); - }; + } +} - new Questions(); -}()); +new Questions(); diff --git a/docs/js/prism.js b/docs/js/prism.js index f7c0fbe..26adb51 100644 --- a/docs/js/prism.js +++ b/docs/js/prism.js @@ -1,10 +1,11 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */ -var _self = "undefined" != typeof window ? window : "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = function () { var e = /\blang(?:uage)?-(\w+)\b/i, t = 0, n = _self.Prism = { manual: _self.Prism && _self.Prism.manual, util: { encode: function (e) { return e instanceof a ? new a(e.type, n.util.encode(e.content), e.alias) : "Array" === n.util.type(e) ? e.map(n.util.encode) : e.replace(/&/g, "&").replace(/ e.length) return; if (!(w instanceof s)) { h.lastIndex = 0; var _ = h.exec(w), P = 1; if (!_ && m && b != t.length - 1) { if (h.lastIndex = k, _ = h.exec(e), !_) break; for (var A = _.index + (d ? _[1].length : 0), j = _.index + _[0].length, x = b, O = k, S = t.length; S > x && (j > O || !t[x].type && !t[x - 1].greedy); ++x)O += t[x].length, A >= O && (++b, k = O); if (t[b] instanceof s || t[x - 1].greedy) continue; P = x - b, w = e.slice(k, O), _.index -= k } if (_) { d && (p = _[1].length); var A = _.index + p, _ = _[0].slice(p), j = A + _.length, N = w.slice(0, A), C = w.slice(j), E = [b, P]; N && (++b, k += N.length, E.push(N)); var I = new s(u, f ? n.tokenize(_, f) : _, y, _, m); if (E.push(I), C && E.push(C), Array.prototype.splice.apply(t, E), 1 != P && n.matchGrammar(e, t, a, b, k, !0, u), l) break } else if (l) break } } } } }, tokenize: function (e, t) { var a = [e], r = t.rest; if (r) { for (var i in r) t[i] = r[i]; delete t.rest } return n.matchGrammar(e, a, t, 0, 0, !1), a }, hooks: { all: {}, add: function (e, t) { var a = n.hooks.all; a[e] = a[e] || [], a[e].push(t) }, run: function (e, t) { var a = n.hooks.all[e]; if (a && a.length) for (var r, i = 0; r = a[i++];)r(t) } } }, a = n.Token = function (e, t, n, a, r) { this.type = e, this.content = t, this.alias = n, this.length = 0 | (a || "").length, this.greedy = !!r }; if (a.stringify = function (e, t, r) { if ("string" == typeof e) return e; if ("Array" === n.util.type(e)) return e.map(function (n) { return a.stringify(n, t, e) }).join(""); var i = { type: e.type, content: a.stringify(e.content, t, r), tag: "span", classes: ["token", e.type], attributes: {}, language: t, parent: r }; if (e.alias) { var l = "Array" === n.util.type(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(i.classes, l) } n.hooks.run("wrap", i); var o = Object.keys(i.attributes).map(function (e) { return e + '="' + (i.attributes[e] || "").replace(/"/g, """) + '"' }).join(" "); return "<" + i.tag + ' class="' + i.classes.join(" ") + '"' + (o ? " " + o : "") + ">" + i.content + "" }, !_self.document) return _self.addEventListener ? (_self.addEventListener("message", function (e) { var t = JSON.parse(e.data), a = t.language, r = t.code, i = t.immediateClose; _self.postMessage(n.highlight(r, n.languages[a], a)), i && _self.close() }, !1), _self.Prism) : _self.Prism; var r = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); return r && (n.filename = r.src, n.manual || r.hasAttribute("data-manual") || ("loading" !== document.readyState ? window.requestAnimationFrame ? window.requestAnimationFrame(n.highlightAll) : window.setTimeout(n.highlightAll, 16) : document.addEventListener("DOMContentLoaded", n.highlightAll))), _self.Prism }(); "undefined" != typeof module && module.exports && (module.exports = Prism), "undefined" != typeof global && (global.Prism = Prism); -Prism.languages.markup = { comment: //, prolog: /<\?[\s\S]+?\?>/, doctype: //i, cdata: //i, tag: { pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i, inside: { tag: { pattern: /^<\/?[^\s>\/]+/i, inside: { punctuation: /^<\/?/, namespace: /^[^\s>\/:]+:/ } }, "attr-value": { pattern: /=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i, inside: { punctuation: [/^=/, { pattern: /(^|[^\\])["']/, lookbehind: !0 }] } }, punctuation: /\/?>/, "attr-name": { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }, Prism.languages.markup.tag.inside["attr-value"].inside.entity = Prism.languages.markup.entity, Prism.hooks.add("wrap", function (a) { "entity" === a.type && (a.attributes.title = a.content.replace(/&/, "&")) }), Prism.languages.xml = Prism.languages.markup, Prism.languages.html = Prism.languages.markup, Prism.languages.mathml = Prism.languages.markup, Prism.languages.svg = Prism.languages.markup; -Prism.languages.css = { comment: /\/\*[\s\S]*?\*\//, atrule: { pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, inside: { rule: /@[\w-]+/ } }, url: /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, selector: /[^{}\s][^{};]*?(?=\s*\{)/, string: { pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, greedy: !0 }, property: /[\w-]+(?=\s*:)/i, important: /\B!important\b/i, "function": /[-a-z0-9]+(?=\()/i, punctuation: /[(){};:]/ }, Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css), Prism.languages.markup && (Prism.languages.insertBefore("markup", "tag", { style: { pattern: /()[\s\S]*?(?=<\/style>)/i, lookbehind: !0, inside: Prism.languages.css, alias: "language-css" } }), Prism.languages.insertBefore("inside", "attr-value", { "style-attr": { pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, inside: { "attr-name": { pattern: /^\s*style/i, inside: Prism.languages.markup.tag.inside }, punctuation: /^\s*=\s*['"]|['"]\s*$/, "attr-value": { pattern: /.+/i, inside: Prism.languages.css } }, alias: "language-css" } }, Prism.languages.markup.tag)); -Prism.languages.clike = { comment: [{ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, lookbehind: !0 }, { pattern: /(^|[^\\:])\/\/.*/, lookbehind: !0 }], string: { pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, greedy: !0 }, "class-name": { pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i, lookbehind: !0, inside: { punctuation: /[.\\]/ } }, keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, "boolean": /\b(?:true|false)\b/, "function": /[a-z0-9_]+(?=\()/i, number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, operator: /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, punctuation: /[{}[\];(),.:]/ }; -Prism.languages.javascript = Prism.languages.extend("clike", { keyword: /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, number: /\b-?(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+(?:[Ee][+-]?\d+)?|NaN|Infinity)\b/, "function": /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*\()/i, operator: /-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/ }), Prism.languages.insertBefore("javascript", "keyword", { regex: { pattern: /(^|[^\/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, lookbehind: !0, greedy: !0 }, "function-variable": { pattern: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i, alias: "function" } }), Prism.languages.insertBefore("javascript", "string", { "template-string": { pattern: /`(?:\\[\s\S]|[^\\`])*`/, greedy: !0, inside: { interpolation: { pattern: /\$\{[^}]+\}/, inside: { "interpolation-punctuation": { pattern: /^\$\{|\}$/, alias: "punctuation" }, rest: Prism.languages.javascript } }, string: /[\s\S]+/ } } }), Prism.languages.markup && Prism.languages.insertBefore("markup", "tag", { script: { pattern: /()[\s\S]*?(?=<\/script>)/i, lookbehind: !0, inside: Prism.languages.javascript, alias: "language-javascript" } }), Prism.languages.js = Prism.languages.javascript; -!function (a) { var e = a.util.clone(a.languages.javascript); a.languages.jsx = a.languages.extend("markup", e), a.languages.jsx.tag.pattern = /<\/?[\w.:-]+\s*(?:\s+(?:[\w\.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+|(?:\{[^}]*\})))?|\{\.{3}\w+\}))*\s*\/?>/i, a.languages.jsx.tag.inside["attr-value"].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i, a.languages.insertBefore("inside", "attr-name", { spread: { pattern: /\{\.{3}\w+\}/, inside: { punctuation: /[{}]|\.{3}/, "attr-value": /\w+/ } } }, a.languages.jsx.tag); var s = a.util.clone(a.languages.jsx); delete s.punctuation, s = a.languages.insertBefore("jsx", "operator", { punctuation: /=(?={)|[{}[\];(),.:]/ }, { jsx: s }), a.languages.insertBefore("inside", "attr-value", { script: { pattern: /=(\{(?:\{[^}]*\}|[^}])+\})/i, inside: s, alias: "language-javascript" } }, a.languages.jsx.tag) }(Prism); -Prism.languages.scss = Prism.languages.extend("css", { comment: { pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/, lookbehind: !0 }, atrule: { pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/, inside: { rule: /@[\w-]+/ } }, url: /(?:[-a-z]+-)*url(?=\()/i, selector: { pattern: /(?=\S)[^@;{}()]?(?:[^@;{}()]|&|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m, inside: { parent: { pattern: /&/, alias: "important" }, placeholder: /%[-\w]+/, variable: /\$[-\w]+|#\{\$[-\w]+\}/ } } }), Prism.languages.insertBefore("scss", "atrule", { keyword: [/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i, { pattern: /( +)(?:from|through)(?= )/, lookbehind: !0 }] }), Prism.languages.scss.property = { pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/i, inside: { variable: /\$[-\w]+|#\{\$[-\w]+\}/ } }, Prism.languages.insertBefore("scss", "important", { variable: /\$[-\w]+|#\{\$[-\w]+\}/ }), Prism.languages.insertBefore("scss", "function", { placeholder: { pattern: /%[-\w]+/, alias: "selector" }, statement: { pattern: /\B!(?:default|optional)\b/i, alias: "keyword" }, "boolean": /\b(?:true|false)\b/, "null": /\bnull\b/, operator: { pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/, lookbehind: !0 } }), Prism.languages.scss.atrule.inside.rest = Prism.util.clone(Prism.languages.scss); -!function () { function e(e, t) { return Array.prototype.slice.call((t || document).querySelectorAll(e)) } function t(e, t) { return t = " " + t + " ", (" " + e.className + " ").replace(/[\n\t]/g, " ").indexOf(t) > -1 } function n(e, n, i) { for (var o, a = n.replace(/\s+/g, "").split(","), l = +e.getAttribute("data-line-offset") || 0, d = r() ? parseInt : parseFloat, c = d(getComputedStyle(e).lineHeight), s = 0; o = a[s++];) { o = o.split("-"); var u = +o[0], m = +o[1] || u, h = document.createElement("div"); h.textContent = Array(m - u + 2).join(" \n"), h.setAttribute("aria-hidden", "true"), h.className = (i || "") + " line-highlight", t(e, "line-numbers") || (h.setAttribute("data-start", u), m > u && h.setAttribute("data-end", m)), h.style.top = (u - l - 1) * c + "px", t(e, "line-numbers") ? e.appendChild(h) : (e.querySelector("code") || e).appendChild(h) } } function i() { var t = location.hash.slice(1); e(".temporary.line-highlight").forEach(function (e) { e.parentNode.removeChild(e) }); var i = (t.match(/\.([\d,-]+)$/) || [, ""])[1]; if (i && !document.getElementById(t)) { var r = t.slice(0, t.lastIndexOf(".")), o = document.getElementById(r); o && (o.hasAttribute("data-line") || o.setAttribute("data-line", ""), n(o, i, "temporary "), document.querySelector(".temporary.line-highlight").scrollIntoView()) } } if ("undefined" != typeof self && self.Prism && self.document && document.querySelector) { var r = function () { var e; return function () { if ("undefined" == typeof e) { var t = document.createElement("div"); t.style.fontSize = "13px", t.style.lineHeight = "1.5", t.style.padding = 0, t.style.border = 0, t.innerHTML = " 
     ", document.body.appendChild(t), e = 38 === t.offsetHeight, document.body.removeChild(t) } return e } }(), o = 0; Prism.hooks.add("before-sanity-check", function (t) { var n = t.element.parentNode, i = n && n.getAttribute("data-line"); if (n && i && /pre/i.test(n.nodeName)) { var r = 0; e(".line-highlight", n).forEach(function (e) { r += e.textContent.length, e.parentNode.removeChild(e) }), r && /^( \n)+$/.test(t.code.slice(-r)) && (t.code = t.code.slice(0, -r)) } }), Prism.hooks.add("complete", function (e) { var t = e.element.parentNode, r = t && t.getAttribute("data-line"); t && r && /pre/i.test(t.nodeName) && (clearTimeout(o), n(t, r), o = setTimeout(i, 1)) }), window.addEventListener("hashchange", i) } }(); -!function () { "undefined" != typeof self && self.Prism && self.document && document.querySelector && (self.Prism.fileHighlight = function () { var e = { js: "javascript", py: "python", rb: "ruby", ps1: "powershell", psm1: "powershell", sh: "bash", bat: "batch", h: "c", tex: "latex" }; Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function (t) { for (var s, a = t.getAttribute("data-src"), n = t, r = /\blang(?:uage)?-(?!\*)(\w+)\b/i; n && !r.test(n.className);)n = n.parentNode; if (n && (s = (t.className.match(r) || [, ""])[1]), !s) { var o = (a.match(/\.(\w+)$/) || [, ""])[1]; s = e[o] || o } var l = document.createElement("code"); l.className = "language-" + s, t.textContent = "", l.textContent = "Loading…", t.appendChild(l); var i = new XMLHttpRequest; i.open("GET", a, !0), i.onreadystatechange = function () { 4 == i.readyState && (i.status < 400 && i.responseText ? (l.textContent = i.responseText, Prism.highlightElement(l)) : l.textContent = i.status >= 400 ? "✖ Error " + i.status + " while fetching file: " + i.statusText : "✖ Error: File does not exist or is empty") }, i.send(null) }) }, document.addEventListener("DOMContentLoaded", self.Prism.fileHighlight)) }(); +/* PrismJS 1.26.0 +https://prismjs.com/download.html?#themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,e={},M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);y+=m.value.length,m=m.next){var k=m.value;if(t.length>n.length)return;if(!(k instanceof W)){var x,b=1;if(h){if(!(x=z(p,y,n,f))||x.index>=n.length)break;var w=x.index,A=x.index+x[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var E=m;E!==t.tail&&(Pl.reach&&(l.reach=j);var C=m.prev;S&&(C=I(t,C,S),y+=S.length),q(t,C,b);var N=new W(o,g?M.tokenize(L,g):L,d,L);if(m=I(t,C,N),O&&I(t,m,O),1l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function z(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function q(e,n,t){for(var r=n.next,a=0;a"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var r=M.util.currentScript();function a(){M.manual||M.highlightAll()}if(r&&(M.filename=r.src,r.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var l=document.readyState;"loading"===l||"interactive"===l&&r&&r.defer?document.addEventListener("DOMContentLoaded",a):window.requestAnimationFrame?window.requestAnimationFrame(a):window.setTimeout(a,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var t={"included-cdata":{pattern://i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript; +!function(o){var t=o.util.clone(o.languages.javascript),e="(?:\\{*\\.{3}(?:[^{}]|)*\\})";function n(t,n){return t=t.replace(//g,function(){return"(?:\\s|//.*(?!.)|/\\*(?:[^*]|\\*(?!/))\\*/)"}).replace(//g,function(){return"(?:\\{(?:\\{(?:\\{[^{}]*\\}|[^{}])*\\}|[^{}])*\\})"}).replace(//g,function(){return e}),RegExp(t,n)}e=n(e).source,o.languages.jsx=o.languages.extend("markup",t),o.languages.jsx.tag.pattern=n("+(?:[\\w.:$-]+(?:=(?:\"(?:\\\\[^]|[^\\\\\"])*\"|'(?:\\\\[^]|[^\\\\'])*'|[^\\s{'\"/>=]+|))?|))**/?)?>"),o.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,o.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,o.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,o.languages.jsx.tag.inside.comment=t.comment,o.languages.insertBefore("inside","attr-name",{spread:{pattern:n(""),inside:o.languages.jsx}},o.languages.jsx.tag),o.languages.insertBefore("inside","special-attr",{script:{pattern:n("="),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:o.languages.jsx}}},o.languages.jsx.tag);var i=function(t){return t?"string"==typeof t?t:"string"==typeof t.content?t.content:t.content.map(i).join(""):""},r=function(t){for(var n=[],e=0;e"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):0=?|and|not|or)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss; +!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document&&document.querySelector){var t,o="line-numbers",s="linkable-line-numbers",l=function(){if(void 0===t){var e=document.createElement("div");e.style.fontSize="13px",e.style.lineHeight="1.5",e.style.padding="0",e.style.border="0",e.innerHTML=" 
     ",document.body.appendChild(e),t=38===e.offsetHeight,document.body.removeChild(e)}return t},a=!0;Prism.plugins.lineHighlight={highlightLines:function(u,e,c){var t=(e="string"==typeof e?e:u.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),d=+u.getAttribute("data-line-offset")||0,h=(l()?parseInt:parseFloat)(getComputedStyle(u).lineHeight),f=Prism.util.isActive(u,o),i=u.querySelector("code"),p=f?u:i||u,g=[],m=i&&p!=i?function(e,t){var i=getComputedStyle(e),n=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(n.borderTopWidth)+r(n.paddingTop)-r(i.paddingTop)}(u,i):0;t.forEach(function(e){var t=e.split("-"),i=+t[0],n=+t[1]||i,r=u.querySelector('.line-highlight[data-range="'+e+'"]')||document.createElement("div");if(g.push(function(){r.setAttribute("aria-hidden","true"),r.setAttribute("data-range",e),r.className=(c||"")+" line-highlight"}),f&&Prism.plugins.lineNumbers){var o=Prism.plugins.lineNumbers.getLine(u,i),s=Prism.plugins.lineNumbers.getLine(u,n);if(o){var l=o.offsetTop+m+"px";g.push(function(){r.style.top=l})}if(s){var a=s.offsetTop-o.offsetTop+s.offsetHeight+"px";g.push(function(){r.style.height=a})}}else g.push(function(){r.setAttribute("data-start",String(i)),i span",u).forEach(function(e,t){var i=t+r;e.onclick=function(){var e=n+"."+i;a=!1,location.hash=e,setTimeout(function(){a=!0},1)}})}return function(){g.forEach(b)}}};var u=0;Prism.hooks.add("before-sanity-check",function(e){var t=e.element.parentElement;if(c(t)){var i=0;v(".line-highlight",t).forEach(function(e){i+=e.textContent.length,e.parentNode.removeChild(e)}),i&&/^(?: \n)+$/.test(e.code.slice(-i))&&(e.code=e.code.slice(0,-i))}}),Prism.hooks.add("complete",function e(t){var i=t.element.parentElement;if(c(i)){clearTimeout(u);var n=Prism.plugins.lineNumbers,r=t.plugins&&t.plugins.lineNumbers;if(y(i,o)&&n&&!r)Prism.hooks.add("line-numbers",e);else Prism.plugins.lineHighlight.highlightLines(i)(),u=setTimeout(d,1)}}),window.addEventListener("hashchange",d),window.addEventListener("resize",function(){v("pre").filter(c).map(function(e){return Prism.plugins.lineHighlight.highlightLines(e)}).forEach(b)})}function v(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function y(e,t){return e.classList.contains(t)}function b(e){e()}function c(e){return!(!e||!/pre/i.test(e.nodeName))&&(!!e.hasAttribute("data-line")||!(!e.id||!Prism.util.isActive(e,s)))}function d(){var e=location.hash.slice(1);v(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var i=e.slice(0,e.lastIndexOf(".")),n=document.getElementById(i);if(n)n.hasAttribute("data-line")||n.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(n,t,"temporary ")(),a&&document.querySelector(".temporary.line-highlight").scrollIntoView()}}}(); +!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var l={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},o="data-src-status",h="loading",g="loaded",u="pre[data-src]:not(["+o+'="'+g+'"]):not(['+o+'="'+h+'"])';Prism.hooks.add("before-highlightall",function(t){t.selector+=", "+u}),Prism.hooks.add("before-sanity-check",function(t){var r=t.element;if(r.matches(u)){t.code="",r.setAttribute(o,h);var s=r.appendChild(document.createElement("CODE"));s.textContent="Loading…";var e=r.getAttribute("data-src"),i=t.language;if("none"===i){var n=(/\.(\w+)$/.exec(e)||[,"none"])[1];i=l[n]||n}Prism.util.setLanguage(s,i),Prism.util.setLanguage(r,i);var a=Prism.plugins.autoloader;a&&a.loadLanguages(i),function(t,e,i){var n=new XMLHttpRequest;n.open("GET",t,!0),n.onreadystatechange=function(){4==n.readyState&&(n.status<400&&n.responseText?e(n.responseText):400<=n.status?i(function(t,e){return"✖ Error "+t+" while fetching file: "+e}(n.status,n.statusText)):i("✖ Error: File does not exist or is empty"))},n.send(null)}(e,function(t){r.setAttribute(o,g);var e=function(t){var e=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(t||"");if(e){var i=Number(e[1]),n=e[2],a=e[3];return n?a?[i,Number(a)]:[i,void 0]:[i,i]}}(r.getAttribute("data-range"));if(e){var i=t.split(/\r\n?|\n/g),n=e[0],a=null==e[1]?i.length:e[1];n<0&&(n+=i.length),n=Math.max(0,Math.min(n-1,i.length)),a<0&&(a+=i.length),a=Math.max(0,Math.min(a,i.length)),t=i.slice(n,a).join("\n"),r.hasAttribute("data-start")||r.setAttribute("data-start",String(n+1))}s.textContent=t,Prism.highlightElement(s)},function(t){r.setAttribute(o,"failed"),s.textContent=t})}});var t=!(Prism.plugins.fileHighlight={highlight:function(t){for(var e,i=(t||document).querySelectorAll(u),n=0;e=i[n++];)Prism.highlightElement(e)}});Prism.fileHighlight=function(){t||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),t=!0),Prism.plugins.fileHighlight.highlight.apply(this,arguments)}}}(); diff --git a/docs/js/require-main.js b/docs/js/require-main.js index edb4de9..79ff503 100644 --- a/docs/js/require-main.js +++ b/docs/js/require-main.js @@ -2,14 +2,6 @@ requirejs.config({ baseUrl: window.site_url + '/js', paths: { shufflejs: '../dist/shuffle', - polyfill: 'https://polyfill.io/v3/polyfill.min.js?features=default%2Ces5%2Ces6%2Ces7', - }, - - // Load the polyfill before Shuffle. - shim: { - shufflejs: { - deps: ['polyfill'], - }, }, }); diff --git a/docs/js/site-nav.js b/docs/js/site-nav.js index 52f8d2d..04ee0f1 100644 --- a/docs/js/site-nav.js +++ b/docs/js/site-nav.js @@ -1,5 +1,5 @@ -(function () { - var SiteNav = function (element) { +class SiteNav { + constructor(element) { this.element = element; var buttons = Array.from(document.querySelectorAll('.site-nav__link-toggle')); var dropdowns = buttons.map(function (button) { @@ -15,9 +15,9 @@ this.handleResize = this.handleResize.bind(this); window.addEventListener('resize', this.handleResize); window.addEventListener('load', this.handleResize); - }; + } - SiteNav.prototype.toggle = function (event) { + toggle(event) { var button = event.currentTarget; var wrapper = button.parentNode; var willOpen = !wrapper.classList.contains('site-nav__link--dropdown-active'); @@ -36,16 +36,16 @@ } else { document.body.classList.toggle('site-nav--open'); } - }; + } - SiteNav.prototype.handleResize = function () { + handleResize() { var viewportHeight = window.innerHeight; var navHeight = this.element.offsetHeight; var dropdowns = Array.from(document.querySelectorAll('.site-nav__dropdown')); dropdowns.forEach(function (dropdown) { - dropdown.style.maxHeight = (viewportHeight - navHeight) + 'px'; + dropdown.style.maxHeight = viewportHeight - navHeight + 'px'; }); - }; + } +} - new SiteNav(document.querySelector('.site-nav')); -})(); +new SiteNav(document.querySelector('.site-nav')); diff --git a/gulp/config.js b/gulp/config.js index d2f1bbd..48ba55d 100644 --- a/gulp/config.js +++ b/gulp/config.js @@ -9,6 +9,7 @@ const commonjsOptions = { const babelOptions = { exclude: 'node_modules/**', + babelHelpers: 'bundled', }; const minifyOptions = { diff --git a/gulp/tasks/copy-dist.js b/gulp/tasks/copy-dist.js index 8b2fa7c..b9e8895 100644 --- a/gulp/tasks/copy-dist.js +++ b/gulp/tasks/copy-dist.js @@ -2,6 +2,5 @@ const gulp = require('gulp'); // Copy dist directory to docs. GitHub pages don't work with symlinks. module.exports = function copyDist() { - return gulp.src('dist/*') - .pipe(gulp.dest('docs/dist/')); + return gulp.src('dist/*').pipe(gulp.dest('docs/dist/')); }; diff --git a/gulp/tasks/jekyll.js b/gulp/tasks/jekyll.js index f4627f9..cd79f89 100644 --- a/gulp/tasks/jekyll.js +++ b/gulp/tasks/jekyll.js @@ -5,6 +5,5 @@ const shell = require('gulp-shell'); module.exports = function jekyll() { const cmd = 'jekyll serve --config _config.yml,_config_dev.yml'; - return gulp.src('docs/_config.yml', { read: false }) - .pipe(shell([cmd], { cwd: path.join(process.cwd(), 'docs') })); + return gulp.src('docs/_config.yml', { read: false }).pipe(shell([cmd], { cwd: path.join(process.cwd(), 'docs') })); }; diff --git a/gulp/tasks/scripts.js b/gulp/tasks/scripts.js index d8bc7dd..ccc000d 100644 --- a/gulp/tasks/scripts.js +++ b/gulp/tasks/scripts.js @@ -2,10 +2,12 @@ const { rollup } = require('rollup'); const { configs } = require('../config'); module.exports = function scripts() { - const bundles = configs.map(config => rollup(config).then((bundle) => { - config.cache = bundle; - return bundle.write(config.output); - })); + const bundles = configs.map((config) => + rollup(config).then((bundle) => { + config.cache = bundle; + return bundle.write(config.output); + }), + ); return Promise.all(bundles); }; diff --git a/gulp/tasks/test.js b/gulp/tasks/test.js index 1d2b1d6..25b92da 100644 --- a/gulp/tasks/test.js +++ b/gulp/tasks/test.js @@ -2,8 +2,9 @@ const gulp = require('gulp'); const shell = require('gulp-shell'); module.exports = function test() { - return gulp.src('package.json', { - read: false, - }) + return gulp + .src('package.json', { + read: false, + }) .pipe(shell(['npx jest'])); }; diff --git a/gulpfile.js b/gulpfile.js index 4baa726..cfa80af 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,11 +7,6 @@ gulp.task('css', require('./gulp/tasks/css')); gulp.task('jekyll', require('./gulp/tasks/jekyll')); gulp.task('test', require('./gulp/tasks/test')); -gulp.task('watch', gulp.series( - 'set-watching', - gulp.parallel('css', 'scripts'), - 'copy-dist', - 'jekyll', -)); +gulp.task('watch', gulp.series('set-watching', gulp.parallel('css', 'scripts'), 'copy-dist', 'jekyll')); gulp.task('default', gulp.series('scripts', 'css', 'test', 'copy-dist')); diff --git a/index.d.ts b/index.d.ts index 21e1a6b..a7f2e79 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Shuffle 5.2.2 +// Type definitions for Shuffle 6.0.0 // Project: https://github.com/Vestride/Shuffle // Definitions by: Glen Cheney @@ -32,9 +32,6 @@ export interface ShuffleOptions { */ delimiter?: string; - /** @deprecated Misspelling that will be removed in v6 */ - delimeter?: string; - /** * CSS easing function to use. */ diff --git a/package.json b/package.json index 2689ed5..fd1af05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shufflejs", - "version": "5.4.1", + "version": "6.0.0", "description": "Categorize, sort, and filter a responsive grid of items", "keywords": [ "gallery", @@ -47,7 +47,6 @@ ], "dependencies": { "array-parallel": "^0.1.3", - "matches-selector": "^1.0.0", "throttleit": "^1.0.0", "tiny-emitter": "^2.1.0" }, @@ -69,6 +68,7 @@ "gulp-shell": "^0.8.0", "jest": "^27.4.7", "postcss": "^8.4.5", + "prettier": "^2.5.1", "rollup": "^2.66.1", "rollup-plugin-terser": "^7.0.0", "sass": "^1.49.0", diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..d101153 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,7 @@ +module.exports = { + printWidth: 120, + trailingComma: 'all', + semi: true, + tabWidth: 2, + singleQuote: true, +}; diff --git a/src/array-max.js b/src/array-max.js index 2b95a73..91f7d71 100644 --- a/src/array-max.js +++ b/src/array-max.js @@ -1,3 +1,3 @@ export default function arrayMax(array) { - return Math.max.apply(Math, array); // eslint-disable-line prefer-spread + return Math.max(...array); } diff --git a/src/array-min.js b/src/array-min.js index a9828e5..ac99ff5 100644 --- a/src/array-min.js +++ b/src/array-min.js @@ -1,3 +1,3 @@ export default function arrayMin(array) { - return Math.min.apply(Math, array); // eslint-disable-line prefer-spread + return Math.min(...array); } diff --git a/src/get-number-style.js b/src/get-number-style.js index cb0dcc6..299a874 100644 --- a/src/get-number-style.js +++ b/src/get-number-style.js @@ -11,23 +11,22 @@ import testComputedSize from './computed-size'; * will return 'auto' when the element doesn't have margins instead of * the computed style. */ -export default function getNumberStyle( - element, style, - styles = window.getComputedStyle(element, null), -) { +export default function getNumberStyle(element, style, styles = window.getComputedStyle(element, null)) { let value = getNumber(styles[style]); // Support IE<=11 and W3C spec. if (!testComputedSize() && style === 'width') { - value += getNumber(styles.paddingLeft) - + getNumber(styles.paddingRight) - + getNumber(styles.borderLeftWidth) - + getNumber(styles.borderRightWidth); + value += + getNumber(styles.paddingLeft) + + getNumber(styles.paddingRight) + + getNumber(styles.borderLeftWidth) + + getNumber(styles.borderRightWidth); } else if (!testComputedSize() && style === 'height') { - value += getNumber(styles.paddingTop) - + getNumber(styles.paddingBottom) - + getNumber(styles.borderTopWidth) - + getNumber(styles.borderBottomWidth); + value += + getNumber(styles.paddingTop) + + getNumber(styles.paddingBottom) + + getNumber(styles.borderTopWidth) + + getNumber(styles.borderBottomWidth); } return value; diff --git a/src/layout.js b/src/layout.js index e091c71..100404f 100644 --- a/src/layout.js +++ b/src/layout.js @@ -100,9 +100,7 @@ export function getShortColumn(positions, buffer) { * @param {number} buffer Vertical buffer for the height of items. * @return {Point} */ -export function getItemPosition({ - itemSize, positions, gridSize, total, threshold, buffer, -}) { +export function getItemPosition({ itemSize, positions, gridSize, total, threshold, buffer }) { const span = getColumnSpan(itemSize.width, gridSize, total, threshold); const setY = getAvailablePositions(positions, span, total); const shortColumnIndex = getShortColumn(setY, buffer); @@ -183,13 +181,15 @@ export function getCenteredPositions(itemRects, containerWidth) { // elements could be in the way). if (!canMove) { let intersectingRect; - const hasOverlap = itemRects.some((itemRect) => rects.some((r) => { - const intersects = Rect.intersects(itemRect, r); - if (intersects) { - intersectingRect = r; - } - return intersects; - })); + const hasOverlap = itemRects.some((itemRect) => + rects.some((r) => { + const intersects = Rect.intersects(itemRect, r); + if (intersects) { + intersectingRect = r; + } + return intersects; + }), + ); // If there is any overlap, replace the overlapping row with the original. if (hasOverlap) { @@ -206,7 +206,8 @@ export function getCenteredPositions(itemRects, containerWidth) { // https://stackoverflow.com/a/10865042/373422 // Then reset sort back to how the items were passed to this method. // Remove the wrapper object with index, map to a Point. - return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread - .sort((a, b) => (a.id - b.id)) + return centeredRows + .flat() + .sort((a, b) => a.id - b.id) .map((itemRect) => new Point(itemRect.left, itemRect.top)); } diff --git a/src/rect.js b/src/rect.js index 71c5a65..785769b 100644 --- a/src/rect.js +++ b/src/rect.js @@ -33,7 +33,7 @@ export default class Rect { */ static intersects(a, b) { return ( - a.left < b.left + b.width && b.left < a.left + a.width - && a.top < b.top + b.height && b.top < a.top + a.height); + a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height + ); } } diff --git a/src/shuffle-item.js b/src/shuffle-item.js index 6f04c56..b5f9a6c 100644 --- a/src/shuffle-item.js +++ b/src/shuffle-item.js @@ -69,11 +69,7 @@ class ShuffleItem { } dispose() { - this.removeClasses([ - Classes.HIDDEN, - Classes.VISIBLE, - Classes.SHUFFLE_ITEM, - ]); + this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); this.element.removeAttribute('style'); this.element = null; diff --git a/src/shuffle.js b/src/shuffle.js index b2f9330..ea94d98 100644 --- a/src/shuffle.js +++ b/src/shuffle.js @@ -1,5 +1,4 @@ import TinyEmitter from 'tiny-emitter'; -import matches from 'matches-selector'; import throttle from 'throttleit'; import parallel from 'array-parallel'; @@ -31,14 +30,7 @@ class Shuffle extends TinyEmitter { */ constructor(element, options = {}) { super(); - // eslint-disable-next-line prefer-object-spread - 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.options = { ...Shuffle.options, ...options }; this.lastSort = {}; this.group = Shuffle.ALL_ITEMS; @@ -327,7 +319,7 @@ class Shuffle extends TinyEmitter { _getItems() { return Array.from(this.element.children) - .filter((el) => matches(el, this.options.itemSelector)) + .filter((el) => el.matches(this.options.itemSelector)) .map((el) => new ShuffleItem(el, this.options.isRTL)); } @@ -641,8 +633,7 @@ class Shuffle extends TinyEmitter { */ getStylesForTransition(item, styleObject) { // Clone the object to avoid mutating the original. - // eslint-disable-next-line prefer-object-spread - const styles = Object.assign({}, styleObject); + const styles = { ...styleObject }; if (this.options.useTransforms) { const sign = this.options.isRTL ? '-' : ''; diff --git a/src/sorter.js b/src/sorter.js index 4631f57..bb34b8c 100644 --- a/src/sorter.js +++ b/src/sorter.js @@ -44,8 +44,7 @@ const defaults = { * @return {Array} */ export default function sorter(arr, options) { - // eslint-disable-next-line prefer-object-spread - const opts = Object.assign({}, defaults, options); + const opts = { ...defaults, ...options }; const original = Array.from(arr); let revert = false; diff --git a/test/test.js b/test/test.js index 2fe16cb..e3f08af 100644 --- a/test/test.js +++ b/test/test.js @@ -623,15 +623,6 @@ describe('shuffle', () => { expect(instance.visibleItems).toBe(3); }); - - it('can use the old misspelled delimiter option', () => { - instance = new Shuffle(fixture, { - delimeter: ',', - group: 'design', - }); - - expect(instance.visibleItems).toBe(3); - }); }); describe('Custom shuffle item styles', () => { diff --git a/test/types/tsconfig.json b/test/types/tsconfig.json index 99eef74..5ca5f8a 100644 --- a/test/types/tsconfig.json +++ b/test/types/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "target": "ES2018" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, // "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ @@ -12,7 +12,7 @@ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./build", /* Redirect output structure to the directory. */ + "outDir": "./build" /* Redirect output structure to the directory. */, // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ @@ -23,14 +23,14 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* Enable strict null checks. */ - "strictFunctionTypes": true, /* Enable strict checking of function types. */ - "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + "strict": true /* Enable all strict type-checking options. */, + "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, + "strictNullChecks": true /* Enable strict null checks. */, + "strictFunctionTypes": true /* Enable strict checking of function types. */, + "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */, + "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, + "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, + "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ @@ -39,14 +39,14 @@ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */