PageSourceSearch

https://www.azurhotelvancouver.com/wp-content/themes/salient/js/build/third-party/flickity.min.js?ver=2.3

js azurhotelvancouver.com collected 2026-10-08 09:55:25 UTC 122,445 bytes, 4,683 lines download raw bytes

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

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.