PageSourceSearch

https://lechateaudeforbin.com/wp-content/plugins/hoteller-elementor/assets/js/flickity.pkgd.js?ver=7.1

js lechateaudeforbin.com collected 2026-10-05 07:57:48 UTC 120,012 bytes, 4,607 lines download raw bytes

vendor: 16,358 bytes, lines 1-668
1/*!
2 * Flickity PACKAGED v2.2.2
3 * Touch, responsive, flickable carousels
4 *
5 * Licensed GPLv3 for open source use
6 * or Flickity Commercial License for commercial use
7 *
8 * https://flickity.metafizzy.co
9 * Copyright 2015-2021 Metafizzy
10 */
11
12/**
13 * Bridget makes jQuery widgets
14 * v2.0.1
15 * MIT license
16 */
17
18/* jshint browser: true, strict: true, undef: true, unused: true */
19
20( function( window, factory ) {
21  // universal module definition
22  /*jshint strict: false */ /* globals define, module, require */
23  if ( typeof define == 'function' && define.amd ) {
24    // AMD
25    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
26      return factory( window, jQuery );
27    });
28  } else if ( typeof module == 'object' && module.exports ) {
29    // CommonJS
30    module.exports = factory(
31      window,
32      require('jquery')
33    );
34  } else {
35    // browser global
36    window.jQueryBridget = factory(
37      window,
38      window.jQuery
39    );
40  }
41
42}( window, function factory( window, jQuery ) {
43'use strict';
44
45// ----- utils ----- //
46
47var arraySlice = Array.prototype.slice;
48
49// helper function for logging errors
50// $.error breaks jQuery chaining
51var console = window.console;
52var logError = typeof console == 'undefined' ? function() {} :
53  function( message ) {
54    console.error( message );
55  };
56
57// ----- jQueryBridget ----- //
58
59function jQueryBridget( namespace, PluginClass, $ ) {
60  $ = $ || jQuery || window.jQuery;
61  if ( !$ ) {
62    return;
63  }
64
65  // add option method -> $().plugin('option', {...})
66  if ( !PluginClass.prototype.option ) {
67    // option setter
68    PluginClass.prototype.option = function( opts ) {
69      // bail out if not an object
70      if ( !$.isPlainObject( opts ) ){
71        return;
72      }
73      this.options = $.extend( true, this.options, opts );
74    };
75  }
76
77  // make jQuery plugin
78  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
79    if ( typeof arg0 == 'string' ) {
80      // method call $().plugin( 'methodName', { options } )
81      // shift arguments by 1
82      var args = arraySlice.call( arguments, 1 );
83      return methodCall( this, arg0, args );
84    }
85    // just $().plugin({ options })
86    plainCall( this, arg0 );
87    return this;
88  };
89
90  // $().plugin('methodName')
91  function methodCall( $elems, methodName, args ) {
92    var returnValue;
93    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
94
95    $elems.each( function( i, elem ) {
96      // get instance
97      var instance = $.data( elem, namespace );
98      if ( !instance ) {
99        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
100          pluginMethodStr );
101        return;
102      }
103
104      var method = instance[ methodName ];
105      if ( !method || methodName.charAt(0) == '_' ) {
106        logError( pluginMethodStr + ' is not a valid method' );
107        return;
108      }
109
110      // apply method, get return value
111      var value = method.apply( instance, args );
112      // set return value if value is returned, use only first value
113      returnValue = returnValue === undefined ? value : returnValue;
114    });
115
116    return returnValue !== undefined ? returnValue : $elems;
117  }
118
119  function plainCall( $elems, options ) {
120    $elems.each( function( i, elem ) {
121      var instance = $.data( elem, namespace );
122      if ( instance ) {
123        // set options & init
124        instance.option( options );
125        instance._init();
126      } else {
127        // initialize new instance
128        instance = new PluginClass( elem, options );
129        $.data( elem, namespace, instance );
130      }
131    });
132  }
133
134  updateJQuery( $ );
135
136}
137
138// ----- updateJQuery ----- //
139
140// set $.bridget for v1 backwards compatibility
141function updateJQuery( $ ) {
142  if ( !$ || ( $ && $.bridget ) ) {
143    return;
144  }
145  $.bridget = jQueryBridget;
146}
147
148updateJQuery( jQuery || window.jQuery );
149
150// -----  ----- //
151
152return jQueryBridget;
153
154}));
155
156/**
157 * EvEmitter v1.1.0
158 * Lil' event emitter
159 * MIT License
160 */
161
162/* jshint unused: true, undef: true, strict: true */
163
164( function( global, factory ) {
165  // universal module definition
166  /* jshint strict: false */ /* globals define, module, window */
167  if ( typeof define == 'function' && define.amd ) {
168    // AMD - RequireJS
169    define( 'ev-emitter/ev-emitter',factory );
170  } else if ( typeof module == 'object' && module.exports ) {
171    // CommonJS - Browserify, Webpack
172    module.exports = factory();
173  } else {
174    // Browser globals
175    global.EvEmitter = factory();
176  }
177
178}( typeof window != 'undefined' ? window : this, function() {
179
180
181
182function EvEmitter() {}
183
184var proto = EvEmitter.prototype;
185
186proto.on = function( eventName, listener ) {
187  if ( !eventName || !listener ) {
188    return;
189  }
190  // set events hash
191  var events = this._events = this._events || {};
192  // set listeners array
193  var listeners = events[ eventName ] = events[ eventName ] || [];
194  // only add once
195  if ( listeners.indexOf( listener ) == -1 ) {
196    listeners.push( listener );
197  }
198
199  return this;
200};
201
202proto.once = function( eventName, listener ) {
203  if ( !eventName || !listener ) {
204    return;
205  }
206  // add event
207  this.on( eventName, listener );
208  // set once flag
209  // set onceEvents hash
210  var onceEvents = this._onceEvents = this._onceEvents || {};
211  // set onceListeners object
212  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
213  // set flag
214  onceListeners[ listener ] = true;
215
216  return this;
217};
218
219proto.off = function( eventName, listener ) {
220  var listeners = this._events && this._events[ eventName ];
221  if ( !listeners || !listeners.length ) {
222    return;
223  }
224  var index = listeners.indexOf( listener );
225  if ( index != -1 ) {
226    listeners.splice( index, 1 );
227  }
228
229  return this;
230};
231
232proto.emitEvent = function( eventName, args ) {
233  var listeners = this._events && this._events[ eventName ];
234  if ( !listeners || !listeners.length ) {
235    return;
236  }
237  // copy over to avoid interference if .off() in listener
238  listeners = listeners.slice(0);
239  args = args || [];
240  // once stuff
241  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
242
243  for ( var i=0; i < listeners.length; i++ ) {
244    var listener = listeners[i]
245    var isOnce = onceListeners && onceListeners[ listener ];
246    if ( isOnce ) {
247      // remove listener
248      // remove before trigger to prevent recursion
249      this.off( eventName, listener );
250      // unset once flag
251      delete onceListeners[ listener ];
252    }
253    // trigger listener
254    listener.apply( this, args );
255  }
256
257  return this;
258};
259
260proto.allOff = function() {
261  delete this._events;
262  delete this._onceEvents;
263};
264
265return EvEmitter;
266
267}));
268
269/*!
270 * getSize v2.0.3
271 * measure size of elements
272 * MIT license
273 */
274
275/* jshint browser: true, strict: true, undef: true, unused: true */
276/* globals console: false */
277
278( function( window, factory ) {
279  /* jshint strict: false */ /* globals define, module */
280  if ( typeof define == 'function' && define.amd ) {
281    // AMD
282    define( 'get-size/get-size',factory );
283  } else if ( typeof module == 'object' && module.exports ) {
284    // CommonJS
285    module.exports = factory();
286  } else {
287    // browser global
288    window.getSize = factory();
289  }
290
291})( window, function factory() {
292'use strict';
293
294// -------------------------- helpers -------------------------- //
295
296// get a number from a string, not a percentage
297function getStyleSize( value ) {
298  var num = parseFloat( value );
299  // not a percent like '100%', and a number
300  var isValid = value.indexOf('%') == -1 && !isNaN( num );
301  return isValid && num;
302}
303
304function noop() {}
305
306var logError = typeof console == 'undefined' ? noop :
307  function( message ) {
308    console.error( message );
309  };
310
311// -------------------------- measurements -------------------------- //
312
313var measurements = [
314  'paddingLeft',
315  'paddingRight',
316  'paddingTop',
317  'paddingBottom',
318  'marginLeft',
319  'marginRight',
320  'marginTop',
321  'marginBottom',
322  'borderLeftWidth',
323  'borderRightWidth',
324  'borderTopWidth',
325  'borderBottomWidth'
326];
327
328var measurementsLength = measurements.length;
329
330function getZeroSize() {
331  var size = {
332    width: 0,
333    height: 0,
334    innerWidth: 0,
335    innerHeight: 0,
336    outerWidth: 0,
337    outerHeight: 0
338  };
339  for ( var i=0; i < measurementsLength; i++ ) {
340    var measurement = measurements[i];
341    size[ measurement ] = 0;
342  }
343  return size;
344}
345
346// -------------------------- getStyle -------------------------- //
347
348/**
349 * getStyle, get style of element, check for Firefox bug
350 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
351 */
352function getStyle( elem ) {
353  var style = getComputedStyle( elem );
354  if ( !style ) {
355    logError( 'Style returned ' + style +
356      '. Are you running this code in a hidden iframe on Firefox? ' +
357      'See https://bit.ly/getsizebug1' );
358  }
359  return style;
360}
361
362// -------------------------- setup -------------------------- //
363
364var isSetup = false;
365
366var isBoxSizeOuter;
367
368/**
369 * setup
370 * check isBoxSizerOuter
371 * do on first getSize() rather than on page load for Firefox bug
372 */
373function setup() {
374  // setup once
375  if ( isSetup ) {
376    return;
377  }
378  isSetup = true;
379
380  // -------------------------- box sizing -------------------------- //
381
382  /**
383   * Chrome & Safari measure the outer-width on style.width on border-box elems
384   * IE11 & Firefox<29 measures the inner-width
385   */
386  var div = document.createElement('div');
387  div.style.width = '200px';
388  div.style.padding = '1px 2px 3px 4px';
389  div.style.borderStyle = 'solid';
390  div.style.borderWidth = '1px 2px 3px 4px';
391  div.style.boxSizing = 'border-box';
392
393  var body = document.body || document.documentElement;
394  body.appendChild( div );
395  var style = getStyle( div );
396  // round value for browser zoom. desandro/masonry#928
397  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
398  getSize.isBoxSizeOuter = isBoxSizeOuter;
399
400  body.removeChild( div );
401}
402
403// -------------------------- getSize -------------------------- //
404
405function getSize( elem ) {
406  setup();
407
408  // use querySeletor if elem is string
409  if ( typeof elem == 'string' ) {
410    elem = document.querySelector( elem );
411  }
412
413  // do not proceed on non-objects
414  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
415    return;
416  }
417
418  var style = getStyle( elem );
419
420  // if hidden, everything is 0
421  if ( style.display == 'none' ) {
422    return getZeroSize();
423  }
424
425  var size = {};
426  size.width = elem.offsetWidth;
427  size.height = elem.offsetHeight;
428
429  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
430
431  // get all measurements
432  for ( var i=0; i < measurementsLength; i++ ) {
433    var measurement = measurements[i];
434    var value = style[ measurement ];
435    var num = parseFloat( value );
436    // any 'auto', 'medium' value will be 0
437    size[ measurement ] = !isNaN( num ) ? num : 0;
438  }
439
440  var paddingWidth = size.paddingLeft + size.paddingRight;
441  var paddingHeight = size.paddingTop + size.paddingBottom;
442  var marginWidth = size.marginLeft + size.marginRight;
443  var marginHeight = size.marginTop + size.marginBottom;
444  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
445  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
446
447  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
448
449  // overwrite width and height if we can get it from style
450  var styleWidth = getStyleSize( style.width );
451  if ( styleWidth !== false ) {
452    size.width = styleWidth +
453      // add padding and border unless it's already including it
454      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
455  }
456
457  var styleHeight = getStyleSize( style.height );
458  if ( styleHeight !== false ) {
459    size.height = styleHeight +
460      // add padding and border unless it's already including it
461      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
462  }
463
464  size.innerWidth = size.width - ( paddingWidth + borderWidth );
465  size.innerHeight = size.height - ( paddingHeight + borderHeight );
466
467  size.outerWidth = size.width + marginWidth;
468  size.outerHeight = size.height + marginHeight;
469
470  return size;
471}
472
473return getSize;
474
475});
476
477/**
478 * matchesSelector v2.0.2
479 * matchesSelector( element, '.selector' )
480 * MIT license
481 */
482
483/*jshint browser: true, strict: true, undef: true, unused: true */
484
485( function( window, factory ) {
486  /*global define: false, module: false */
487  'use strict';
488  // universal module definition
489  if ( typeof define == 'function' && define.amd ) {
490    // AMD
491    define( 'desandro-matches-selector/matches-selector',factory );
492  } else if ( typeof module == 'object' && module.exports ) {
493    // CommonJS
494    module.exports = factory();
495  } else {
496    // browser global
497    window.matchesSelector = factory();
498  }
499
500}( window, function factory() {
501  'use strict';
502
503  var matchesMethod = ( function() {
504    var ElemProto = window.Element.prototype;
505    // check for the standard method name first
506    if ( ElemProto.matches ) {
507      return 'matches';
508    }
509    // check un-prefixed
510    if ( ElemProto.matchesSelector ) {
511      return 'matchesSelector';
512    }
513    // check vendor prefixes
514    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
515
516    for ( var i=0; i < prefixes.length; i++ ) {
517      var prefix = prefixes[i];
518      var method = prefix + 'MatchesSelector';
519      if ( ElemProto[ method ] ) {
520        return method;
521      }
522    }
523  })();
524
525  return function matchesSelector( elem, selector ) {
526    return elem[ matchesMethod ]( selector );
527  };
528
529}));
530
531/**
532 * Fizzy UI utils v2.0.7
533 * MIT license
534 */
535
536/*jshint browser: true, undef: true, unused: true, strict: true */
537
538( function( window, factory ) {
539  // universal module definition
540  /*jshint strict: false */ /*globals define, module, require */
541
542  if ( typeof define == 'function' && define.amd ) {
543    // AMD
544    define( 'fizzy-ui-utils/utils',[
545      'desandro-matches-selector/matches-selector'
546    ], function( matchesSelector ) {
547      return factory( window, matchesSelector );
548    });
549  } else if ( typeof module == 'object' && module.exports ) {
550    // CommonJS
551    module.exports = factory(
552      window,
553      require('desandro-matches-selector')
554    );
555  } else {
556    // browser global
557    window.fizzyUIUtils = factory(
558      window,
559      window.matchesSelector
560    );
561  }
562
563}( window, function factory( window, matchesSelector ) {
564
565
566
567var utils = {};
568
569// ----- extend ----- //
570
571// extends objects
572utils.extend = function( a, b ) {
573  for ( var prop in b ) {
574    a[ prop ] = b[ prop ];
575  }
576  return a;
577};
578
579// ----- modulo ----- //
580
581utils.modulo = function( num, div ) {
582  return ( ( num % div ) + div ) % div;
583};
584
585// ----- makeArray ----- //
586
587var arraySlice = Array.prototype.slice;
588
589// turn element or nodeList into an array
590utils.makeArray = function( obj ) {
591  if ( Array.isArray( obj ) ) {
592    // use object if already an array
593    return obj;
594  }
595  // return empty array if undefined or null. #6
596  if ( obj === null || obj === undefined ) {
597    return [];
598  }
599
600  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
601  if ( isArrayLike ) {
602    // convert nodeList to array
603    return arraySlice.call( obj );
604  }
605
606  // array of single index
607  return [ obj ];
608};
609
610// ----- removeFrom ----- //
611
612utils.removeFrom = function( ary, obj ) {
613  var index = ary.indexOf( obj );
614  if ( index != -1 ) {
615    ary.splice( index, 1 );
616  }
617};
618
619// ----- getParent ----- //
620
621utils.getParent = function( elem, selector ) {
622  while ( elem.parentNode && elem != document.body ) {
623    elem = elem.parentNode;
624    if ( matchesSelector( elem, selector ) ) {
625      return elem;
626    }
627  }
628};
629
630// ----- getQueryElement ----- //
631
632// use element as selector string
633utils.getQueryElement = function( elem ) {
634  if ( typeof elem == 'string' ) {
635    return document.querySelector( elem );
636  }
637  return elem;
638};
639
640// ----- handleEvent ----- //
641
642// enable .ontype to trigger from .addEventListener( elem, 'type' )
643utils.handleEvent = function( event ) {
644  var method = 'on' + event.type;
645  if ( this[ method ] ) {
646    this[ method ]( event );
647  }
648};
649
650// ----- filterFindElements ----- //
651
652utils.filterFindElements = function (elems, selector) {
653  // make array of elems
654  elems = utils.makeArray(elems);
655  var ffElems = [];
656
657  /**
658  *
659  *  ThemeGoods fix for Elementor backend
660  *
661  **/
662  
663  var isElement = function (elem) {
664    return (
665      typeof HTMLElement === "object" ? elem instanceof HTMLElement : elem && typeof elem === "object" && elem !== null && elem.nodeType === 1 && typeof elem.nodeName === "string"
666    );
667  };
668
669  elems.forEach(function (elem) {
670    // check that elem is an actual element
671    if (!isElement(elem)) {
672      return;
673    }
674    // add elem if no selector
675    if (!selector) {
676      ffElems.push(elem);
677      return;
678    }
679    // filter & find items if we have a selector
680    // filter
681    if (matchesSelector(elem, selector)) {
682      ffElems.push(elem);
683    }
684    // find children
685    var childElems = elem.querySelectorAll(selector);
686    // concat childElems to filterFound array
687    for (var i = 0; i < childElems.length; i++) {
688      ffElems.push(childElems[i]);
689    }
690  });
691
692  return ffElems;
693};
694
695// ----- debounceMethod ----- //
696
697utils.debounceMethod = function( _class, methodName, threshold ) {
698  threshold = threshold || 100;
699  // original method
700  var method = _class.prototype[ methodName ];
701  var timeoutName = methodName + 'Timeout';
702
703  _class.prototype[ methodName ] = function() {
704    var timeout = this[ timeoutName ];
705    clearTimeout( timeout );
706
707    var args = arguments;
708    var _this = this;
709    this[ timeoutName ] = setTimeout( function() {
710      method.apply( _this, args );
711      delete _this[ timeoutName ];
712    }, threshold );
713  };
714};
715
716// ----- docReady ----- //
717
718utils.docReady = function( callback ) {
719  var readyState = document.readyState;
720  if ( readyState == 'complete' || readyState == 'interactive' ) {
721    // do async to allow for other scripts to run. metafizzy/flickity#441
722    setTimeout( callback );
723  } else {
724    document.addEventListener( 'DOMContentLoaded', callback );
725  }
726};
727
728// ----- htmlInit ----- //
729
730// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
731utils.toDashed = function( str ) {
732  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
733    return $1 + '-' + $2;
734  }).toLowerCase();
735};
736
737var console = window.console;
738/**
739 * allow user to initialize classes via [data-namespace] or .js-namespace class
740 * htmlInit( Widget, 'widgetName' )
741 * options are parsed from data-namespace-options
742 */
743utils.htmlInit = function( WidgetClass, namespace ) {
744  utils.docReady( function() {
745    var dashedNamespace = utils.toDashed( namespace );
746    var dataAttr = 'data-' + dashedNamespace;
747    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
748    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
749    var elems = utils.makeArray( dataAttrElems )
750      .concat( utils.makeArray( jsDashElems ) );
751    var dataOptionsAttr = dataAttr + '-options';
752    var jQuery = window.jQuery;
753
754    elems.forEach( function( elem ) {
755      var attr = elem.getAttribute( dataAttr ) ||
756        elem.getAttribute( dataOptionsAttr );
757      var options;
758      try {
759        options = attr && JSON.parse( attr );
760      } catch ( error ) {
761        // log error, do not initialize
762        if ( console ) {
763          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
764          ': ' + error );
765        }
766        return;
767      }
768      // initialize
769      var instance = new WidgetClass( elem, options );
770      // make available via $().data('namespace')
771      if ( jQuery ) {
772        jQuery.data( elem, namespace, instance );
773      }
774    });
775
776  });
777};
778
779// -----  ----- //
780
781return utils;
782
783}));
784
785// Flickity.Cell
786( function( window, factory ) {
787  // universal module definition
788  if ( typeof define == 'function' && define.amd ) {
789    // AMD
790    define( 'flickity/js/cell',[
791      'get-size/get-size',
792    ], function( getSize ) {
793      return factory( window, getSize );
794    } );
795  } else if ( typeof module == 'object' && module.exports ) {
796    // CommonJS
797    module.exports = factory(
798        window,
799        require('get-size')
800    );
801  } else {
802    // browser global
803    window.Flickity = window.Flickity || {};
804    window.Flickity.Cell = factory(
805        window,
806        window.getSize
807    );
808  }
809
810}( window, function factory( window, getSize ) {
811
812
813
814function Cell( elem, parent ) {
815  this.element = elem;
816  this.parent = parent;
817
818  this.create();
819}
820
821var proto = Cell.prototype;
822
823proto.create = function() {
824  this.element.style.position = 'absolute';
825  this.element.setAttribute( 'aria-hidden', 'true' );
826  this.x = 0;
827  this.shift = 0;
828};
829
830proto.destroy = function() {
831  // reset style
832  this.unselect();
833  this.element.style.position = '';
834  var side = this.parent.originSide;
835  this.element.style[ side ] = '';
836  this.element.removeAttribute('aria-hidden');
837};
838
839proto.getSize = function() {
840  this.size = getSize( this.element );
841};
842
843proto.setPosition = function( x ) {
844  this.x = x;
845  this.updateTarget();
846  this.renderPosition( x );
847};
848
849// setDefaultTarget v1 method, backwards compatibility, remove in v3
850proto.updateTarget = proto.setDefaultTarget = function() {
851  var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight';
852  this.target = this.x + this.size[ marginProperty ] +
853    this.size.width * this.parent.cellAlign;
854};
855
856proto.renderPosition = function( x ) {
857  // render position of cell with in slider
858  var side = this.parent.originSide;
859  this.element.style[ side ] = this.parent.getPositionValue( x );
860};
861
862proto.select = function() {
863  this.element.classList.add('is-selected');
864  this.element.removeAttribute('aria-hidden');
865};
866
867proto.unselect = function() {
868  this.element.classList.remove('is-selected');
869  this.element.setAttribute( 'aria-hidden', 'true' );
870};
871
872/**
873 * @param {Integer} shift - 0, 1, or -1
874 */
875proto.wrapShift = function( shift ) {
876  this.shift = shift;
877  this.renderPosition( this.x + this.parent.slideableWidth * shift );
878};
879
880proto.remove = function() {
881  this.element.parentNode.removeChild( this.element );
882};
883
884return Cell;
885
886} ) );
887
888// slide
889( function( window, factory ) {
890  // universal module definition
891  if ( typeof define == 'function' && define.amd ) {
892    // AMD
893    define( 'flickity/js/slide',factory );
894  } else if ( typeof module == 'object' && module.exports ) {
895    // CommonJS
896    module.exports = factory();
897  } else {
898    // browser global
899    window.Flickity = window.Flickity || {};
900    window.Flickity.Slide = factory();
901  }
902
903}( window, function factory() {
904'use strict';
905
906function Slide( parent ) {
907  this.parent = parent;
908  this.isOriginLeft = parent.originSide == 'left';
909  this.cells = [];
910  this.outerWidth = 0;
911  this.height = 0;
912}
913
914var proto = Slide.prototype;
915
916proto.addCell = function( cell ) {
917  this.cells.push( cell );
918  this.outerWidth += cell.size.outerWidth;
919  this.height = Math.max( cell.size.outerHeight, this.height );
920  // first cell stuff
921  if ( this.cells.length == 1 ) {
922    this.x = cell.x; // x comes from first cell
923    var beginMargin = this.isOriginLeft ? 'marginLeft' : 'marginRight';
924    this.firstMargin = cell.size[ beginMargin ];
925  }
926};
927
928proto.updateTarget = function() {
929  var endMargin = this.isOriginLeft ? 'marginRight' : 'marginLeft';
930  var lastCell = this.getLastCell();
931  var lastMargin = lastCell ? lastCell.size[ endMargin ] : 0;
932  var slideWidth = this.outerWidth - ( this.firstMargin + lastMargin );
933  this.target = this.x + this.firstMargin + slideWidth * this.parent.cellAlign;
934};
935
936proto.getLastCell = function() {
937  return this.cells[ this.cells.length - 1 ];
938};
939
940proto.select = function() {
941  this.cells.forEach( function( cell ) {
942    cell.select();
943  } );
944};
945
946proto.unselect = function() {
947  this.cells.forEach( function( cell ) {
948    cell.unselect();
949  } );
950};
951
952proto.getCellElements = function() {
953  return this.cells.map( function( cell ) {
954    return cell.element;
955  } );
956};
957
958return Slide;
959
960} ) );
961
962// animate
963( function( window, factory ) {
964  // universal module definition
965  if ( typeof define == 'function' && define.amd ) {
966    // AMD
967    define( 'flickity/js/animate',[
968      'fizzy-ui-utils/utils',
969    ], function( utils ) {
970      return factory( window, utils );
971    } );
972  } else if ( typeof module == 'object' && module.exports ) {
973    // CommonJS
974    module.exports = factory(
975        window,
976        require('fizzy-ui-utils')
977    );
978  } else {
979    // browser global
980    window.Flickity = window.Flickity || {};
981    window.Flickity.animatePrototype = factory(
982        window,
983        window.fizzyUIUtils
984    );
985  }
986
987}( window, function factory( window, utils ) {
988
989
990
991// -------------------------- animate -------------------------- //
992
993var proto = {};
994
995proto.startAnimation = function() {
996  if ( this.isAnimating ) {
997    return;
998  }
999
1000  this.isAnimating = true;
1001  this.restingFrames = 0;
1002  this.animate();
1003};
1004
1005proto.animate = function() {
1006  this.applyDragForce();
1007  this.applySelectedAttraction();
1008
1009  var previousX = this.x;
1010
1011  this.integratePhysics();
1012  this.positionSlider();
1013  this.settle( previousX );
1014  // animate next frame
1015  if ( this.isAnimating ) {
1016    var _this = this;
1017    requestAnimationFrame( function animateFrame() {
1018      _this.animate();
1019    } );
1020  }
1021};
1022
1023proto.positionSlider = function() {
1024  var x = this.x;
1025  // wrap position around
1026  if ( this.options.wrapAround && this.cells.length > 1 ) {
1027    x = utils.modulo( x, this.slideableWidth );
1028    x -= this.slideableWidth;
1029    this.shiftWrapCells( x );
1030  }
1031
1032  this.setTranslateX( x, this.isAnimating );
1033  this.dispatchScrollEvent();
1034};
1035
1036proto.setTranslateX = function( x, is3d ) {
1037  x += this.cursorPosition;
1038  // reverse if right-to-left and using transform
1039  x = this.options.rightToLeft ? -x : x;
1040  var translateX = this.getPositionValue( x );
1041  // use 3D transforms for hardware acceleration on iOS
1042  // but use 2D when settled, for better font-rendering
1043  this.slider.style.transform = is3d ?
1044    'translate3d(' + translateX + ',0,0)' : 'translateX(' + translateX + ')';
1045};
1046
1047proto.dispatchScrollEvent = function() {
1048  var firstSlide = this.slides[0];
1049  if ( !firstSlide ) {
1050    return;
1051  }
1052  var positionX = -this.x - firstSlide.target;
1053  var progress = positionX / this.slidesWidth;
1054  this.dispatchEvent( 'scroll', null, [ progress, positionX ] );
1055};
1056
1057proto.positionSliderAtSelected = function() {
1058  if ( !this.cells.length ) {
1059    return;
1060  }
1061  this.x = -this.selectedSlide.target;
1062  this.velocity = 0; // stop wobble
1063  this.positionSlider();
1064};
1065
1066proto.getPositionValue = function( position ) {
1067  if ( this.options.percentPosition ) {
1068    // percent position, round to 2 digits, like 12.34%
1069    return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 ) + '%';
1070  } else {
1071    // pixel positioning
1072    return Math.round( position ) + 'px';
1073  }
1074};
1075
1076proto.settle = function( previousX ) {
1077  // keep track of frames where x hasn't moved
1078  var isResting = !this.isPointerDown &&
1079      Math.round( this.x * 100 ) == Math.round( previousX * 100 );
1080  if ( isResting ) {
1081    this.restingFrames++;
1082  }
1083  // stop animating if resting for 3 or more frames
1084  if ( this.restingFrames > 2 ) {
1085    this.isAnimating = false;
1086    delete this.isFreeScrolling;
1087    // render position with translateX when settled
1088    this.positionSlider();
1089    this.dispatchEvent( 'settle', null, [ this.selectedIndex ] );
1090  }
1091};
1092
1093proto.shiftWrapCells = function( x ) {
1094  // shift before cells
1095  var beforeGap = this.cursorPosition + x;
1096  this._shiftCells( this.beforeShiftCells, beforeGap, -1 );
1097  // shift after cells
1098  var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition );
1099  this._shiftCells( this.afterShiftCells, afterGap, 1 );
1100};
1101
1102proto._shiftCells = function( cells, gap, shift ) {
1103  for ( var i = 0; i < cells.length; i++ ) {
1104    var cell = cells[i];
1105    var cellShift = gap > 0 ? shift : 0;
1106    cell.wrapShift( cellShift );
1107    gap -= cell.size.outerWidth;
1108  }
1109};
1110
1111proto._unshiftCells = function( cells ) {
1112  if ( !cells || !cells.length ) {
1113    return;
1114  }
1115  for ( var i = 0; i < cells.length; i++ ) {
1116    cells[i].wrapShift( 0 );
1117  }
1118};
1119
1120// -------------------------- physics -------------------------- //
1121
1122proto.integratePhysics = function() {
1123  this.x += this.velocity;
1124  this.velocity *= this.getFrictionFactor();
1125};
1126
1127proto.applyForce = function( force ) {
1128  this.velocity += force;
1129};
1130
1131proto.getFrictionFactor = function() {
1132  return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ];
1133};
1134
1135proto.getRestingPosition = function() {
1136  // my thanks to Steven Wittens, who simplified this math greatly
1137  return this.x + this.velocity / ( 1 - this.getFrictionFactor() );
1138};
1139
1140proto.applyDragForce = function() {
1141  if ( !this.isDraggable || !this.isPointerDown ) {
1142    return;
1143  }
1144  // change the position to drag position by applying force
1145  var dragVelocity = this.dragX - this.x;
1146  var dragForce = dragVelocity - this.velocity;
1147  this.applyForce( dragForce );
1148};
1149
1150proto.applySelectedAttraction = function() {
1151  // do not attract if pointer down or no slides
1152  var dragDown = this.isDraggable && this.isPointerDown;
1153  if ( dragDown || this.isFreeScrolling || !this.slides.length ) {
1154    return;
1155  }
1156  var distance = this.selectedSlide.target * -1 - this.x;
1157  var force = distance * this.options.selectedAttraction;
1158  this.applyForce( force );
1159};
1160
1161return proto;
1162
1163} ) );
1164
1165// Flickity main
1166/* eslint-disable max-params */
1167( function( window, factory ) {
1168  // universal module definition
1169  if ( typeof define == 'function' && define.amd ) {
1170    // AMD
1171    define( 'flickity/js/flickity',[
1172      'ev-emitter/ev-emitter',
1173      'get-size/get-size',
1174      'fizzy-ui-utils/utils',
1175      './cell',
1176      './slide',
1177      './animate',
1178    ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) {
1179      return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype );
1180    } );
1181  } else if ( typeof module == 'object' && module.exports ) {
1182    // CommonJS
1183    module.exports = factory(
1184        window,
1185        require('ev-emitter'),
1186        require('get-size'),
1187        require('fizzy-ui-utils'),
1188        require('./cell'),
1189        require('./slide'),
1190        require('./animate')
1191    );
1192  } else {
1193    // browser global
1194    var _Flickity = window.Flickity;
1195
1196    window.Flickity = factory(
1197        window,
1198        window.EvEmitter,
1199        window.getSize,
1200        window.fizzyUIUtils,
1201        _Flickity.Cell,
1202        _Flickity.Slide,
1203        _Flickity.animatePrototype
1204    );
1205  }
1206
1207}( window, function factory( window, EvEmitter, getSize,
1208    utils, Cell, Slide, animatePrototype ) {
1209
1210/* eslint-enable max-params */
1211
1212
1213// vars
1214var jQuery = window.jQuery;
1215var getComputedStyle = window.getComputedStyle;
1216var console = window.console;
1217
1218function moveElements( elems, toElem ) {
1219  elems = utils.makeArray( elems );
1220  while ( elems.length ) {
1221    toElem.appendChild( elems.shift() );
1222  }
1223}
1224
1225// -------------------------- Flickity -------------------------- //
1226
1227// globally unique identifiers
1228var GUID = 0;
1229// internal store of all Flickity intances
1230var instances = {};
1231
1232function Flickity( element, options ) {
1233  var queryElement = utils.getQueryElement( element );
1234  if ( !queryElement ) {
1235    if ( console ) {
1236      console.error( 'Bad element for Flickity: ' + ( queryElement || element ) );
1237    }
1238    return;
1239  }
1240  this.element = queryElement;
1241  // do not initialize twice on same element
1242  if ( this.element.flickityGUID ) {
1243    var instance = instances[ this.element.flickityGUID ];
1244    if ( instance ) instance.option( options );
1245    return instance;
1246  }
1247
1248  // add jQuery
1249  if ( jQuery ) {
1250    this.$element = jQuery( this.element );
1251  }
1252  // options
1253  this.options = utils.extend( {}, this.constructor.defaults );
1254  this.option( options );
1255
1256  // kick things off
1257  this._create();
1258}
1259
1260Flickity.defaults = {
1261  accessibility: true,
1262  // adaptiveHeight: false,
1263  cellAlign: 'center',
1264  // cellSelector: undefined,
1265  // contain: false,
1266  freeScrollFriction: 0.075, // friction when free-scrolling
1267  friction: 0.28, // friction when selecting
1268  namespaceJQueryEvents: true,
1269  // initialIndex: 0,
1270  percentPosition: true,
1271  resize: true,
1272  selectedAttraction: 0.025,
1273  setGallerySize: true,
1274  // watchCSS: false,
1275  // wrapAround: false
1276};
1277
1278// hash of methods triggered on _create()
1279Flickity.createMethods = [];
1280
1281var proto = Flickity.prototype;
1282// inherit EventEmitter
1283utils.extend( proto, EvEmitter.prototype );
1284
1285proto._create = function() {
1286  // add id for Flickity.data
1287  var id = this.guid = ++GUID;
1288  this.element.flickityGUID = id; // expando
1289  instances[ id ] = this; // associate via id
1290  // initial properties
1291  this.selectedIndex = 0;
1292  // how many frames slider has been in same position
1293  this.restingFrames = 0;
1294  // initial physics properties
1295  this.x = 0;
1296  this.velocity = 0;
1297  this.originSide = this.options.rightToLeft ? 'right' : 'left';
1298  // create viewport & slider
1299  this.viewport = document.createElement('div');
1300  this.viewport.className = 'flickity-viewport';
1301  this._createSlider();
1302
1303  if ( this.options.resize || this.options.watchCSS ) {
1304    window.addEventListener( 'resize', this );
1305  }
1306
1307  // add listeners from on option
1308  for ( var eventName in this.options.on ) {
1309    var listener = this.options.on[ eventName ];
1310    this.on( eventName, listener );
1311  }
1312
1313  Flickity.createMethods.forEach( function( method ) {
1314    this[ method ]();
1315  }, this );
1316
1317  if ( this.options.watchCSS ) {
1318    this.watchCSS();
1319  } else {
1320    this.activate();
1321  }
1322
1323};
1324
1325/**
1326 * set options
1327 * @param {Object} opts - options to extend
1328 */
1329proto.option = function( opts ) {
1330  utils.extend( this.options, opts );
1331};
1332
1333proto.activate = function() {
1334  if ( this.isActive ) {
1335    return;
1336  }
1337  this.isActive = true;
1338  this.element.classList.add('flickity-enabled');
1339  if ( this.options.rightToLeft ) {
1340    this.element.classList.add('flickity-rtl');
1341  }
1342
1343  this.getSize();
1344  // move initial cell elements so they can be loaded as cells
1345  var cellElems = this._filterFindCellElements( this.element.children );
1346  moveElements( cellElems, this.slider );
1347  this.viewport.appendChild( this.slider );
1348  this.element.appendChild( this.viewport );
1349  // get cells from children
1350  this.reloadCells();
1351
1352  if ( this.options.accessibility ) {
1353    // allow element to focusable
1354    this.element.tabIndex = 0;
1355    // listen for key presses
1356    this.element.addEventListener( 'keydown', this );
1357  }
1358
1359  this.emitEvent('activate');
1360  this.selectInitialIndex();
1361  // flag for initial activation, for using initialIndex
1362  this.isInitActivated = true;
1363  // ready event. #493
1364  this.dispatchEvent('ready');
1365};
1366
1367// slider positions the cells
1368proto._createSlider = function() {
1369  // slider element does all the positioning
1370  var slider = document.createElement('div');
1371  slider.className = 'flickity-slider';
1372  slider.style[ this.originSide ] = 0;
1373  this.slider = slider;
1374};
1375
1376proto._filterFindCellElements = function( elems ) {
1377  return utils.filterFindElements( elems, this.options.cellSelector );
1378};
1379
1380// goes through all children
1381proto.reloadCells = function() {
1382  // collection of item elements
1383  this.cells = this._makeCells( this.slider.children );
1384  this.positionCells();
1385  this._getWrapShiftCells();
1386  this.setGallerySize();
1387};
1388
1389/**
1390 * turn elements into Flickity.Cells
1391 * @param {[Array, NodeList, HTMLElement]} elems - elements to make into cells
1392 * @returns {Array} items - collection of new Flickity Cells
1393 */
1394proto._makeCells = function( elems ) {
1395  var cellElems = this._filterFindCellElements( elems );
1396
1397  // create new Flickity for collection
1398  var cells = cellElems.map( function( cellElem ) {
1399    return new Cell( cellElem, this );
1400  }, this );
1401
1402  return cells;
1403};
1404
1405proto.getLastCell = function() {
1406  return this.cells[ this.cells.length - 1 ];
1407};
1408
1409proto.getLastSlide = function() {
1410  return this.slides[ this.slides.length - 1 ];
1411};
1412
1413// positions all cells
1414proto.positionCells = function() {
1415  // size all cells
1416  this._sizeCells( this.cells );
1417  // position all cells
1418  this._positionCells( 0 );
1419};
1420
1421/**
1422 * position certain cells
1423 * @param {Integer} index - which cell to start with
1424 */
1425proto._positionCells = function( index ) {
1426  index = index || 0;
1427  // also measure maxCellHeight
1428  // start 0 if positioning all cells
1429  this.maxCellHeight = index ? this.maxCellHeight || 0 : 0;
1430  var cellX = 0;
1431  // get cellX
1432  if ( index > 0 ) {
1433    var startCell = this.cells[ index - 1 ];
1434    cellX = startCell.x + startCell.size.outerWidth;
1435  }
1436  var len = this.cells.length;
1437  for ( var i = index; i < len; i++ ) {
1438    var cell = this.cells[i];
1439    cell.setPosition( cellX );
1440    cellX += cell.size.outerWidth;
1441    this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight );
1442  }
1443  // keep track of cellX for wrap-around
1444  this.slideableWidth = cellX;
1445  // slides
1446  this.updateSlides();
1447  // contain slides target
1448  this._containSlides();
1449  // update slidesWidth
1450  this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0;
1451};
1452
1453/**
1454 * cell.getSize() on multiple cells
1455 * @param {Array} cells - cells to size
1456 */
1457proto._sizeCells = function( cells ) {
1458  cells.forEach( function( cell ) {
1459    cell.getSize();
1460  } );
1461};
1462
1463// --------------------------  -------------------------- //
1464
1465proto.updateSlides = function() {
1466  this.slides = [];
1467  if ( !this.cells.length ) {
1468    return;
1469  }
1470
1471  var slide = new Slide( this );
1472  this.slides.push( slide );
1473  var isOriginLeft = this.originSide == 'left';
1474  var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft';
1475
1476  var canCellFit = this._getCanCellFit();
1477
1478  this.cells.forEach( function( cell, i ) {
1479    // just add cell if first cell in slide
1480    if ( !slide.cells.length ) {
1481      slide.addCell( cell );
1482      return;
1483    }
1484
1485    var slideWidth = ( slide.outerWidth - slide.firstMargin ) +
1486      ( cell.size.outerWidth - cell.size[ nextMargin ] );
1487
1488    if ( canCellFit.call( this, i, slideWidth ) ) {
1489      slide.addCell( cell );
1490    } else {
1491      // doesn't fit, new slide
1492      slide.updateTarget();
1493
1494      slide = new Slide( this );
1495      this.slides.push( slide );
1496      slide.addCell( cell );
1497    }
1498  }, this );
1499  // last slide
1500  slide.updateTarget();
1501  // update .selectedSlide
1502  this.updateSelectedSlide();
1503};
1504
1505proto._getCanCellFit = function() {
1506  var groupCells = this.options.groupCells;
1507  if ( !groupCells ) {
1508    return function() {
1509      return false;
1510    };
1511  } else if ( typeof groupCells == 'number' ) {
1512    // group by number. 3 -> [0,1,2], [3,4,5], ...
1513    var number = parseInt( groupCells, 10 );
1514    return function( i ) {
1515      return ( i % number ) !== 0;
1516    };
1517  }
1518  // default, group by width of slide
1519  // parse '75%
1520  var percentMatch = typeof groupCells == 'string' &&
1521    groupCells.match( /^(\d+)%$/ );
1522  var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1;
1523  return function( i, slideWidth ) {
1524    /* eslint-disable-next-line no-invalid-this */
1525    return slideWidth <= ( this.size.innerWidth + 1 ) * percent;
1526  };
1527};
1528
1529// alias _init for jQuery plugin .flickity()
1530proto._init =
1531proto.reposition = function() {
1532  this.positionCells();
1533  this.positionSliderAtSelected();
1534};
1535
1536proto.getSize = function() {
1537  this.size = getSize( this.element );
1538  this.setCellAlign();
1539  this.cursorPosition = this.size.innerWidth * this.cellAlign;
1540};
1541
1542var cellAlignShorthands = {
1543  // cell align, then based on origin side
1544  center: {
1545    left: 0.5,
1546    right: 0.5,
1547  },
1548  left: {
1549    left: 0,
1550    right: 1,
1551  },
1552  right: {
1553    right: 0,
1554    left: 1,
1555  },
1556};
1557
1558proto.setCellAlign = function() {
1559  var shorthand = cellAlignShorthands[ this.options.cellAlign ];
1560  this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign;
1561};
1562
1563proto.setGallerySize = function() {
1564  if ( this.options.setGallerySize ) {
1565    var height = this.options.adaptiveHeight && this.selectedSlide ?
1566      this.selectedSlide.height : this.maxCellHeight;
1567    this.viewport.style.height = height + 'px';
1568  }
1569};
1570
1571proto._getWrapShiftCells = function() {
1572  // only for wrap-around
1573  if ( !this.options.wrapAround ) {
1574    return;
1575  }
1576  // unshift previous cells
1577  this._unshiftCells( this.beforeShiftCells );
1578  this._unshiftCells( this.afterShiftCells );
1579  // get before cells
1580  // initial gap
1581  var gapX = this.cursorPosition;
1582  var cellIndex = this.cells.length - 1;
1583  this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 );
1584  // get after cells
1585  // ending gap between last cell and end of gallery viewport
1586  gapX = this.size.innerWidth - this.cursorPosition;
1587  // start cloning at first cell, working forwards
1588  this.afterShiftCells = this._getGapCells( gapX, 0, 1 );
1589};
1590
1591proto._getGapCells = function( gapX, cellIndex, increment ) {
1592  // keep adding cells until the cover the initial gap
1593  var cells = [];
1594  while ( gapX > 0 ) {
1595    var cell = this.cells[ cellIndex ];
1596    if ( !cell ) {
1597      break;
1598    }
1599    cells.push( cell );
1600    cellIndex += increment;
1601    gapX -= cell.size.outerWidth;
1602  }
1603  return cells;
1604};
1605
1606// ----- contain ----- //
1607
1608// contain cell targets so no excess sliding
1609proto._containSlides = function() {
1610  if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) {
1611    return;
1612  }
1613  var isRightToLeft = this.options.rightToLeft;
1614  var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft';
1615  var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight';
1616  var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ];
1617  // content is less than gallery size
1618  var isContentSmaller = contentWidth < this.size.innerWidth;
1619  // bounds
1620  var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ];
1621  var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign );
1622  // contain each cell target
1623  this.slides.forEach( function( slide ) {
1624    if ( isContentSmaller ) {
1625      // all cells fit inside gallery
1626      slide.target = contentWidth * this.cellAlign;
1627    } else {
1628      // contain to bounds
1629      slide.target = Math.max( slide.target, beginBound );
1630      slide.target = Math.min( slide.target, endBound );
1631    }
1632  }, this );
1633};
1634
1635// -----  ----- //
1636
1637/**
1638 * emits events via eventEmitter and jQuery events
1639 * @param {String} type - name of event
1640 * @param {Event} event - original event
1641 * @param {Array} args - extra arguments
1642 */
1643proto.dispatchEvent = function( type, event, args ) {
1644  var emitArgs = event ? [ event ].concat( args ) : args;
1645  this.emitEvent( type, emitArgs );
1646
1647  if ( jQuery && this.$element ) {
1648    // default trigger with type if no event
1649    type += this.options.namespaceJQueryEvents ? '.flickity' : '';
1650    var $event = type;
1651    if ( event ) {
1652      // create jQuery event
1653      var jQEvent = new jQuery.Event( event );
1654      jQEvent.type = type;
1655      $event = jQEvent;
1656    }
1657    this.$element.trigger( $event, args );
1658  }
1659};
1660
1661// -------------------------- select -------------------------- //
1662
1663/**
1664 * @param {Integer} index - index of the slide
1665 * @param {Boolean} isWrap - will wrap-around to last/first if at the end
1666 * @param {Boolean} isInstant - will immediately set position at selected cell
1667 */
1668proto.select = function( index, isWrap, isInstant ) {
1669  if ( !this.isActive ) {
1670    return;
1671  }
1672  index = parseInt( index, 10 );
1673  this._wrapSelect( index );
1674
1675  if ( this.options.wrapAround || isWrap ) {
1676    index = utils.modulo( index, this.slides.length );
1677  }
1678  // bail if invalid index
1679  if ( !this.slides[ index ] ) {
1680    return;
1681  }
1682  var prevIndex = this.selectedIndex;
1683  this.selectedIndex = index;
1684  this.updateSelectedSlide();
1685  if ( isInstant ) {
1686    this.positionSliderAtSelected();
1687  } else {
1688    this.startAnimation();
1689  }
1690  if ( this.options.adaptiveHeight ) {
1691    this.setGallerySize();
1692  }
1693  // events
1694  this.dispatchEvent( 'select', null, [ index ] );
1695  // change event if new index
1696  if ( index != prevIndex ) {
1697    this.dispatchEvent( 'change', null, [ index ] );
1698  }
1699  // old v1 event name, remove in v3
1700  this.dispatchEvent('cellSelect');
1701};
1702
1703// wraps position for wrapAround, to move to closest slide. #113
1704proto._wrapSelect = function( index ) {
1705  var len = this.slides.length;
1706  var isWrapping = this.options.wrapAround && len > 1;
1707  if ( !isWrapping ) {
1708    return index;
1709  }
1710  var wrapIndex = utils.modulo( index, len );
1711  // go to shortest
1712  var delta = Math.abs( wrapIndex - this.selectedIndex );
1713  var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex );
1714  var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex );
1715  if ( !this.isDragSelect && backWrapDelta < delta ) {
1716    index += len;
1717  } else if ( !this.isDragSelect && forewardWrapDelta < delta ) {
1718    index -= len;
1719  }
1720  // wrap position so slider is within normal area
1721  if ( index < 0 ) {
1722    this.x -= this.slideableWidth;
1723  } else if ( index >= len ) {
1724    this.x += this.slideableWidth;
1725  }
1726};
1727
1728proto.previous = function( isWrap, isInstant ) {
1729  this.select( this.selectedIndex - 1, isWrap, isInstant );
1730};
1731
1732proto.next = function( isWrap, isInstant ) {
1733  this.select( this.selectedIndex + 1, isWrap, isInstant );
1734};
1735
1736proto.updateSelectedSlide = function() {
1737  var slide = this.slides[ this.selectedIndex ];
1738  // selectedIndex could be outside of slides, if triggered before resize()
1739  if ( !slide ) {
1740    return;
1741  }
1742  // unselect previous selected slide
1743  this.unselectSelectedSlide();
1744  // update new selected slide
1745  this.selectedSlide = slide;
1746  slide.select();
1747  this.selectedCells = slide.cells;
1748  this.selectedElements = slide.getCellElements();
1749  // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility
1750  // Remove in v3?
1751  this.selectedCell = slide.cells[0];
1752  this.selectedElement = this.selectedElements[0];
1753};
1754
1755proto.unselectSelectedSlide = function() {
1756  if ( this.selectedSlide ) {
1757    this.selectedSlide.unselect();
1758  }
1759};
1760
1761proto.selectInitialIndex = function() {
1762  var initialIndex = this.options.initialIndex;
1763  // already activated, select previous selectedIndex
1764  if ( this.isInitActivated ) {
1765    this.select( this.selectedIndex, false, true );
1766    return;
1767  }
1768  // select with selector string
1769  if ( initialIndex && typeof initialIndex == 'string' ) {
1770    var cell = this.queryCell( initialIndex );
1771    if ( cell ) {
1772      this.selectCell( initialIndex, false, true );
1773      return;
1774    }
1775  }
1776
1777  var index = 0;
1778  // select with number
1779  if ( initialIndex && this.slides[ initialIndex ] ) {
1780    index = initialIndex;
1781  }
1782  // select instantly
1783  this.select( index, false, true );
1784};
1785
1786/**
1787 * select slide from number or cell element
1788 * @param {[Element, Number]} value - zero-based index or element to select
1789 * @param {Boolean} isWrap - enables wrapping around for extra index
1790 * @param {Boolean} isInstant - disables slide animation
1791 */
1792proto.selectCell = function( value, isWrap, isInstant ) {
1793  // get cell
1794  var cell = this.queryCell( value );
1795  if ( !cell ) {
1796    return;
1797  }
1798
1799  var index = this.getCellSlideIndex( cell );
1800  this.select( index, isWrap, isInstant );
1801};
1802
1803proto.getCellSlideIndex = function( cell ) {
1804  // get index of slides that has cell
1805  for ( var i = 0; i < this.slides.length; i++ ) {
1806    var slide = this.slides[i];
1807    var index = slide.cells.indexOf( cell );
1808    if ( index != -1 ) {
1809      return i;
1810    }
1811  }
1812};
1813
1814// -------------------------- get cells -------------------------- //
1815
1816/**
1817 * get Flickity.Cell, given an Element
1818 * @param {Element} elem - matching cell element
1819 * @returns {Flickity.Cell} cell - matching cell
1820 */
1821proto.getCell = function( elem ) {
1822  // loop through cells to get the one that matches
1823  for ( var i = 0; i < this.cells.length; i++ ) {
1824    var cell = this.cells[i];
1825    if ( cell.element == elem ) {
1826      return cell;
1827    }
1828  }
1829};
1830
1831/**
1832 * get collection of Flickity.Cells, given Elements
1833 * @param {[Element, Array, NodeList]} elems - multiple elements
1834 * @returns {Array} cells - Flickity.Cells
1835 */
1836proto.getCells = function( elems ) {
1837  elems = utils.makeArray( elems );
1838  var cells = [];
vendor: 5,319 bytes, lines 1839-2038
1839  elems.forEach( function( elem ) {
1840    var cell = this.getCell( elem );
1841    if ( cell ) {
1842      cells.push( cell );
1843    }
1844  }, this );
1845  return cells;
1846};
1847
1848/**
1849 * get cell elements
1850 * @returns {Array} cellElems
1851 */
1852proto.getCellElements = function() {
1853  return this.cells.map( function( cell ) {
1854    return cell.element;
1855  } );
1856};
1857
1858/**
1859 * get parent cell from an element
1860 * @param {Element} elem - child element
1861 * @returns {Flickit.Cell} cell - parent cell
1862 */
1863proto.getParentCell = function( elem ) {
1864  // first check if elem is cell
1865  var cell = this.getCell( elem );
1866  if ( cell ) {
1867    return cell;
1868  }
1869  // try to get parent cell elem
1870  elem = utils.getParent( elem, '.flickity-slider > *' );
1871  return this.getCell( elem );
1872};
1873
1874/**
1875 * get cells adjacent to a slide
1876 * @param {Integer} adjCount - number of adjacent slides
1877 * @param {Integer} index - index of slide to start
1878 * @returns {Array} cells - array of Flickity.Cells
1879 */
1880proto.getAdjacentCellElements = function( adjCount, index ) {
1881  if ( !adjCount ) {
1882    return this.selectedSlide.getCellElements();
1883  }
1884  index = index === undefined ? this.selectedIndex : index;
1885
1886  var len = this.slides.length;
1887  if ( 1 + ( adjCount * 2 ) >= len ) {
1888    return this.getCellElements();
1889  }
1890
1891  var cellElems = [];
1892  for ( var i = index - adjCount; i <= index + adjCount; i++ ) {
1893    var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i;
1894    var slide = this.slides[ slideIndex ];
1895    if ( slide ) {
1896      cellElems = cellElems.concat( slide.getCellElements() );
1897    }
1898  }
1899  return cellElems;
1900};
1901
1902/**
1903 * select slide from number or cell element
1904 * @param {[Element, String, Number]} selector - element, selector string, or index
1905 * @returns {Flickity.Cell} - matching cell
1906 */
1907proto.queryCell = function( selector ) {
1908  if ( typeof selector == 'number' ) {
1909    // use number as index
1910    return this.cells[ selector ];
1911  }
1912  if ( typeof selector == 'string' ) {
1913    // do not select invalid selectors from hash: #123, #/. #791
1914    if ( selector.match( /^[#.]?[\d/]/ ) ) {
1915      return;
1916    }
1917    // use string as selector, get element
1918    selector = this.element.querySelector( selector );
1919  }
1920  // get cell from element
1921  return this.getCell( selector );
1922};
1923
1924// -------------------------- events -------------------------- //
1925
1926proto.uiChange = function() {
1927  this.emitEvent('uiChange');
1928};
1929
1930// keep focus on element when child UI elements are clicked
1931proto.childUIPointerDown = function( event ) {
1932  // HACK iOS does not allow touch events to bubble up?!
1933  if ( event.type != 'touchstart' ) {
1934    event.preventDefault();
1935  }
1936  this.focus();
1937};
1938
1939// ----- resize ----- //
1940
1941proto.onresize = function() {
1942  this.watchCSS();
1943  this.resize();
1944};
1945
1946utils.debounceMethod( Flickity, 'onresize', 150 );
1947
1948proto.resize = function() {
1949  if ( !this.isActive ) {
1950    return;
1951  }
1952  this.getSize();
1953  // wrap values
1954  if ( this.options.wrapAround ) {
1955    this.x = utils.modulo( this.x, this.slideableWidth );
1956  }
1957  this.positionCells();
1958  this._getWrapShiftCells();
1959  this.setGallerySize();
1960  this.emitEvent('resize');
1961  // update selected index for group slides, instant
1962  // TODO: position can be lost between groups of various numbers
1963  var selectedElement = this.selectedElements && this.selectedElements[0];
1964  this.selectCell( selectedElement, false, true );
1965};
1966
1967// watches the :after property, activates/deactivates
1968proto.watchCSS = function() {
1969  var watchOption = this.options.watchCSS;
1970  if ( !watchOption ) {
1971    return;
1972  }
1973
1974  var afterContent = getComputedStyle( this.element, ':after' ).content;
1975  // activate if :after { content: 'flickity' }
1976  if ( afterContent.indexOf('flickity') != -1 ) {
1977    this.activate();
1978  } else {
1979    this.deactivate();
1980  }
1981};
1982
1983// ----- keydown ----- //
1984
1985// go previous/next if left/right keys pressed
1986proto.onkeydown = function( event ) {
1987  // only work if element is in focus
1988  var isNotFocused = document.activeElement && document.activeElement != this.element;
1989  if ( !this.options.accessibility || isNotFocused ) {
1990    return;
1991  }
1992
1993  var handler = Flickity.keyboardHandlers[ event.keyCode ];
1994  if ( handler ) {
1995    handler.call( this );
1996  }
1997};
1998
1999Flickity.keyboardHandlers = {
2000  // left arrow
2001  37: function() {
2002    var leftMethod = this.options.rightToLeft ? 'next' : 'previous';
2003    this.uiChange();
2004    this[ leftMethod ]();
2005  },
2006  // right arrow
2007  39: function() {
2008    var rightMethod = this.options.rightToLeft ? 'previous' : 'next';
2009    this.uiChange();
2010    this[ rightMethod ]();
2011  },
2012};
2013
2014// ----- focus ----- //
2015
2016proto.focus = function() {
2017  // TODO remove scrollTo once focus options gets more support
2018  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus ...
2019  //    #Browser_compatibility
2020  var prevScrollY = window.pageYOffset;
2021  this.element.focus({ preventScroll: true });
2022  // hack to fix scroll jump after focus, #76
2023  if ( window.pageYOffset != prevScrollY ) {
2024    window.scrollTo( window.pageXOffset, prevScrollY );
2025  }
2026};
2027
2028// -------------------------- destroy -------------------------- //
2029
2030// deactivate all Flickity functionality, but keep stuff available
2031proto.deactivate = function() {
2032  if ( !this.isActive ) {
2033    return;
2034  }
2035  this.element.classList.remove('flickity-enabled');
2036  this.element.classList.remove('flickity-rtl');
2037  this.unselectSelectedSlide();
2038  // destroy cells
vendor: 10,349 bytes, lines 2039-2477
2039  this.cells.forEach( function( cell ) {
2040    cell.destroy();
2041  } );
2042  this.element.removeChild( this.viewport );
2043  // move child elements back into element
2044  moveElements( this.slider.children, this.element );
2045  if ( this.options.accessibility ) {
2046    this.element.removeAttribute('tabIndex');
2047    this.element.removeEventListener( 'keydown', this );
2048  }
2049  // set flags
2050  this.isActive = false;
2051  this.emitEvent('deactivate');
2052};
2053
2054proto.destroy = function() {
2055  this.deactivate();
2056  window.removeEventListener( 'resize', this );
2057  this.allOff();
2058  this.emitEvent('destroy');
2059  if ( jQuery && this.$element ) {
2060    jQuery.removeData( this.element, 'flickity' );
2061  }
2062  delete this.element.flickityGUID;
2063  delete instances[ this.guid ];
2064};
2065
2066// -------------------------- prototype -------------------------- //
2067
2068utils.extend( proto, animatePrototype );
2069
2070// -------------------------- extras -------------------------- //
2071
2072/**
2073 * get Flickity instance from element
2074 * @param {[Element, String]} elem - element or selector string
2075 * @returns {Flickity} - Flickity instance
2076 */
2077Flickity.data = function( elem ) {
2078  elem = utils.getQueryElement( elem );
2079  var id = elem && elem.flickityGUID;
2080  return id && instances[ id ];
2081};
2082
2083utils.htmlInit( Flickity, 'flickity' );
2084
2085if ( jQuery && jQuery.bridget ) {
2086  jQuery.bridget( 'flickity', Flickity );
2087}
2088
2089// set internal jQuery, for Webpack + jQuery v3, #478
2090Flickity.setJQuery = function( jq ) {
2091  jQuery = jq;
2092};
2093
2094Flickity.Cell = Cell;
2095Flickity.Slide = Slide;
2096
2097return Flickity;
2098
2099} ) );
2100
2101/*!
2102 * Unipointer v2.3.0
2103 * base class for doing one thing with pointer event
2104 * MIT license
2105 */
2106
2107/*jshint browser: true, undef: true, unused: true, strict: true */
2108
2109( function( window, factory ) {
2110  // universal module definition
2111  /* jshint strict: false */ /*global define, module, require */
2112  if ( typeof define == 'function' && define.amd ) {
2113    // AMD
2114    define( 'unipointer/unipointer',[
2115      'ev-emitter/ev-emitter'
2116    ], function( EvEmitter ) {
2117      return factory( window, EvEmitter );
2118    });
2119  } else if ( typeof module == 'object' && module.exports ) {
2120    // CommonJS
2121    module.exports = factory(
2122      window,
2123      require('ev-emitter')
2124    );
2125  } else {
2126    // browser global
2127    window.Unipointer = factory(
2128      window,
2129      window.EvEmitter
2130    );
2131  }
2132
2133}( window, function factory( window, EvEmitter ) {
2134
2135
2136
2137function noop() {}
2138
2139function Unipointer() {}
2140
2141// inherit EvEmitter
2142var proto = Unipointer.prototype = Object.create( EvEmitter.prototype );
2143
2144proto.bindStartEvent = function( elem ) {
2145  this._bindStartEvent( elem, true );
2146};
2147
2148proto.unbindStartEvent = function( elem ) {
2149  this._bindStartEvent( elem, false );
2150};
2151
2152/**
2153 * Add or remove start event
2154 * @param {Boolean} isAdd - remove if falsey
2155 */
2156proto._bindStartEvent = function( elem, isAdd ) {
2157  // munge isAdd, default to true
2158  isAdd = isAdd === undefined ? true : isAdd;
2159  var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
2160
2161  // default to mouse events
2162  var startEvent = 'mousedown';
2163  if ( window.PointerEvent ) {
2164    // Pointer Events
2165    startEvent = 'pointerdown';
2166  } else if ( 'ontouchstart' in window ) {
2167    // Touch Events. iOS Safari
2168    startEvent = 'touchstart';
2169  }
2170  elem[ bindMethod ]( startEvent, this );
2171};
2172
2173// trigger handler methods for events
2174proto.handleEvent = function( event ) {
2175  var method = 'on' + event.type;
2176  if ( this[ method ] ) {
2177    this[ method ]( event );
2178  }
2179};
2180
2181// returns the touch that we're keeping track of
2182proto.getTouch = function( touches ) {
2183  for ( var i=0; i < touches.length; i++ ) {
2184    var touch = touches[i];
2185    if ( touch.identifier == this.pointerIdentifier ) {
2186      return touch;
2187    }
2188  }
2189};
2190
2191// ----- start event ----- //
2192
2193proto.onmousedown = function( event ) {
2194  // dismiss clicks from right or middle buttons
2195  var button = event.button;
2196  if ( button && ( button !== 0 && button !== 1 ) ) {
2197    return;
2198  }
2199  this._pointerDown( event, event );
2200};
2201
2202proto.ontouchstart = function( event ) {
2203  this._pointerDown( event, event.changedTouches[0] );
2204};
2205
2206proto.onpointerdown = function( event ) {
2207  this._pointerDown( event, event );
2208};
2209
2210/**
2211 * pointer start
2212 * @param {Event} event
2213 * @param {Event or Touch} pointer
2214 */
2215proto._pointerDown = function( event, pointer ) {
2216  // dismiss right click and other pointers
2217  // button = 0 is okay, 1-4 not
2218  if ( event.button || this.isPointerDown ) {
2219    return;
2220  }
2221
2222  this.isPointerDown = true;
2223  // save pointer identifier to match up touch events
2224  this.pointerIdentifier = pointer.pointerId !== undefined ?
2225    // pointerId for pointer events, touch.indentifier for touch events
2226    pointer.pointerId : pointer.identifier;
2227
2228  this.pointerDown( event, pointer );
2229};
2230
2231proto.pointerDown = function( event, pointer ) {
2232  this._bindPostStartEvents( event );
2233  this.emitEvent( 'pointerDown', [ event, pointer ] );
2234};
2235
2236// hash of events to be bound after start event
2237var postStartEvents = {
2238  mousedown: [ 'mousemove', 'mouseup' ],
2239  touchstart: [ 'touchmove', 'touchend', 'touchcancel' ],
2240  pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ],
2241};
2242
2243proto._bindPostStartEvents = function( event ) {
2244  if ( !event ) {
2245    return;
2246  }
2247  // get proper events to match start event
2248  var events = postStartEvents[ event.type ];
2249  // bind events to node
2250  events.forEach( function( eventName ) {
2251    window.addEventListener( eventName, this );
2252  }, this );
2253  // save these arguments
2254  this._boundPointerEvents = events;
2255};
2256
2257proto._unbindPostStartEvents = function() {
2258  // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug)
2259  if ( !this._boundPointerEvents ) {
2260    return;
2261  }
2262  this._boundPointerEvents.forEach( function( eventName ) {
2263    window.removeEventListener( eventName, this );
2264  }, this );
2265
2266  delete this._boundPointerEvents;
2267};
2268
2269// ----- move event ----- //
2270
2271proto.onmousemove = function( event ) {
2272  this._pointerMove( event, event );
2273};
2274
2275proto.onpointermove = function( event ) {
2276  if ( event.pointerId == this.pointerIdentifier ) {
2277    this._pointerMove( event, event );
2278  }
2279};
2280
2281proto.ontouchmove = function( event ) {
2282  var touch = this.getTouch( event.changedTouches );
2283  if ( touch ) {
2284    this._pointerMove( event, touch );
2285  }
2286};
2287
2288/**
2289 * pointer move
2290 * @param {Event} event
2291 * @param {Event or Touch} pointer
2292 * @private
2293 */
2294proto._pointerMove = function( event, pointer ) {
2295  this.pointerMove( event, pointer );
2296};
2297
2298// public
2299proto.pointerMove = function( event, pointer ) {
2300  this.emitEvent( 'pointerMove', [ event, pointer ] );
2301};
2302
2303// ----- end event ----- //
2304
2305
2306proto.onmouseup = function( event ) {
2307  this._pointerUp( event, event );
2308};
2309
2310proto.onpointerup = function( event ) {
2311  if ( event.pointerId == this.pointerIdentifier ) {
2312    this._pointerUp( event, event );
2313  }
2314};
2315
2316proto.ontouchend = function( event ) {
2317  var touch = this.getTouch( event.changedTouches );
2318  if ( touch ) {
2319    this._pointerUp( event, touch );
2320  }
2321};
2322
2323/**
2324 * pointer up
2325 * @param {Event} event
2326 * @param {Event or Touch} pointer
2327 * @private
2328 */
2329proto._pointerUp = function( event, pointer ) {
2330  this._pointerDone();
2331  this.pointerUp( event, pointer );
2332};
2333
2334// public
2335proto.pointerUp = function( event, pointer ) {
2336  this.emitEvent( 'pointerUp', [ event, pointer ] );
2337};
2338
2339// ----- pointer done ----- //
2340
2341// triggered on pointer up & pointer cancel
2342proto._pointerDone = function() {
2343  this._pointerReset();
2344  this._unbindPostStartEvents();
2345  this.pointerDone();
2346};
2347
2348proto._pointerReset = function() {
2349  // reset properties
2350  this.isPointerDown = false;
2351  delete this.pointerIdentifier;
2352};
2353
2354proto.pointerDone = noop;
2355
2356// ----- pointer cancel ----- //
2357
2358proto.onpointercancel = function( event ) {
2359  if ( event.pointerId == this.pointerIdentifier ) {
2360    this._pointerCancel( event, event );
2361  }
2362};
2363
2364proto.ontouchcancel = function( event ) {
2365  var touch = this.getTouch( event.changedTouches );
2366  if ( touch ) {
2367    this._pointerCancel( event, touch );
2368  }
2369};
2370
2371/**
2372 * pointer cancel
2373 * @param {Event} event
2374 * @param {Event or Touch} pointer
2375 * @private
2376 */
2377proto._pointerCancel = function( event, pointer ) {
2378  this._pointerDone();
2379  this.pointerCancel( event, pointer );
2380};
2381
2382// public
2383proto.pointerCancel = function( event, pointer ) {
2384  this.emitEvent( 'pointerCancel', [ event, pointer ] );
2385};
2386
2387// -----  ----- //
2388
2389// utility function for getting x/y coords from event
2390Unipointer.getPointerPoint = function( pointer ) {
2391  return {
2392    x: pointer.pageX,
2393    y: pointer.pageY
2394  };
2395};
2396
2397// -----  ----- //
2398
2399return Unipointer;
2400
2401}));
2402
2403/*!
2404 * Unidragger v2.3.1
2405 * Draggable base class
2406 * MIT license
2407 */
2408
2409/*jshint browser: true, unused: true, undef: true, strict: true */
2410
2411( function( window, factory ) {
2412  // universal module definition
2413  /*jshint strict: false */ /*globals define, module, require */
2414
2415  if ( typeof define == 'function' && define.amd ) {
2416    // AMD
2417    define( 'unidragger/unidragger',[
2418      'unipointer/unipointer'
2419    ], function( Unipointer ) {
2420      return factory( window, Unipointer );
2421    });
2422  } else if ( typeof module == 'object' && module.exports ) {
2423    // CommonJS
2424    module.exports = factory(
2425      window,
2426      require('unipointer')
2427    );
2428  } else {
2429    // browser global
2430    window.Unidragger = factory(
2431      window,
2432      window.Unipointer
2433    );
2434  }
2435
2436}( window, function factory( window, Unipointer ) {
2437
2438
2439
2440// -------------------------- Unidragger -------------------------- //
2441
2442function Unidragger() {}
2443
2444// inherit Unipointer & EvEmitter
2445var proto = Unidragger.prototype = Object.create( Unipointer.prototype );
2446
2447// ----- bind start ----- //
2448
2449proto.bindHandles = function() {
2450  this._bindHandles( true );
2451};
2452
2453proto.unbindHandles = function() {
2454  this._bindHandles( false );
2455};
2456
2457/**
2458 * Add or remove start event
2459 * @param {Boolean} isAdd
2460 */
2461proto._bindHandles = function( isAdd ) {
2462  // munge isAdd, default to true
2463  isAdd = isAdd === undefined ? true : isAdd;
2464  // bind each handle
2465  var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
2466  var touchAction = isAdd ? this._touchActionValue : '';
2467  for ( var i=0; i < this.handles.length; i++ ) {
2468    var handle = this.handles[i];
2469    this._bindStartEvent( handle, isAdd );
2470    handle[ bindMethod ]( 'click', this );
2471    // touch-action: none to override browser touch gestures. metafizzy/flickity#540
2472    if ( window.PointerEvent ) {
2473      handle.style.touchAction = touchAction;
2474    }
2475  }
2476};
2477
vendor: 3,209 bytes, lines 2478-2603
2478// prototype so it can be overwriteable by Flickity
2479proto._touchActionValue = 'none';
2480
2481// ----- start event ----- //
2482
2483/**
2484 * pointer start
2485 * @param {Event} event
2486 * @param {Event or Touch} pointer
2487 */
2488proto.pointerDown = function( event, pointer ) {
2489  var isOkay = this.okayPointerDown( event );
2490  if ( !isOkay ) {
2491    return;
2492  }
2493  // track start event position
2494  // Safari 9 overrides pageX and pageY. These values needs to be copied. flickity#842
2495  this.pointerDownPointer = {
2496    pageX: pointer.pageX,
2497    pageY: pointer.pageY,
2498  };
2499
2500  event.preventDefault();
2501  this.pointerDownBlur();
2502  // bind move and end events
2503  this._bindPostStartEvents( event );
2504  this.emitEvent( 'pointerDown', [ event, pointer ] );
2505};
2506
2507// nodes that have text fields
2508var cursorNodes = {
2509  TEXTAREA: true,
2510  INPUT: true,
2511  SELECT: true,
2512  OPTION: true,
2513};
2514
2515// input types that do not have text fields
2516var clickTypes = {
2517  radio: true,
2518  checkbox: true,
2519  button: true,
2520  submit: true,
2521  image: true,
2522  file: true,
2523};
2524
2525// dismiss inputs with text fields. flickity#403, flickity#404
2526proto.okayPointerDown = function( event ) {
2527  var isCursorNode = cursorNodes[ event.target.nodeName ];
2528  var isClickType = clickTypes[ event.target.type ];
2529  var isOkay = !isCursorNode || isClickType;
2530  if ( !isOkay ) {
2531    this._pointerReset();
2532  }
2533  return isOkay;
2534};
2535
2536// kludge to blur previously focused input
2537proto.pointerDownBlur = function() {
2538  var focused = document.activeElement;
2539  // do not blur body for IE10, metafizzy/flickity#117
2540  var canBlur = focused && focused.blur && focused != document.body;
2541  if ( canBlur ) {
2542    focused.blur();
2543  }
2544};
2545
2546// ----- move event ----- //
2547
2548/**
2549 * drag move
2550 * @param {Event} event
2551 * @param {Event or Touch} pointer
2552 */
2553proto.pointerMove = function( event, pointer ) {
2554  var moveVector = this._dragPointerMove( event, pointer );
2555  this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );
2556  this._dragMove( event, pointer, moveVector );
2557};
2558
2559// base pointer move logic
2560proto._dragPointerMove = function( event, pointer ) {
2561  var moveVector = {
2562    x: pointer.pageX - this.pointerDownPointer.pageX,
2563    y: pointer.pageY - this.pointerDownPointer.pageY
2564  };
2565  // start drag if pointer has moved far enough to start drag
2566  if ( !this.isDragging && this.hasDragStarted( moveVector ) ) {
2567    this._dragStart( event, pointer );
2568  }
2569  return moveVector;
2570};
2571
2572// condition if pointer has moved far enough to start drag
2573proto.hasDragStarted = function( moveVector ) {
2574  return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;
2575};
2576
2577// ----- end event ----- //
2578
2579/**
2580 * pointer up
2581 * @param {Event} event
2582 * @param {Event or Touch} pointer
2583 */
2584proto.pointerUp = function( event, pointer ) {
2585  this.emitEvent( 'pointerUp', [ event, pointer ] );
2586  this._dragPointerUp( event, pointer );
2587};
2588
2589proto._dragPointerUp = function( event, pointer ) {
2590  if ( this.isDragging ) {
2591    this._dragEnd( event, pointer );
2592  } else {
2593    // pointer didn't move enough for drag to start
2594    this._staticClick( event, pointer );
2595  }
2596};
2597
2598// -------------------------- drag -------------------------- //
2599
2600// dragStart
2601proto._dragStart = function( event, pointer ) {
2602  this.isDragging = true;
2603  // prevent clicks
2604  this.isPreventingClicks = true;
2605  this.dragStart( event, pointer );
2606};
2607
2608proto.dragStart = function( event, pointer ) {
2609  this.emitEvent( 'dragStart', [ event, pointer ] );
2610};
2611
2612// dragMove
2613proto._dragMove = function( event, pointer, moveVector ) {
2614  // do not drag if not dragging yet
2615  if ( !this.isDragging ) {
2616    return;
2617  }
2618
2619  this.dragMove( event, pointer, moveVector );
2620};
2621
2622proto.dragMove = function( event, pointer, moveVector ) {
2623  event.preventDefault();
2624  this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );
2625};
2626
2627// dragEnd
2628proto._dragEnd = function( event, pointer ) {
2629  // set flags
2630  this.isDragging = false;
2631  // re-enable clicking async
2632  setTimeout( function() {
2633    delete this.isPreventingClicks;
2634  }.bind( this ) );
2635
2636  this.dragEnd( event, pointer );
2637};
2638
2639proto.dragEnd = function( event, pointer ) {
2640  this.emitEvent( 'dragEnd', [ event, pointer ] );
2641};
2642
2643// ----- onclick ----- //
2644
2645// handle all clicks and prevent clicks when dragging
2646proto.onclick = function( event ) {
2647  if ( this.isPreventingClicks ) {
2648    event.preventDefault();
2649  }
2650};
2651
2652// ----- staticClick ----- //
2653
2654// triggered after pointer down & up with no/tiny movement
2655proto._staticClick = function( event, pointer ) {
2656  // ignore emulated mouse up clicks
2657  if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) {
2658    return;
2659  }
2660
2661  this.staticClick( event, pointer );
2662
2663  // set flag for emulated clicks 300ms after touchend
2664  if ( event.type != 'mouseup' ) {
2665    this.isIgnoringMouseUp = true;
2666    // reset flag after 300ms
2667    setTimeout( function() {
2668      delete this.isIgnoringMouseUp;
2669    }.bind( this ), 400 );
2670  }
2671};
2672
2673proto.staticClick = function( event, pointer ) {
2674  this.emitEvent( 'staticClick', [ event, pointer ] );
2675};
2676
2677// ----- utils ----- //
2678
2679Unidragger.getPointerPoint = Unipointer.getPointerPoint;
2680
2681// -----  ----- //
2682
2683return Unidragger;
2684
2685}));
2686
2687// drag
2688( function( window, factory ) {
2689  // universal module definition
2690  if ( typeof define == 'function' && define.amd ) {
2691    // AMD
2692    define( 'flickity/js/drag',[
2693      './flickity',
2694      'unidragger/unidragger',
2695      'fizzy-ui-utils/utils',
2696    ], function( Flickity, Unidragger, utils ) {
2697      return factory( window, Flickity, Unidragger, utils );
2698    } );
2699  } else if ( typeof module == 'object' && module.exports ) {
2700    // CommonJS
2701    module.exports = factory(
2702        window,
2703        require('./flickity'),
2704        require('unidragger'),
2705        require('fizzy-ui-utils')
2706    );
2707  } else {
2708    // browser global
2709    window.Flickity = factory(
2710        window,
2711        window.Flickity,
2712        window.Unidragger,
2713        window.fizzyUIUtils
2714    );
2715  }
2716
2717}( window, function factory( window, Flickity, Unidragger, utils ) {
2718
2719
2720
2721// ----- defaults ----- //
2722
2723utils.extend( Flickity.defaults, {
2724  draggable: '>1',
2725  dragThreshold: 3,
2726} );
2727
2728// ----- create ----- //
2729
2730Flickity.createMethods.push('_createDrag');
2731
2732// -------------------------- drag prototype -------------------------- //
2733
2734var proto = Flickity.prototype;
2735utils.extend( proto, Unidragger.prototype );
2736proto._touchActionValue = 'pan-y';
2737
2738// --------------------------  -------------------------- //
2739
2740var isTouch = 'createTouch' in document;
2741var isTouchmoveScrollCanceled = false;
2742
2743proto._createDrag = function() {
2744  this.on( 'activate', this.onActivateDrag );
2745  this.on( 'uiChange', this._uiChangeDrag );
2746  this.on( 'deactivate', this.onDeactivateDrag );
2747  this.on( 'cellChange', this.updateDraggable );
2748  // TODO updateDraggable on resize? if groupCells & slides change
2749  // HACK - add seemingly innocuous handler to fix iOS 10 scroll behavior
2750  // #457, RubaXa/Sortable#973
2751  if ( isTouch && !isTouchmoveScrollCanceled ) {
2752    window.addEventListener( 'touchmove', function() {} );
2753    isTouchmoveScrollCanceled = true;
2754  }
2755};
2756
2757proto.onActivateDrag = function() {
2758  this.handles = [ this.viewport ];
2759  this.bindHandles();
2760  this.updateDraggable();
2761};
2762
2763proto.onDeactivateDrag = function() {
2764  this.unbindHandles();
2765  this.element.classList.remove('is-draggable');
2766};
2767
2768proto.updateDraggable = function() {
2769  // disable dragging if less than 2 slides. #278
2770  if ( this.options.draggable == '>1' ) {
2771    this.isDraggable = this.slides.length > 1;
2772  } else {
2773    this.isDraggable = this.options.draggable;
2774  }
2775  if ( this.isDraggable ) {
2776    this.element.classList.add('is-draggable');
2777  } else {
2778    this.element.classList.remove('is-draggable');
2779  }
2780};
2781
2782// backwards compatibility
2783proto.bindDrag = function() {
2784  this.options.draggable = true;
2785  this.updateDraggable();
2786};
2787
2788proto.unbindDrag = function() {
2789  this.options.draggable = false;
vendor: 5,130 bytes, lines 2790-2962
2790  this.updateDraggable();
2791};
2792
2793proto._uiChangeDrag = function() {
2794  delete this.isFreeScrolling;
2795};
2796
2797// -------------------------- pointer events -------------------------- //
2798
2799proto.pointerDown = function( event, pointer ) {
2800  if ( !this.isDraggable ) {
2801    this._pointerDownDefault( event, pointer );
2802    return;
2803  }
2804  var isOkay = this.okayPointerDown( event );
2805  if ( !isOkay ) {
2806    return;
2807  }
2808
2809  this._pointerDownPreventDefault( event );
2810  this.pointerDownFocus( event );
2811  // blur
2812  if ( document.activeElement != this.element ) {
2813    // do not blur if already focused
2814    this.pointerDownBlur();
2815  }
2816
2817  // stop if it was moving
2818  this.dragX = this.x;
2819  this.viewport.classList.add('is-pointer-down');
2820  // track scrolling
2821  this.pointerDownScroll = getScrollPosition();
2822  window.addEventListener( 'scroll', this );
2823
2824  this._pointerDownDefault( event, pointer );
2825};
2826
2827// default pointerDown logic, used for staticClick
2828proto._pointerDownDefault = function( event, pointer ) {
2829  // track start event position
2830  // Safari 9 overrides pageX and pageY. These values needs to be copied. #779
2831  this.pointerDownPointer = {
2832    pageX: pointer.pageX,
2833    pageY: pointer.pageY,
2834  };
2835  // bind move and end events
2836  this._bindPostStartEvents( event );
2837  this.dispatchEvent( 'pointerDown', event, [ pointer ] );
2838};
2839
2840var focusNodes = {
2841  INPUT: true,
2842  TEXTAREA: true,
2843  SELECT: true,
2844};
2845
2846proto.pointerDownFocus = function( event ) {
2847  var isFocusNode = focusNodes[ event.target.nodeName ];
2848  if ( !isFocusNode ) {
2849    this.focus();
2850  }
2851};
2852
2853proto._pointerDownPreventDefault = function( event ) {
2854  var isTouchStart = event.type == 'touchstart';
2855  var isTouchPointer = event.pointerType == 'touch';
2856  var isFocusNode = focusNodes[ event.target.nodeName ];
2857  if ( !isTouchStart && !isTouchPointer && !isFocusNode ) {
2858    event.preventDefault();
2859  }
2860};
2861
2862// ----- move ----- //
2863
2864proto.hasDragStarted = function( moveVector ) {
2865  return Math.abs( moveVector.x ) > this.options.dragThreshold;
2866};
2867
2868// ----- up ----- //
2869
2870proto.pointerUp = function( event, pointer ) {
2871  delete this.isTouchScrolling;
2872  this.viewport.classList.remove('is-pointer-down');
2873  this.dispatchEvent( 'pointerUp', event, [ pointer ] );
2874  this._dragPointerUp( event, pointer );
2875};
2876
2877proto.pointerDone = function() {
2878  window.removeEventListener( 'scroll', this );
2879  delete this.pointerDownScroll;
2880};
2881
2882// -------------------------- dragging -------------------------- //
2883
2884proto.dragStart = function( event, pointer ) {
2885  if ( !this.isDraggable ) {
2886    return;
2887  }
2888  this.dragStartPosition = this.x;
2889  this.startAnimation();
2890  window.removeEventListener( 'scroll', this );
2891  this.dispatchEvent( 'dragStart', event, [ pointer ] );
2892};
2893
2894proto.pointerMove = function( event, pointer ) {
2895  var moveVector = this._dragPointerMove( event, pointer );
2896  this.dispatchEvent( 'pointerMove', event, [ pointer, moveVector ] );
2897  this._dragMove( event, pointer, moveVector );
2898};
2899
2900proto.dragMove = function( event, pointer, moveVector ) {
2901  if ( !this.isDraggable ) {
2902    return;
2903  }
2904  event.preventDefault();
2905
2906  this.previousDragX = this.dragX;
2907  // reverse if right-to-left
2908  var direction = this.options.rightToLeft ? -1 : 1;
2909  if ( this.options.wrapAround ) {
2910    // wrap around move. #589
2911    moveVector.x %= this.slideableWidth;
2912  }
2913  var dragX = this.dragStartPosition + moveVector.x * direction;
2914
2915  if ( !this.options.wrapAround && this.slides.length ) {
2916    // slow drag
2917    var originBound = Math.max( -this.slides[0].target, this.dragStartPosition );
2918    dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX;
2919    var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition );
2920    dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX;
2921  }
2922
2923  this.dragX = dragX;
2924
2925  this.dragMoveTime = new Date();
2926  this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] );
2927};
2928
2929proto.dragEnd = function( event, pointer ) {
2930  if ( !this.isDraggable ) {
2931    return;
2932  }
2933  if ( this.options.freeScroll ) {
2934    this.isFreeScrolling = true;
2935  }
2936  // set selectedIndex based on where flick will end up
2937  var index = this.dragEndRestingSelect();
2938
2939  if ( this.options.freeScroll && !this.options.wrapAround ) {
2940    // if free-scroll & not wrap around
2941    // do not free-scroll if going outside of bounding slides
2942    // so bounding slides can attract slider, and keep it in bounds
2943    var restingX = this.getRestingPosition();
2944    this.isFreeScrolling = -restingX > this.slides[0].target &&
2945      -restingX < this.getLastSlide().target;
2946  } else if ( !this.options.freeScroll && index == this.selectedIndex ) {
2947    // boost selection if selected index has not changed
2948    index += this.dragEndBoostSelect();
2949  }
2950  delete this.previousDragX;
2951  // apply selection
2952  // TODO refactor this, selecting here feels weird
2953  // HACK, set flag so dragging stays in correct direction
2954  this.isDragSelect = this.options.wrapAround;
2955  this.select( index );
2956  delete this.isDragSelect;
2957  this.dispatchEvent( 'dragEnd', event, [ pointer ] );
2958};
2959
2960proto.dragEndRestingSelect = function() {
2961  var restingX = this.getRestingPosition();
2962  // how far away from selected slide
2963  var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) );
2964  // get closet resting going up and going down
2965  var positiveResting = this._getClosestResting( restingX, distance, 1 );
2966  var negativeResting = this._getClosestResting( restingX, distance, -1 );
2967  // use closer resting for wrap-around
2968  var index = positiveResting.distance < negativeResting.distance ?
2969    positiveResting.index : negativeResting.index;
2970  return index;
2971};
2972
2973/**
2974 * given resting X and distance to selected cell
2975 * get the distance and index of the closest cell
2976 * @param {Number} restingX - estimated post-flick resting position
2977 * @param {Number} distance - distance to selected cell
2978 * @param {Integer} increment - +1 or -1, going up or down
2979 * @returns {Object} - { distance: {Number}, index: {Integer} }
2980 */
2981proto._getClosestResting = function( restingX, distance, increment ) {
2982  var index = this.selectedIndex;
2983  var minDistance = Infinity;
2984  var condition = this.options.contain && !this.options.wrapAround ?
2985    // if contain, keep going if distance is equal to minDistance
2986    function( dist, minDist ) {
2987      return dist <= minDist;
2988    } : function( dist, minDist ) {
2989      return dist < minDist;
2990    };
2991  while ( condition( distance, minDistance ) ) {
2992    // measure distance to next cell
2993    index += increment;
2994    minDistance = distance;
2995    distance = this.getSlideDistance( -restingX, index );
2996    if ( distance === null ) {
2997      break;
2998    }
2999    distance = Math.abs( distance );
3000  }
3001  return {
3002    distance: minDistance,
3003    // selected was previous index
3004    index: index - increment,
3005  };
3006};
3007
3008/**
3009 * measure distance between x and a slide target
3010 * @param {Number} x - horizontal position
3011 * @param {Integer} index - slide index
3012 * @returns {Number} - slide distance
3013 */
3014proto.getSlideDistance = function( x, index ) {
3015  var len = this.slides.length;
3016  // wrap around if at least 2 slides
3017  var isWrapAround = this.options.wrapAround && len > 1;
3018  var slideIndex = isWrapAround ? utils.modulo( index, len ) : index;
3019  var slide = this.slides[ slideIndex ];
3020  if ( !slide ) {
3021    return null;
3022  }
3023  // add distance for wrap-around slides
3024  var wrap = isWrapAround ? this.slideableWidth * Math.floor( index/len ) : 0;
3025  return x - ( slide.target + wrap );
3026};
3027
3028proto.dragEndBoostSelect = function() {
3029  // do not boost if no previousDragX or dragMoveTime
3030  if ( this.previousDragX === undefined || !this.dragMoveTime ||
3031    // or if drag was held for 100 ms
3032    new Date() - this.dragMoveTime > 100 ) {
3033    return 0;
3034  }
3035
3036  var distance = this.getSlideDistance( -this.dragX, this.selectedIndex );
3037  var delta = this.previousDragX - this.dragX;
3038  if ( distance > 0 && delta > 0 ) {
3039    // boost to next if moving towards the right, and positive velocity
3040    return 1;
3041  } else if ( distance < 0 && delta < 0 ) {
3042    // boost to previous if moving towards the left, and negative velocity
3043    return -1;
3044  }
3045  return 0;
3046};
3047
3048// ----- staticClick ----- //
3049
3050proto.staticClick = function( event, pointer ) {
3051  // get clickedCell, if cell was clicked
3052  var clickedCell = this.getParentCell( event.target );
3053  var cellElem = clickedCell && clickedCell.element;
3054  var cellIndex = clickedCell && this.cells.indexOf( clickedCell );
3055  this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] );
3056};
3057
3058// ----- scroll ----- //
3059
3060proto.onscroll = function() {
3061  var scroll = getScrollPosition();
3062  var scrollMoveX = this.pointerDownScroll.x - scroll.x;
3063  var scrollMoveY = this.pointerDownScroll.y - scroll.y;
3064  // cancel click/tap if scroll is too much
3065  if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) {
3066    this._pointerDone();
3067  }
3068};
3069
3070// ----- utils ----- //
3071
3072function getScrollPosition() {
3073  return {
3074    x: window.pageXOffset,
3075    y: window.pageYOffset,
3076  };
3077}
3078
3079// -----  ----- //
3080
3081return Flickity;
3082
3083} ) );
3084
3085// prev/next buttons
3086( function( window, factory ) {
3087  // universal module definition
3088  if ( typeof define == 'function' && define.amd ) {
3089    // AMD
3090    define( 'flickity/js/prev-next-button',[
3091      './flickity',
3092      'unipointer/unipointer',
3093      'fizzy-ui-utils/utils',
3094    ], function( Flickity, Unipointer, utils ) {
3095      return factory( window, Flickity, Unipointer, utils );
3096    } );
3097  } else if ( typeof module == 'object' && module.exports ) {
3098    // CommonJS
3099    module.exports = factory(
3100        window,
3101        require('./flickity'),
3102        require('unipointer'),
3103        require('fizzy-ui-utils')
3104    );
3105  } else {
3106    // browser global
3107    factory(
3108        window,
3109        window.Flickity,
3110        window.Unipointer,
3111        window.fizzyUIUtils
3112    );
3113  }
3114
3115}( window, function factory( window, Flickity, Unipointer, utils ) {
3116'use strict';
3117
3118var svgURI = 'http://www.w3.org/2000/svg';
3119
3120// -------------------------- PrevNextButton -------------------------- //
3121
3122function PrevNextButton( direction, parent ) {
3123  this.direction = direction;
3124  this.parent = parent;
3125  this._create();
3126}
3127
3128PrevNextButton.prototype = Object.create( Unipointer.prototype );
3129
3130PrevNextButton.prototype._create = function() {
3131  // properties
3132  this.isEnabled = true;
3133  this.isPrevious = this.direction == -1;
3134  var leftDirection = this.parent.options.rightToLeft ? 1 : -1;
3135  this.isLeft = this.direction == leftDirection;
3136
3137  var element = this.element = document.createElement('button');
3138  element.className = 'flickity-button flickity-prev-next-button';
3139  element.className += this.isPrevious ? ' previous' : ' next';
3140  // prevent button from submitting form http://stackoverflow.com/a/10836076/182183
3141  element.setAttribute( 'type', 'button' );
3142  // init as disabled
3143  this.disable();
3144
3145  element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' );
3146
3147  // create arrow
3148  var svg = this.createSVG();
3149  element.appendChild( svg );
3150  // events
3151  this.parent.on( 'select', this.update.bind( this ) );
3152  this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
3153};
3154
3155PrevNextButton.prototype.activate = function() {
3156  this.bindStartEvent( this.element );
3157  this.element.addEventListener( 'click', this );
3158  // add to DOM
3159  this.parent.element.appendChild( this.element );
3160};
3161
3162PrevNextButton.prototype.deactivate = function() {
3163  // remove from DOM
3164  this.parent.element.removeChild( this.element );
3165  // click events
3166  this.unbindStartEvent( this.element );
3167  this.element.removeEventListener( 'click', this );
3168};
3169
3170PrevNextButton.prototype.createSVG = function() {
3171  var svg = document.createElementNS( svgURI, 'svg' );
3172  svg.setAttribute( 'class', 'flickity-button-icon' );
3173  svg.setAttribute( 'viewBox', '0 0 100 100' );
3174  var path = document.createElementNS( svgURI, 'path' );
3175  var pathMovements = getArrowMovements( this.parent.options.arrowShape );
3176  path.setAttribute( 'd', pathMovements );
3177  path.setAttribute( 'class', 'arrow' );
3178  // rotate arrow
3179  if ( !this.isLeft ) {
3180    path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' );
3181  }
3182  svg.appendChild( path );
3183  return svg;
3184};
3185
3186// get SVG path movmement
3187function getArrowMovements( shape ) {
3188  // use shape as movement if string
3189  if ( typeof shape == 'string' ) {
3190    return shape;
3191  }
3192  // create movement string
3193  return 'M ' + shape.x0 + ',50' +
3194    ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) +
3195    ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) +
3196    ' L ' + shape.x3 + ',50 ' +
3197    ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) +
3198    ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) +
3199    ' Z';
3200}
3201
3202PrevNextButton.prototype.handleEvent = utils.handleEvent;
3203
3204PrevNextButton.prototype.onclick = function() {
3205  if ( !this.isEnabled ) {
3206    return;
3207  }
3208  this.parent.uiChange();
3209  var method = this.isPrevious ? 'previous' : 'next';
3210  this.parent[ method ]();
3211};
3212
3213// -----  ----- //
3214
3215PrevNextButton.prototype.enable = function() {
3216  if ( this.isEnabled ) {
3217    return;
3218  }
3219  this.element.disabled = false;
3220  this.isEnabled = true;
3221};
3222
3223PrevNextButton.prototype.disable = function() {
3224  if ( !this.isEnabled ) {
3225    return;
3226  }
3227  this.element.disabled = true;
3228  this.isEnabled = false;
3229};
3230
3231PrevNextButton.prototype.update = function() {
3232  // index of first or last slide, if previous or next
3233  var slides = this.parent.slides;
3234  // enable is wrapAround and at least 2 slides
3235  if ( this.parent.options.wrapAround && slides.length > 1 ) {
3236    this.enable();
3237    return;
3238  }
3239  var lastIndex = slides.length ? slides.length - 1 : 0;
3240  var boundIndex = this.isPrevious ? 0 : lastIndex;
3241  var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable';
3242  this[ method ]();
3243};
3244
3245PrevNextButton.prototype.destroy = function() {
3246  this.deactivate();
3247  this.allOff();
3248};
3249
3250// -------------------------- Flickity prototype -------------------------- //
3251
3252utils.extend( Flickity.defaults, {
3253  prevNextButtons: true,
3254  arrowShape: {
3255    x0: 10,
3256    x1: 60, y1: 50,
3257    x2: 70, y2: 40,
3258    x3: 30,
3259  },
3260} );
3261
3262Flickity.createMethods.push('_createPrevNextButtons');
3263var proto = Flickity.prototype;
3264
3265proto._createPrevNextButtons = function() {
3266  if ( !this.options.prevNextButtons ) {
3267    return;
3268  }
3269
3270  this.prevButton = new PrevNextButton( -1, this );
3271  this.nextButton = new PrevNextButton( 1, this );
3272
3273  this.on( 'activate', this.activatePrevNextButtons );
3274};
3275
3276proto.activatePrevNextButtons = function() {
3277  this.prevButton.activate();
3278  this.nextButton.activate();
3279  this.on( 'deactivate', this.deactivatePrevNextButtons );
3280};
3281
3282proto.deactivatePrevNextButtons = function() {
3283  this.prevButton.deactivate();
3284  this.nextButton.deactivate();
3285  this.off( 'deactivate', this.deactivatePrevNextButtons );
3286};
3287
3288// --------------------------  -------------------------- //
3289
3290Flickity.PrevNextButton = PrevNextButton;
3291
3292return Flickity;
3293
3294} ) );
3295
3296// page dots
3297( function( window, factory ) {
3298  // universal module definition
3299  if ( typeof define == 'function' && define.amd ) {
3300    // AMD
3301    define( 'flickity/js/page-dots',[
3302      './flickity',
3303      'unipointer/unipointer',
3304      'fizzy-ui-utils/utils',
3305    ], function( Flickity, Unipointer, utils ) {
3306      return factory( window, Flickity, Unipointer, utils );
3307    } );
3308  } else if ( typeof module == 'object' && module.exports ) {
3309    // CommonJS
3310    module.exports = factory(
3311        window,
3312        require('./flickity'),
3313        require('unipointer'),
3314        require('fizzy-ui-utils')
3315    );
3316  } else {
3317    // browser global
3318    factory(
3319        window,
3320        window.Flickity,
3321        window.Unipointer,
3322        window.fizzyUIUtils
3323    );
3324  }
3325
3326}( window, function factory( window, Flickity, Unipointer, utils ) {
3327
3328// -------------------------- PageDots -------------------------- //
3329
3330
3331
3332function PageDots( parent ) {
3333  this.parent = parent;
3334  this._create();
3335}
3336
3337PageDots.prototype = Object.create( Unipointer.prototype );
3338
3339PageDots.prototype._create = function() {
3340  // create holder element
3341  this.holder = document.createElement('ol');
3342  this.holder.className = 'flickity-page-dots';
3343  // create dots, array of elements
3344  this.dots = [];
3345  // events
3346  this.handleClick = this.onClick.bind( this );
3347  this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
3348};
3349
3350PageDots.prototype.activate = function() {
3351  this.setDots();
3352  this.holder.addEventListener( 'click', this.handleClick );
3353  this.bindStartEvent( this.holder );
3354  // add to DOM
3355  this.parent.element.appendChild( this.holder );
3356};
3357
3358PageDots.prototype.deactivate = function() {
3359  this.holder.removeEventListener( 'click', this.handleClick );
3360  this.unbindStartEvent( this.holder );
3361  // remove from DOM
3362  this.parent.element.removeChild( this.holder );
3363};
3364
3365PageDots.prototype.setDots = function() {
3366  // get difference between number of slides and number of dots
3367  var delta = this.parent.slides.length - this.dots.length;
3368  if ( delta > 0 ) {
3369    this.addDots( delta );
3370  } else if ( delta < 0 ) {
3371    this.removeDots( -delta );
3372  }
3373};
3374
3375PageDots.prototype.addDots = function( count ) {
3376  var fragment = document.createDocumentFragment();
3377  var newDots = [];
3378  var length = this.dots.length;
3379  var max = length + count;
3380
3381  for ( var i = length; i < max; i++ ) {
3382    var dot = document.createElement('li');
3383    dot.className = 'dot';
3384    dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) );
3385    fragment.appendChild( dot );
3386    newDots.push( dot );
3387  }
3388
3389  this.holder.appendChild( fragment );
3390  this.dots = this.dots.concat( newDots );
3391};
3392
3393PageDots.prototype.removeDots = function( count ) {
3394  // remove from this.dots collection
3395  var removeDots = this.dots.splice( this.dots.length - count, count );
3396  // remove from DOM
3397  removeDots.forEach( function( dot ) {
3398    this.holder.removeChild( dot );
3399  }, this );
3400};
3401
3402PageDots.prototype.updateSelected = function() {
3403  // remove selected class on previous
3404  if ( this.selectedDot ) {
3405    this.selectedDot.className = 'dot';
3406    this.selectedDot.removeAttribute('aria-current');
3407  }
3408  // don't proceed if no dots
3409  if ( !this.dots.length ) {
3410    return;
3411  }
3412  this.selectedDot = this.dots[ this.parent.selectedIndex ];
3413  this.selectedDot.className = 'dot is-selected';
3414  this.selectedDot.setAttribute( 'aria-current', 'step' );
3415};
3416
3417PageDots.prototype.onTap = // old method name, backwards-compatible
3418PageDots.prototype.onClick = function( event ) {
3419  var target = event.target;
3420  // only care about dot clicks
3421  if ( target.nodeName != 'LI' ) {
3422    return;
3423  }
3424
3425  this.parent.uiChange();
3426  var index = this.dots.indexOf( target );
3427  this.parent.select( index );
3428};
3429
3430PageDots.prototype.destroy = function() {
3431  this.deactivate();
3432  this.allOff();
3433};
3434
3435Flickity.PageDots = PageDots;
3436
3437// -------------------------- Flickity -------------------------- //
3438
3439utils.extend( Flickity.defaults, {
3440  pageDots: true,
3441} );
3442
3443Flickity.createMethods.push('_createPageDots');
3444
3445var proto = Flickity.prototype;
3446
3447proto._createPageDots = function() {
3448  if ( !this.options.pageDots ) {
3449    return;
3450  }
3451  this.pageDots = new PageDots( this );
3452  // events
3453  this.on( 'activate', this.activatePageDots );
3454  this.on( 'select', this.updateSelectedPageDots );
3455  this.on( 'cellChange', this.updatePageDots );
3456  this.on( 'resize', this.updatePageDots );
3457  this.on( 'deactivate', this.deactivatePageDots );
3458};
3459
3460proto.activatePageDots = function() {
3461  this.pageDots.activate();
3462};
3463
3464proto.updateSelectedPageDots = function() {
3465  this.pageDots.updateSelected();
3466};
3467
3468proto.updatePageDots = function() {
3469  this.pageDots.setDots();
3470};
3471
3472proto.deactivatePageDots = function() {
3473  this.pageDots.deactivate();
3474};
3475
3476// -----  ----- //
3477
3478Flickity.PageDots = PageDots;
3479
3480return Flickity;
3481
3482} ) );
3483
3484// player & autoPlay
3485( function( window, factory ) {
3486  // universal module definition
3487  if ( typeof define == 'function' && define.amd ) {
3488    // AMD
3489    define( 'flickity/js/player',[
3490      'ev-emitter/ev-emitter',
3491      'fizzy-ui-utils/utils',
3492      './flickity',
3493    ], function( EvEmitter, utils, Flickity ) {
3494      return factory( EvEmitter, utils, Flickity );
3495    } );
3496  } else if ( typeof module == 'object' && module.exports ) {
3497    // CommonJS
3498    module.exports = factory(
3499        require('ev-emitter'),
3500        require('fizzy-ui-utils'),
3501        require('./flickity')
3502    );
3503  } else {
3504    // browser global
3505    factory(
3506        window.EvEmitter,
3507        window.fizzyUIUtils,
3508        window.Flickity
3509    );
3510  }
3511
3512}( window, function factory( EvEmitter, utils, Flickity ) {
3513
3514
3515
3516// -------------------------- Player -------------------------- //
3517
3518function Player( parent ) {
3519  this.parent = parent;
3520  this.state = 'stopped';
3521  // visibility change event handler
3522  this.onVisibilityChange = this.visibilityChange.bind( this );
3523  this.onVisibilityPlay = this.visibilityPlay.bind( this );
3524}
3525
3526Player.prototype = Object.create( EvEmitter.prototype );
3527
3528// start play
3529Player.prototype.play = function() {
3530  if ( this.state == 'playing' ) {
3531    return;
3532  }
3533  // do not play if page is hidden, start playing when page is visible
3534  var isPageHidden = document.hidden;
3535  if ( isPageHidden ) {
3536    document.addEventListener( 'visibilitychange', this.onVisibilityPlay );
3537    return;
3538  }
3539
3540  this.state = 'playing';
3541  // listen to visibility change
3542  document.addEventListener( 'visibilitychange', this.onVisibilityChange );
3543  // start ticking
3544  this.tick();
3545};
3546
3547Player.prototype.tick = function() {
3548  // do not tick if not playing
3549  if ( this.state != 'playing' ) {
3550    return;
3551  }
3552
3553  var time = this.parent.options.autoPlay;
3554  // default to 3 seconds
3555  time = typeof time == 'number' ? time : 3000;
3556  var _this = this;
3557  // HACK: reset ticks if stopped and started within interval
3558  this.clear();
3559  this.timeout = setTimeout( function() {
3560    _this.parent.next( true );
3561    _this.tick();
3562  }, time );
3563};
3564
3565Player.prototype.stop = function() {
3566  this.state = 'stopped';
3567  this.clear();
3568  // remove visibility change event
3569  document.removeEventListener( 'visibilitychange', this.onVisibilityChange );
3570};
3571
3572Player.prototype.clear = function() {
3573  clearTimeout( this.timeout );
3574};
3575
3576Player.prototype.pause = function() {
3577  if ( this.state == 'playing' ) {
3578    this.state = 'paused';
3579    this.clear();
3580  }
3581};
3582
3583Player.prototype.unpause = function() {
3584  // re-start play if paused
3585  if ( this.state == 'paused' ) {
3586    this.play();
3587  }
3588};
3589
3590// pause if page visibility is hidden, unpause if visible
3591Player.prototype.visibilityChange = function() {
3592  var isPageHidden = document.hidden;
3593  this[ isPageHidden ? 'pause' : 'unpause' ]();
3594};
3595
3596Player.prototype.visibilityPlay = function() {
3597  this.play();
3598  document.removeEventListener( 'visibilitychange', this.onVisibilityPlay );
3599};
3600
3601// -------------------------- Flickity -------------------------- //
3602
3603utils.extend( Flickity.defaults, {
3604  pauseAutoPlayOnHover: true,
3605} );
3606
3607Flickity.createMethods.push('_createPlayer');
3608var proto = Flickity.prototype;
3609
3610proto._createPlayer = function() {
3611  this.player = new Player( this );
3612
3613  this.on( 'activate', this.activatePlayer );
3614  this.on( 'uiChange', this.stopPlayer );
3615  this.on( 'pointerDown', this.stopPlayer );
3616  this.on( 'deactivate', this.deactivatePlayer );
3617};
3618
3619proto.activatePlayer = function() {
3620  if ( !this.options.autoPlay ) {
3621    return;
3622  }
3623  this.player.play();
3624  this.element.addEventListener( 'mouseenter', this );
3625};
3626
3627// Player API, don't hate the ... thanks I know where the door is
3628
3629proto.playPlayer = function() {
3630  this.player.play();
3631};
3632
3633proto.stopPlayer = function() {
3634  this.player.stop();
3635};
3636
3637proto.pausePlayer = function() {
3638  this.player.pause();
3639};
3640
3641proto.unpausePlayer = function() {
3642  this.player.unpause();
3643};
3644
3645proto.deactivatePlayer = function() {
3646  this.player.stop();
3647  this.element.removeEventListener( 'mouseenter', this );
3648};
3649
3650// ----- mouseenter/leave ----- //
3651
3652// pause auto-play on hover
3653proto.onmouseenter = function() {
3654  if ( !this.options.pauseAutoPlayOnHover ) {
3655    return;
3656  }
3657  this.player.pause();
3658  this.element.addEventListener( 'mouseleave', this );
3659};
3660
3661// resume auto-play on hover off
3662proto.onmouseleave = function() {
3663  this.player.unpause();
3664  this.element.removeEventListener( 'mouseleave', this );
3665};
3666
3667// -----  ----- //
3668
3669Flickity.Player = Player;
3670
3671return Flickity;
3672
3673} ) );
3674
3675// add, remove cell
3676( function( window, factory ) {
3677  // universal module definition
3678  if ( typeof define == 'function' && define.amd ) {
3679    // AMD
3680    define( 'flickity/js/add-remove-cell',[
3681      './flickity',
3682      'fizzy-ui-utils/utils',
3683    ], function( Flickity, utils ) {
3684      return factory( window, Flickity, utils );
3685    } );
3686  } else if ( typeof module == 'object' && module.exports ) {
3687    // CommonJS
3688    module.exports = factory(
3689        window,
3690        require('./flickity'),
3691        require('fizzy-ui-utils')
3692    );
3693  } else {
3694    // browser global
3695    factory(
3696        window,
3697        window.Flickity,
3698        window.fizzyUIUtils
3699    );
3700  }
3701
3702}( window, function factory( window, Flickity, utils ) {
3703
3704
3705
3706// append cells to a document fragment
3707function getCellsFragment( cells ) {
3708  var fragment = document.createDocumentFragment();
3709  cells.forEach( function( cell ) {
3710    fragment.appendChild( cell.element );
3711  } );
3712  return fragment;
3713}
3714
3715// -------------------------- add/remove cell prototype -------------------------- //
3716
3717var proto = Flickity.prototype;
3718
3719/**
3720 * Insert, prepend, or append cells
3721 * @param {[Element, Array, NodeList]} elems - Elements to insert
3722 * @param {Integer} index - Zero-based number to insert
3723 */
3724proto.insert = function( elems, index ) {
3725  var cells = this._makeCells( elems );
3726  if ( !cells || !cells.length ) {
3727    return;
3728  }
3729  var len = this.cells.length;
3730  // default to append
3731  index = index === undefined ? len : index;
3732  // add cells with document fragment
3733  var fragment = getCellsFragment( cells );
3734  // append to slider
3735  var isAppend = index == len;
3736  if ( isAppend ) {
3737    this.slider.appendChild( fragment );
3738  } else {
3739    var insertCellElement = this.cells[ index ].element;
3740    this.slider.insertBefore( fragment, insertCellElement );
3741  }
3742  // add to this.cells
3743  if ( index === 0 ) {
3744    // prepend, add to start
3745    this.cells = cells.concat( this.cells );
3746  } else if ( isAppend ) {
3747    // append, add to end
3748    this.cells = this.cells.concat( cells );
3749  } else {
3750    // insert in this.cells
3751    var endCells = this.cells.splice( index, len - index );
3752    this.cells = this.cells.concat( cells ).concat( endCells );
3753  }
3754
3755  this._sizeCells( cells );
3756  this.cellChange( index, true );
3757};
3758
3759proto.append = function( elems ) {
3760  this.insert( elems, this.cells.length );
3761};
3762
3763proto.prepend = function( elems ) {
3764  this.insert( elems, 0 );
3765};
3766
3767/**
3768 * Remove cells
3769 * @param {[Element, Array, NodeList]} elems - ELements to remove
3770 */
3771proto.remove = function( elems ) {
3772  var cells = this.getCells( elems );
3773  if ( !cells || !cells.length ) {
3774    return;
3775  }
3776
3777  var minCellIndex = this.cells.length - 1;
3778  // remove cells from collection & DOM
3779  cells.forEach( function( cell ) {
3780    cell.remove();
3781    var index = this.cells.indexOf( cell );
3782    minCellIndex = Math.min( index, minCellIndex );
3783    utils.removeFrom( this.cells, cell );
3784  }, this );
3785
3786  this.cellChange( minCellIndex, true );
3787};
3788
3789/**
3790 * logic to be run after a cell's size changes
3791 * @param {Element} elem - cell's element
3792 */
3793proto.cellSizeChange = function( elem ) {
3794  var cell = this.getCell( elem );
3795  if ( !cell ) {
3796    return;
3797  }
3798  cell.getSize();
3799
3800  var index = this.cells.indexOf( cell );
3801  this.cellChange( index );
3802};
3803
3804/**
3805 * logic any time a cell is changed: added, removed, or size changed
3806 * @param {Integer} changedCellIndex - index of the changed cell, optional
3807 * @param {Boolean} isPositioningSlider - Positions slider after selection
3808 */
3809proto.cellChange = function( changedCellIndex, isPositioningSlider ) {
3810  var prevSelectedElem = this.selectedElement;
3811  this._positionCells( changedCellIndex );
3812  this._getWrapShiftCells();
3813  this.setGallerySize();
3814  // update selectedIndex
3815  // try to maintain position & select previous selected element
3816  var cell = this.getCell( prevSelectedElem );
3817  if ( cell ) {
3818    this.selectedIndex = this.getCellSlideIndex( cell );
3819  }
3820  this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex );
3821
3822  this.emitEvent( 'cellChange', [ changedCellIndex ] );
3823  // position slider
3824  this.select( this.selectedIndex );
3825  // do not position slider after lazy load
3826  if ( isPositioningSlider ) {
3827    this.positionSliderAtSelected();
3828  }
3829};
3830
3831// -----  ----- //
3832
3833return Flickity;
3834
3835} ) );
3836
3837// lazyload
3838( function( window, factory ) {
3839  // universal module definition
3840  if ( typeof define == 'function' && define.amd ) {
3841    // AMD
3842    define( 'flickity/js/lazyload',[
3843      './flickity',
3844      'fizzy-ui-utils/utils',
3845    ], function( Flickity, utils ) {
3846      return factory( window, Flickity, utils );
3847    } );
3848  } else if ( typeof module == 'object' && module.exports ) {
3849    // CommonJS
3850    module.exports = factory(
3851        window,
3852        require('./flickity'),
3853        require('fizzy-ui-utils')
3854    );
3855  } else {
3856    // browser global
3857    factory(
3858        window,
3859        window.Flickity,
3860        window.fizzyUIUtils
3861    );
3862  }
3863
3864}( window, function factory( window, Flickity, utils ) {
3865'use strict';
3866
3867Flickity.createMethods.push('_createLazyload');
3868var proto = Flickity.prototype;
3869
3870proto._createLazyload = function() {
3871  this.on( 'select', this.lazyLoad );
3872};
3873
3874proto.lazyLoad = function() {
3875  var lazyLoad = this.options.lazyLoad;
3876  if ( !lazyLoad ) {
3877    return;
3878  }
3879  // get adjacent cells, use lazyLoad option for adjacent count
3880  var adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0;
3881  var cellElems = this.getAdjacentCellElements( adjCount );
3882  // get lazy images in those cells
3883  var lazyImages = [];
3884  cellElems.forEach( function( cellElem ) {
3885    var lazyCellImages = getCellLazyImages( cellElem );
3886    lazyImages = lazyImages.concat( lazyCellImages );
3887  } );
3888  // load lazy images
3889  lazyImages.forEach( function( img ) {
3890    new LazyLoader( img, this );
3891  }, this );
3892};
3893
3894function getCellLazyImages( cellElem ) {
3895  // check if cell element is lazy image
3896  if ( cellElem.nodeName == 'IMG' ) {
3897    var lazyloadAttr = cellElem.getAttribute('data-flickity-lazyload');
3898    var srcAttr = cellElem.getAttribute('data-flickity-lazyload-src');
3899    var srcsetAttr = cellElem.getAttribute('data-flickity-lazyload-srcset');
3900    if ( lazyloadAttr || srcAttr || srcsetAttr ) {
3901      return [ cellElem ];
3902    }
3903  }
3904  // select lazy images in cell
3905  var lazySelector = 'img[data-flickity-lazyload], ' +
3906    'img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]';
3907  var imgs = cellElem.querySelectorAll( lazySelector );
3908  return utils.makeArray( imgs );
3909}
3910
3911// -------------------------- LazyLoader -------------------------- //
3912
3913/**
3914 * class to handle loading images
3915 * @param {Image} img - Image element
3916 * @param {Flickity} flickity - Flickity instance
3917 */
3918function LazyLoader( img, flickity ) {
3919  this.img = img;
3920  this.flickity = flickity;
3921  this.load();
3922}
3923
3924LazyLoader.prototype.handleEvent = utils.handleEvent;
3925
3926LazyLoader.prototype.load = function() {
3927  this.img.addEventListener( 'load', this );
3928  this.img.addEventListener( 'error', this );
3929  // get src & srcset
3930  var src = this.img.getAttribute('data-flickity-lazyload') ||
3931    this.img.getAttribute('data-flickity-lazyload-src');
3932  var srcset = this.img.getAttribute('data-flickity-lazyload-srcset');
3933  // set src & serset
3934  this.img.src = src;
3935  if ( srcset ) {
3936    this.img.setAttribute( 'srcset', srcset );
3937  }
3938  // remove attr
3939  this.img.removeAttribute('data-flickity-lazyload');
3940  this.img.removeAttribute('data-flickity-lazyload-src');
3941  this.img.removeAttribute('data-flickity-lazyload-srcset');
3942};
3943
3944LazyLoader.prototype.onload = function( event ) {
3945  this.complete( event, 'flickity-lazyloaded' );
3946};
3947
3948LazyLoader.prototype.onerror = function( event ) {
3949  this.complete( event, 'flickity-lazyerror' );
3950};
3951
3952LazyLoader.prototype.complete = function( event, className ) {
3953  // unbind events
3954  this.img.removeEventListener( 'load', this );
3955  this.img.removeEventListener( 'error', this );
3956
3957  var cell = this.flickity.getParentCell( this.img );
3958  var cellElem = cell && cell.element;
3959  this.flickity.cellSizeChange( cellElem );
3960
3961  this.img.classList.add( className );
3962  this.flickity.dispatchEvent( 'lazyLoad', event, cellElem );
3963};
3964
3965// -----  ----- //
3966
3967Flickity.LazyLoader = LazyLoader;
3968
3969return Flickity;
3970
3971} ) );
3972
3973/*!
3974 * Flickity v2.2.2
3975 * Touch, responsive, flickable carousels
3976 *
3977 * Licensed GPLv3 for open source use
3978 * or Flickity Commercial License for commercial use
3979 *
3980 * https://flickity.metafizzy.co
3981 * Copyright 2015-2021 Metafizzy
3982 */
3983
3984( function( window, factory ) {
3985  // universal module definition
3986  if ( typeof define == 'function' && define.amd ) {
3987    // AMD
3988    define( 'flickity/js/index',[
3989      './flickity',
3990      './drag',
3991      './prev-next-button',
3992      './page-dots',
3993      './player',
3994      './add-remove-cell',
3995      './lazyload',
3996    ], factory );
3997  } else if ( typeof module == 'object' && module.exports ) {
3998    // CommonJS
3999    module.exports = factory(
4000        require('./flickity'),
4001        require('./drag'),
4002        require('./prev-next-button'),
4003        require('./page-dots'),
4004        require('./player'),
4005        require('./add-remove-cell'),
4006        require('./lazyload')
4007    );
4008  }
4009
4010} )( window, function factory( Flickity ) {
4011  return Flickity;
4012} );
4013
4014/*!
4015 * Flickity asNavFor v2.0.2
4016 * enable asNavFor for Flickity
4017 */
4018
4019/*jshint browser: true, undef: true, unused: true, strict: true*/
4020
4021( function( window, factory ) {
4022  // universal module definition
4023  /*jshint strict: false */ /*globals define, module, require */
4024  if ( typeof define == 'function' && define.amd ) {
4025    // AMD
4026    define( 'flickity-as-nav-for/as-nav-for',[
4027      'flickity/js/index',
4028      'fizzy-ui-utils/utils'
4029    ], factory );
4030  } else if ( typeof module == 'object' && module.exports ) {
4031    // CommonJS
4032    module.exports = factory(
4033      require('flickity'),
4034      require('fizzy-ui-utils')
4035    );
4036  } else {
4037    // browser global
4038    window.Flickity = factory(
4039      window.Flickity,
4040      window.fizzyUIUtils
4041    );
4042  }
4043
4044}( window, function factory( Flickity, utils ) {
4045
4046
4047
4048// -------------------------- asNavFor prototype -------------------------- //
4049
4050// Flickity.defaults.asNavFor = null;
4051
4052Flickity.createMethods.push('_createAsNavFor');
4053
4054var proto = Flickity.prototype;
4055
4056proto._createAsNavFor = function() {
4057  this.on( 'activate', this.activateAsNavFor );
4058  this.on( 'deactivate', this.deactivateAsNavFor );
4059  this.on( 'destroy', this.destroyAsNavFor );
4060
4061  var asNavForOption = this.options.asNavFor;
4062  if ( !asNavForOption ) {
4063    return;
4064  }
4065  // HACK do async, give time for other flickity to be initalized
4066  var _this = this;
4067  setTimeout( function initNavCompanion() {
4068    _this.setNavCompanion( asNavForOption );
4069  });
4070};
4071
4072proto.setNavCompanion = function( elem ) {
4073  elem = utils.getQueryElement( elem );
4074  var companion = Flickity.data( elem );
4075  // stop if no companion or companion is self
4076  if ( !companion || companion == this ) {
4077    return;
4078  }
4079
4080  this.navCompanion = companion;
4081  // companion select
4082  var _this = this;
4083  this.onNavCompanionSelect = function() {
4084    _this.navCompanionSelect();
4085  };
4086  companion.on( 'select', this.onNavCompanionSelect );
4087  // click
4088  this.on( 'staticClick', this.onNavStaticClick );
4089
4090  this.navCompanionSelect( true );
4091};
4092
4093proto.navCompanionSelect = function( isInstant ) {
4094  // wait for companion & selectedCells first. #8
4095  var companionCells = this.navCompanion && this.navCompanion.selectedCells;
4096  if ( !companionCells ) {
4097    return;
4098  }
4099  // select slide that matches first cell of slide
4100  var selectedCell = companionCells[0];
4101  var firstIndex = this.navCompanion.cells.indexOf( selectedCell );
4102  var lastIndex = firstIndex + companionCells.length - 1;
4103  var selectIndex = Math.floor( lerp( firstIndex, lastIndex,
4104    this.navCompanion.cellAlign ) );
4105  this.selectCell( selectIndex, false, isInstant );
4106  // set nav selected class
4107  this.removeNavSelectedElements();
vendor: 4,404 bytes, lines 4108-4293
4108  // stop if companion has more cells than this one
4109  if ( selectIndex >= this.cells.length ) {
4110    return;
4111  }
4112
4113  var selectedCells = this.cells.slice( firstIndex, lastIndex + 1 );
4114  this.navSelectedElements = selectedCells.map( function( cell ) {
4115    return cell.element;
4116  });
4117  this.changeNavSelectedClass('add');
4118};
4119
4120function lerp( a, b, t ) {
4121  return ( b - a ) * t + a;
4122}
4123
4124proto.changeNavSelectedClass = function( method ) {
4125  this.navSelectedElements.forEach( function( navElem ) {
4126    navElem.classList[ method ]('is-nav-selected');
4127  });
4128};
4129
4130proto.activateAsNavFor = function() {
4131  this.navCompanionSelect( true );
4132};
4133
4134proto.removeNavSelectedElements = function() {
4135  if ( !this.navSelectedElements ) {
4136    return;
4137  }
4138  this.changeNavSelectedClass('remove');
4139  delete this.navSelectedElements;
4140};
4141
4142proto.onNavStaticClick = function( event, pointer, cellElement, cellIndex ) {
4143  if ( typeof cellIndex == 'number' ) {
4144    this.navCompanion.selectCell( cellIndex );
4145  }
4146};
4147
4148proto.deactivateAsNavFor = function() {
4149  this.removeNavSelectedElements();
4150};
4151
4152proto.destroyAsNavFor = function() {
4153  if ( !this.navCompanion ) {
4154    return;
4155  }
4156  this.navCompanion.off( 'select', this.onNavCompanionSelect );
4157  this.off( 'staticClick', this.onNavStaticClick );
4158  delete this.navCompanion;
4159};
4160
4161// -----  ----- //
4162
4163return Flickity;
4164
4165}));
4166
4167/*!
4168 * imagesLoaded v4.1.4
4169 * JavaScript is all like "You images are done yet or what?"
4170 * MIT License
4171 */
4172
4173( function( window, factory ) { 'use strict';
4174  // universal module definition
4175
4176  /*global define: false, module: false, require: false */
4177
4178  if ( typeof define == 'function' && define.amd ) {
4179    // AMD
4180    define( 'imagesloaded/imagesloaded',[
4181      'ev-emitter/ev-emitter'
4182    ], function( EvEmitter ) {
4183      return factory( window, EvEmitter );
4184    });
4185  } else if ( typeof module == 'object' && module.exports ) {
4186    // CommonJS
4187    module.exports = factory(
4188      window,
4189      require('ev-emitter')
4190    );
4191  } else {
4192    // browser global
4193    window.imagesLoaded = factory(
4194      window,
4195      window.EvEmitter
4196    );
4197  }
4198
4199})( typeof window !== 'undefined' ? window : this,
4200
4201// --------------------------  factory -------------------------- //
4202
4203function factory( window, EvEmitter ) {
4204
4205
4206
4207var $ = window.jQuery;
4208var console = window.console;
4209
4210// -------------------------- helpers -------------------------- //
4211
4212// extend objects
4213function extend( a, b ) {
4214  for ( var prop in b ) {
4215    a[ prop ] = b[ prop ];
4216  }
4217  return a;
4218}
4219
4220var arraySlice = Array.prototype.slice;
4221
4222// turn element or nodeList into an array
4223function makeArray( obj ) {
4224  if ( Array.isArray( obj ) ) {
4225    // use object if already an array
4226    return obj;
4227  }
4228
4229  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
4230  if ( isArrayLike ) {
4231    // convert nodeList to array
4232    return arraySlice.call( obj );
4233  }
4234
4235  // array of single index
4236  return [ obj ];
4237}
4238
4239// -------------------------- imagesLoaded -------------------------- //
4240
4241/**
4242 * @param {Array, Element, NodeList, String} elem
4243 * @param {Object or Function} options - if function, use as callback
4244 * @param {Function} onAlways - callback function
4245 */
4246function ImagesLoaded( elem, options, onAlways ) {
4247  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
4248  if ( !( this instanceof ImagesLoaded ) ) {
4249    return new ImagesLoaded( elem, options, onAlways );
4250  }
4251  // use elem as selector string
4252  var queryElem = elem;
4253  if ( typeof elem == 'string' ) {
4254    queryElem = document.querySelectorAll( elem );
4255  }
4256  // bail if bad element
4257  if ( !queryElem ) {
4258    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
4259    return;
4260  }
4261
4262  this.elements = makeArray( queryElem );
4263  this.options = extend( {}, this.options );
4264  // shift arguments if no options set
4265  if ( typeof options == 'function' ) {
4266    onAlways = options;
4267  } else {
4268    extend( this.options, options );
4269  }
4270
4271  if ( onAlways ) {
4272    this.on( 'always', onAlways );
4273  }
4274
4275  this.getImages();
4276
4277  if ( $ ) {
4278    // add jQuery Deferred object
4279    this.jqDeferred = new $.Deferred();
4280  }
4281
4282  // HACK check async to allow time to bind listeners
4283  setTimeout( this.check.bind( this ) );
4284}
4285
4286ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
4287
4288ImagesLoaded.prototype.options = {};
4289
4290ImagesLoaded.prototype.getImages = function() {
4291  this.images = [];
4292
4293  // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 4294-4450
4294  this.elements.forEach( this.addElementImages, this );
4295};
4296
4297/**
4298 * @param {Node} element
4299 */
4300ImagesLoaded.prototype.addElementImages = function( elem ) {
4301  // filter siblings
4302  if ( elem.nodeName == 'IMG' ) {
4303    this.addImage( elem );
4304  }
4305  // get background image on element
4306  if ( this.options.background === true ) {
4307    this.addElementBackgroundImages( elem );
4308  }
4309
4310  // find children
4311  // no non-element nodes, #143
4312  var nodeType = elem.nodeType;
4313  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
4314    return;
4315  }
4316  var childImgs = elem.querySelectorAll('img');
4317  // concat childElems to filterFound array
4318  for ( var i=0; i < childImgs.length; i++ ) {
4319    var img = childImgs[i];
4320    this.addImage( img );
4321  }
4322
4323  // get child background images
4324  if ( typeof this.options.background == 'string' ) {
4325    var children = elem.querySelectorAll( this.options.background );
4326    for ( i=0; i < children.length; i++ ) {
4327      var child = children[i];
4328      this.addElementBackgroundImages( child );
4329    }
4330  }
4331};
4332
4333var elementNodeTypes = {
4334  1: true,
4335  9: true,
4336  11: true
4337};
4338
4339ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
4340  var style = getComputedStyle( elem );
4341  if ( !style ) {
4342    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
4343    return;
4344  }
4345  // get url inside url("...")
4346  var reURL = /url\((['"])?(.*?)\1\)/gi;
4347  var matches = reURL.exec( style.backgroundImage );
4348  while ( matches !== null ) {
4349    var url = matches && matches[2];
4350    if ( url ) {
4351      this.addBackground( url, elem );
4352    }
4353    matches = reURL.exec( style.backgroundImage );
4354  }
4355};
4356
4357/**
4358 * @param {Image} img
4359 */
4360ImagesLoaded.prototype.addImage = function( img ) {
4361  var loadingImage = new LoadingImage( img );
4362  this.images.push( loadingImage );
4363};
4364
4365ImagesLoaded.prototype.addBackground = function( url, elem ) {
4366  var background = new Background( url, elem );
4367  this.images.push( background );
4368};
4369
4370ImagesLoaded.prototype.check = function() {
4371  var _this = this;
4372  this.progressedCount = 0;
4373  this.hasAnyBroken = false;
4374  // complete if no images
4375  if ( !this.images.length ) {
4376    this.complete();
4377    return;
4378  }
4379
4380  function onProgress( image, elem, message ) {
4381    // HACK - Chrome triggers event before object properties have changed. #83
4382    setTimeout( function() {
4383      _this.progress( image, elem, message );
4384    });
4385  }
4386
4387  this.images.forEach( function( loadingImage ) {
4388    loadingImage.once( 'progress', onProgress );
4389    loadingImage.check();
4390  });
4391};
4392
4393ImagesLoaded.prototype.progress = function( image, elem, message ) {
4394  this.progressedCount++;
4395  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
4396  // progress event
4397  this.emitEvent( 'progress', [ this, image, elem ] );
4398  if ( this.jqDeferred && this.jqDeferred.notify ) {
4399    this.jqDeferred.notify( this, image );
4400  }
4401  // check if completed
4402  if ( this.progressedCount == this.images.length ) {
4403    this.complete();
4404  }
4405
4406  if ( this.options.debug && console ) {
4407    console.log( 'progress: ' + message, image, elem );
4408  }
4409};
4410
4411ImagesLoaded.prototype.complete = function() {
4412  var eventName = this.hasAnyBroken ? 'fail' : 'done';
4413  this.isComplete = true;
4414  this.emitEvent( eventName, [ this ] );
4415  this.emitEvent( 'always', [ this ] );
4416  if ( this.jqDeferred ) {
4417    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
4418    this.jqDeferred[ jqMethod ]( this );
4419  }
4420};
4421
4422// --------------------------  -------------------------- //
4423
4424function LoadingImage( img ) {
4425  this.img = img;
4426}
4427
4428LoadingImage.prototype = Object.create( EvEmitter.prototype );
4429
4430LoadingImage.prototype.check = function() {
4431  // If complete is true and browser supports natural sizes,
4432  // try to check for image status manually.
4433  var isComplete = this.getIsImageComplete();
4434  if ( isComplete ) {
4435    // report based on naturalWidth
4436    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
4437    return;
4438  }
4439
4440  // If none of the checks above matched, simulate loading on detached element.
4441  this.proxyImage = new Image();
4442  this.proxyImage.addEventListener( 'load', this );
4443  this.proxyImage.addEventListener( 'error', this );
4444  // bind to image as well for Firefox. #191
4445  this.img.addEventListener( 'load', this );
4446  this.img.addEventListener( 'error', this );
4447  this.proxyImage.src = this.img.src;
4448};
4449
4450LoadingImage.prototype.getIsImageComplete = function() {
vendor: 4,126 bytes, lines 4451-4607
4451  // check for non-zero, non-undefined naturalWidth
4452  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
4453  return this.img.complete && this.img.naturalWidth;
4454};
4455
4456LoadingImage.prototype.confirm = function( isLoaded, message ) {
4457  this.isLoaded = isLoaded;
4458  this.emitEvent( 'progress', [ this, this.img, message ] );
4459};
4460
4461// ----- events ----- //
4462
4463// trigger specified handler for event type
4464LoadingImage.prototype.handleEvent = function( event ) {
4465  var method = 'on' + event.type;
4466  if ( this[ method ] ) {
4467    this[ method ]( event );
4468  }
4469};
4470
4471LoadingImage.prototype.onload = function() {
4472  this.confirm( true, 'onload' );
4473  this.unbindEvents();
4474};
4475
4476LoadingImage.prototype.onerror = function() {
4477  this.confirm( false, 'onerror' );
4478  this.unbindEvents();
4479};
4480
4481LoadingImage.prototype.unbindEvents = function() {
4482  this.proxyImage.removeEventListener( 'load', this );
4483  this.proxyImage.removeEventListener( 'error', this );
4484  this.img.removeEventListener( 'load', this );
4485  this.img.removeEventListener( 'error', this );
4486};
4487
4488// -------------------------- Background -------------------------- //
4489
4490function Background( url, element ) {
4491  this.url = url;
4492  this.element = element;
4493  this.img = new Image();
4494}
4495
4496// inherit LoadingImage prototype
4497Background.prototype = Object.create( LoadingImage.prototype );
4498
4499Background.prototype.check = function() {
4500  this.img.addEventListener( 'load', this );
4501  this.img.addEventListener( 'error', this );
4502  this.img.src = this.url;
4503  // check if image is already complete
4504  var isComplete = this.getIsImageComplete();
4505  if ( isComplete ) {
4506    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
4507    this.unbindEvents();
4508  }
4509};
4510
4511Background.prototype.unbindEvents = function() {
4512  this.img.removeEventListener( 'load', this );
4513  this.img.removeEventListener( 'error', this );
4514};
4515
4516Background.prototype.confirm = function( isLoaded, message ) {
4517  this.isLoaded = isLoaded;
4518  this.emitEvent( 'progress', [ this, this.element, message ] );
4519};
4520
4521// -------------------------- jQuery -------------------------- //
4522
4523ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
4524  jQuery = jQuery || window.jQuery;
4525  if ( !jQuery ) {
4526    return;
4527  }
4528  // set local variable
4529  $ = jQuery;
4530  // $().imagesLoaded()
4531  $.fn.imagesLoaded = function( options, callback ) {
4532    var instance = new ImagesLoaded( this, options, callback );
4533    return instance.jqDeferred.promise( $(this) );
4534  };
4535};
4536// try making plugin
4537ImagesLoaded.makeJQueryPlugin();
4538
4539// --------------------------  -------------------------- //
4540
4541return ImagesLoaded;
4542
4543});
4544
4545/*!
4546 * Flickity imagesLoaded v2.0.0
4547 * enables imagesLoaded option for Flickity
4548 */
4549
4550/*jshint browser: true, strict: true, undef: true, unused: true */
4551
4552( function( window, factory ) {
4553  // universal module definition
4554  /*jshint strict: false */ /*globals define, module, require */
4555  if ( typeof define == 'function' && define.amd ) {
4556    // AMD
4557    define( [
4558      'flickity/js/index',
4559      'imagesloaded/imagesloaded'
4560    ], function( Flickity, imagesLoaded ) {
4561      return factory( window, Flickity, imagesLoaded );
4562    });
4563  } else if ( typeof module == 'object' && module.exports ) {
4564    // CommonJS
4565    module.exports = factory(
4566      window,
4567      require('flickity'),
4568      require('imagesloaded')
4569    );
4570  } else {
4571    // browser global
4572    window.Flickity = factory(
4573      window,
4574      window.Flickity,
4575      window.imagesLoaded
4576    );
4577  }
4578
4579}( window, function factory( window, Flickity, imagesLoaded ) {
4580'use strict';
4581
4582Flickity.createMethods.push('_createImagesLoaded');
4583
4584var proto = Flickity.prototype;
4585
4586proto._createImagesLoaded = function() {
4587  this.on( 'activate', this.imagesLoaded );
4588};
4589
4590proto.imagesLoaded = function() {
4591  if ( !this.options.imagesLoaded ) {
4592    return;
4593  }
4594  var _this = this;
4595  function onImagesLoadedProgress( instance, image ) {
4596    var cell = _this.getParentCell( image.img );
4597    _this.cellSizeChange( cell && cell.element );
4598    if ( !_this.options.freeScroll ) {
4599      _this.positionSliderAtSelected();
4600    }
4601  }
4602  imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress );
4603};
4604
4605return Flickity;
4606
4607}));

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