phcthemes_admin_panel_pack 5.0.0 → 5.1.0

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