UNPKG

90.1 kBJavaScriptView Raw
1/*!
2 * Glide.js v3.6.0
3 * (c) 2013-2022 Jędrzej Chałubek (https://github.com/jedrzejchalubek/)
4 * Released under the MIT License.
5 */
6
7function _typeof(obj) {
8 "@babel/helpers - typeof";
9
10 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
11 _typeof = function (obj) {
12 return typeof obj;
13 };
14 } else {
15 _typeof = function (obj) {
16 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
17 };
18 }
19
20 return _typeof(obj);
21}
22
23function _classCallCheck(instance, Constructor) {
24 if (!(instance instanceof Constructor)) {
25 throw new TypeError("Cannot call a class as a function");
26 }
27}
28
29function _defineProperties(target, props) {
30 for (var i = 0; i < props.length; i++) {
31 var descriptor = props[i];
32 descriptor.enumerable = descriptor.enumerable || false;
33 descriptor.configurable = true;
34 if ("value" in descriptor) descriptor.writable = true;
35 Object.defineProperty(target, descriptor.key, descriptor);
36 }
37}
38
39function _createClass(Constructor, protoProps, staticProps) {
40 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
41 if (staticProps) _defineProperties(Constructor, staticProps);
42 return Constructor;
43}
44
45function _inherits(subClass, superClass) {
46 if (typeof superClass !== "function" && superClass !== null) {
47 throw new TypeError("Super expression must either be null or a function");
48 }
49
50 subClass.prototype = Object.create(superClass && superClass.prototype, {
51 constructor: {
52 value: subClass,
53 writable: true,
54 configurable: true
55 }
56 });
57 if (superClass) _setPrototypeOf(subClass, superClass);
58}
59
60function _getPrototypeOf(o) {
61 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
62 return o.__proto__ || Object.getPrototypeOf(o);
63 };
64 return _getPrototypeOf(o);
65}
66
67function _setPrototypeOf(o, p) {
68 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
69 o.__proto__ = p;
70 return o;
71 };
72
73 return _setPrototypeOf(o, p);
74}
75
76function _isNativeReflectConstruct() {
77 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
78 if (Reflect.construct.sham) return false;
79 if (typeof Proxy === "function") return true;
80
81 try {
82 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
83 return true;
84 } catch (e) {
85 return false;
86 }
87}
88
89function _assertThisInitialized(self) {
90 if (self === void 0) {
91 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
92 }
93
94 return self;
95}
96
97function _possibleConstructorReturn(self, call) {
98 if (call && (typeof call === "object" || typeof call === "function")) {
99 return call;
100 } else if (call !== void 0) {
101 throw new TypeError("Derived constructors may only return object or undefined");
102 }
103
104 return _assertThisInitialized(self);
105}
106
107function _createSuper(Derived) {
108 var hasNativeReflectConstruct = _isNativeReflectConstruct();
109
110 return function _createSuperInternal() {
111 var Super = _getPrototypeOf(Derived),
112 result;
113
114 if (hasNativeReflectConstruct) {
115 var NewTarget = _getPrototypeOf(this).constructor;
116
117 result = Reflect.construct(Super, arguments, NewTarget);
118 } else {
119 result = Super.apply(this, arguments);
120 }
121
122 return _possibleConstructorReturn(this, result);
123 };
124}
125
126function _superPropBase(object, property) {
127 while (!Object.prototype.hasOwnProperty.call(object, property)) {
128 object = _getPrototypeOf(object);
129 if (object === null) break;
130 }
131
132 return object;
133}
134
135function _get() {
136 if (typeof Reflect !== "undefined" && Reflect.get) {
137 _get = Reflect.get;
138 } else {
139 _get = function _get(target, property, receiver) {
140 var base = _superPropBase(target, property);
141
142 if (!base) return;
143 var desc = Object.getOwnPropertyDescriptor(base, property);
144
145 if (desc.get) {
146 return desc.get.call(arguments.length < 3 ? target : receiver);
147 }
148
149 return desc.value;
150 };
151 }
152
153 return _get.apply(this, arguments);
154}
155
156var defaults = {
157 /**
158 * Type of the movement.
159 *
160 * Available types:
161 * `slider` - Rewinds slider to the start/end when it reaches the first or last slide.
162 * `carousel` - Changes slides without starting over when it reaches the first or last slide.
163 *
164 * @type {String}
165 */
166 type: 'slider',
167
168 /**
169 * Start at specific slide number defined with zero-based index.
170 *
171 * @type {Number}
172 */
173 startAt: 0,
174
175 /**
176 * A number of slides visible on the single viewport.
177 *
178 * @type {Number}
179 */
180 perView: 1,
181
182 /**
183 * Focus currently active slide at a specified position in the track.
184 *
185 * Available inputs:
186 * `center` - Current slide will be always focused at the center of a track.
187 * `0,1,2,3...` - Current slide will be focused on the specified zero-based index.
188 *
189 * @type {String|Number}
190 */
191 focusAt: 0,
192
193 /**
194 * A size of the gap added between slides.
195 *
196 * @type {Number}
197 */
198 gap: 10,
199
200 /**
201 * Change slides after a specified interval. Use `false` for turning off autoplay.
202 *
203 * @type {Number|Boolean}
204 */
205 autoplay: false,
206
207 /**
208 * Stop autoplay on mouseover event.
209 *
210 * @type {Boolean}
211 */
212 hoverpause: true,
213
214 /**
215 * Allow for changing slides with left and right keyboard arrows.
216 *
217 * @type {Boolean}
218 */
219 keyboard: true,
220
221 /**
222 * Stop running `perView` number of slides from the end. Use this
223 * option if you don't want to have an empty space after
224 * a slider. Works only with `slider` type and a
225 * non-centered `focusAt` setting.
226 *
227 * @type {Boolean}
228 */
229 bound: false,
230
231 /**
232 * Minimal swipe distance needed to change the slide. Use `false` for turning off a swiping.
233 *
234 * @type {Number|Boolean}
235 */
236 swipeThreshold: 80,
237
238 /**
239 * Minimal mouse drag distance needed to change the slide. Use `false` for turning off a dragging.
240 *
241 * @type {Number|Boolean}
242 */
243 dragThreshold: 120,
244
245 /**
246 * A number of slides moved on single swipe.
247 *
248 * Available types:
249 * `` - Moves slider by one slide per swipe
250 * `|` - Moves slider between views per swipe (number of slides defined in `perView` options)
251 *
252 * @type {String}
253 */
254 perSwipe: '',
255
256 /**
257 * Moving distance ratio of the slides on a swiping and dragging.
258 *
259 * @type {Number}
260 */
261 touchRatio: 0.5,
262
263 /**
264 * Angle required to activate slides moving on swiping or dragging.
265 *
266 * @type {Number}
267 */
268 touchAngle: 45,
269
270 /**
271 * Duration of the animation in milliseconds.
272 *
273 * @type {Number}
274 */
275 animationDuration: 400,
276
277 /**
278 * Allows looping the `slider` type. Slider will rewind to the first/last slide when it's at the start/end.
279 *
280 * @type {Boolean}
281 */
282 rewind: true,
283
284 /**
285 * Duration of the rewinding animation of the `slider` type in milliseconds.
286 *
287 * @type {Number}
288 */
289 rewindDuration: 800,
290
291 /**
292 * Easing function for the animation.
293 *
294 * @type {String}
295 */
296 animationTimingFunc: 'cubic-bezier(.165, .840, .440, 1)',
297
298 /**
299 * Wait for the animation to finish until the next user input can be processed
300 *
301 * @type {boolean}
302 */
303 waitForTransition: true,
304
305 /**
306 * Throttle costly events at most once per every wait milliseconds.
307 *
308 * @type {Number}
309 */
310 throttle: 10,
311
312 /**
313 * Moving direction mode.
314 *
315 * Available inputs:
316 * - 'ltr' - left to right movement,
317 * - 'rtl' - right to left movement.
318 *
319 * @type {String}
320 */
321 direction: 'ltr',
322
323 /**
324 * The distance value of the next and previous viewports which
325 * have to peek in the current view. Accepts number and
326 * pixels as a string. Left and right peeking can be
327 * set up separately with a directions object.
328 *
329 * For example:
330 * `100` - Peek 100px on the both sides.
331 * { before: 100, after: 50 }` - Peek 100px on the left side and 50px on the right side.
332 *
333 * @type {Number|String|Object}
334 */
335 peek: 0,
336
337 /**
338 * Defines how many clones of current viewport will be generated.
339 *
340 * @type {Number}
341 */
342 cloningRatio: 1,
343
344 /**
345 * Collection of options applied at specified media breakpoints.
346 * For example: display two slides per view under 800px.
347 * `{
348 * '800px': {
349 * perView: 2
350 * }
351 * }`
352 */
353 breakpoints: {},
354
355 /**
356 * Collection of internally used HTML classes.
357 *
358 * @todo Refactor `slider` and `carousel` properties to single `type: { slider: '', carousel: '' }` object
359 * @type {Object}
360 */
361 classes: {
362 swipeable: 'glide--swipeable',
363 dragging: 'glide--dragging',
364 direction: {
365 ltr: 'glide--ltr',
366 rtl: 'glide--rtl'
367 },
368 type: {
369 slider: 'glide--slider',
370 carousel: 'glide--carousel'
371 },
372 slide: {
373 clone: 'glide__slide--clone',
374 active: 'glide__slide--active'
375 },
376 arrow: {
377 disabled: 'glide__arrow--disabled'
378 },
379 nav: {
380 active: 'glide__bullet--active'
381 }
382 }
383};
384
385/**
386 * Outputs warning message to the bowser console.
387 *
388 * @param {String} msg
389 * @return {Void}
390 */
391function warn(msg) {
392 console.error("[Glide warn]: ".concat(msg));
393}
394
395/**
396 * Converts value entered as number
397 * or string to integer value.
398 *
399 * @param {String} value
400 * @returns {Number}
401 */
402function toInt(value) {
403 return parseInt(value);
404}
405/**
406 * Converts value entered as number
407 * or string to flat value.
408 *
409 * @param {String} value
410 * @returns {Number}
411 */
412
413function toFloat(value) {
414 return parseFloat(value);
415}
416/**
417 * Indicates whether the specified value is a string.
418 *
419 * @param {*} value
420 * @return {Boolean}
421 */
422
423function isString(value) {
424 return typeof value === 'string';
425}
426/**
427 * Indicates whether the specified value is an object.
428 *
429 * @param {*} value
430 * @return {Boolean}
431 *
432 * @see https://github.com/jashkenas/underscore
433 */
434
435function isObject(value) {
436 var type = _typeof(value);
437
438 return type === 'function' || type === 'object' && !!value; // eslint-disable-line no-mixed-operators
439}
440/**
441 * Indicates whether the specified value is a function.
442 *
443 * @param {*} value
444 * @return {Boolean}
445 */
446
447function isFunction(value) {
448 return typeof value === 'function';
449}
450/**
451 * Indicates whether the specified value is undefined.
452 *
453 * @param {*} value
454 * @return {Boolean}
455 */
456
457function isUndefined(value) {
458 return typeof value === 'undefined';
459}
460/**
461 * Indicates whether the specified value is an array.
462 *
463 * @param {*} value
464 * @return {Boolean}
465 */
466
467function isArray(value) {
468 return value.constructor === Array;
469}
470
471/**
472 * Creates and initializes specified collection of extensions.
473 * Each extension receives access to instance of glide and rest of components.
474 *
475 * @param {Object} glide
476 * @param {Object} extensions
477 *
478 * @returns {Object}
479 */
480
481function mount(glide, extensions, events) {
482 var components = {};
483
484 for (var name in extensions) {
485 if (isFunction(extensions[name])) {
486 components[name] = extensions[name](glide, components, events);
487 } else {
488 warn('Extension must be a function');
489 }
490 }
491
492 for (var _name in components) {
493 if (isFunction(components[_name].mount)) {
494 components[_name].mount();
495 }
496 }
497
498 return components;
499}
500
501/**
502 * Defines getter and setter property on the specified object.
503 *
504 * @param {Object} obj Object where property has to be defined.
505 * @param {String} prop Name of the defined property.
506 * @param {Object} definition Get and set definitions for the property.
507 * @return {Void}
508 */
509function define(obj, prop, definition) {
510 Object.defineProperty(obj, prop, definition);
511}
512/**
513 * Sorts aphabetically object keys.
514 *
515 * @param {Object} obj
516 * @return {Object}
517 */
518
519function sortKeys(obj) {
520 return Object.keys(obj).sort().reduce(function (r, k) {
521 r[k] = obj[k];
522 return r[k], r;
523 }, {});
524}
525/**
526 * Merges passed settings object with default options.
527 *
528 * @param {Object} defaults
529 * @param {Object} settings
530 * @return {Object}
531 */
532
533function mergeOptions(defaults, settings) {
534 var options = Object.assign({}, defaults, settings); // `Object.assign` do not deeply merge objects, so we
535 // have to do it manually for every nested object
536 // in options. Although it does not look smart,
537 // it's smaller and faster than some fancy
538 // merging deep-merge algorithm script.
539
540 if (settings.hasOwnProperty('classes')) {
541 options.classes = Object.assign({}, defaults.classes, settings.classes);
542
543 if (settings.classes.hasOwnProperty('direction')) {
544 options.classes.direction = Object.assign({}, defaults.classes.direction, settings.classes.direction);
545 }
546
547 if (settings.classes.hasOwnProperty('type')) {
548 options.classes.type = Object.assign({}, defaults.classes.type, settings.classes.type);
549 }
550
551 if (settings.classes.hasOwnProperty('slide')) {
552 options.classes.slide = Object.assign({}, defaults.classes.slide, settings.classes.slide);
553 }
554
555 if (settings.classes.hasOwnProperty('arrow')) {
556 options.classes.arrow = Object.assign({}, defaults.classes.arrow, settings.classes.arrow);
557 }
558
559 if (settings.classes.hasOwnProperty('nav')) {
560 options.classes.nav = Object.assign({}, defaults.classes.nav, settings.classes.nav);
561 }
562 }
563
564 if (settings.hasOwnProperty('breakpoints')) {
565 options.breakpoints = Object.assign({}, defaults.breakpoints, settings.breakpoints);
566 }
567
568 return options;
569}
570
571var EventsBus = /*#__PURE__*/function () {
572 /**
573 * Construct a EventBus instance.
574 *
575 * @param {Object} events
576 */
577 function EventsBus() {
578 var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
579
580 _classCallCheck(this, EventsBus);
581
582 this.events = events;
583 this.hop = events.hasOwnProperty;
584 }
585 /**
586 * Adds listener to the specifed event.
587 *
588 * @param {String|Array} event
589 * @param {Function} handler
590 */
591
592
593 _createClass(EventsBus, [{
594 key: "on",
595 value: function on(event, handler) {
596 if (isArray(event)) {
597 for (var i = 0; i < event.length; i++) {
598 this.on(event[i], handler);
599 }
600
601 return;
602 } // Create the event's object if not yet created
603
604
605 if (!this.hop.call(this.events, event)) {
606 this.events[event] = [];
607 } // Add the handler to queue
608
609
610 var index = this.events[event].push(handler) - 1; // Provide handle back for removal of event
611
612 return {
613 remove: function remove() {
614 delete this.events[event][index];
615 }
616 };
617 }
618 /**
619 * Runs registered handlers for specified event.
620 *
621 * @param {String|Array} event
622 * @param {Object=} context
623 */
624
625 }, {
626 key: "emit",
627 value: function emit(event, context) {
628 if (isArray(event)) {
629 for (var i = 0; i < event.length; i++) {
630 this.emit(event[i], context);
631 }
632
633 return;
634 } // If the event doesn't exist, or there's no handlers in queue, just leave
635
636
637 if (!this.hop.call(this.events, event)) {
638 return;
639 } // Cycle through events queue, fire!
640
641
642 this.events[event].forEach(function (item) {
643 item(context || {});
644 });
645 }
646 }]);
647
648 return EventsBus;
649}();
650
651var Glide$1 = /*#__PURE__*/function () {
652 /**
653 * Construct glide.
654 *
655 * @param {String} selector
656 * @param {Object} options
657 */
658 function Glide(selector) {
659 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
660
661 _classCallCheck(this, Glide);
662
663 this._c = {};
664 this._t = [];
665 this._e = new EventsBus();
666 this.disabled = false;
667 this.selector = selector;
668 this.settings = mergeOptions(defaults, options);
669 this.index = this.settings.startAt;
670 }
671 /**
672 * Initializes glide.
673 *
674 * @param {Object} extensions Collection of extensions to initialize.
675 * @return {Glide}
676 */
677
678
679 _createClass(Glide, [{
680 key: "mount",
681 value: function mount$1() {
682 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
683
684 this._e.emit('mount.before');
685
686 if (isObject(extensions)) {
687 this._c = mount(this, extensions, this._e);
688 } else {
689 warn('You need to provide a object on `mount()`');
690 }
691
692 this._e.emit('mount.after');
693
694 return this;
695 }
696 /**
697 * Collects an instance `translate` transformers.
698 *
699 * @param {Array} transformers Collection of transformers.
700 * @return {Void}
701 */
702
703 }, {
704 key: "mutate",
705 value: function mutate() {
706 var transformers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
707
708 if (isArray(transformers)) {
709 this._t = transformers;
710 } else {
711 warn('You need to provide a array on `mutate()`');
712 }
713
714 return this;
715 }
716 /**
717 * Updates glide with specified settings.
718 *
719 * @param {Object} settings
720 * @return {Glide}
721 */
722
723 }, {
724 key: "update",
725 value: function update() {
726 var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
727 this.settings = mergeOptions(this.settings, settings);
728
729 if (settings.hasOwnProperty('startAt')) {
730 this.index = settings.startAt;
731 }
732
733 this._e.emit('update');
734
735 return this;
736 }
737 /**
738 * Change slide with specified pattern. A pattern must be in the special format:
739 * `>` - Move one forward
740 * `<` - Move one backward
741 * `={i}` - Go to {i} zero-based slide (eq. '=1', will go to second slide)
742 * `>>` - Rewinds to end (last slide)
743 * `<<` - Rewinds to start (first slide)
744 * `|>` - Move one viewport forward
745 * `|<` - Move one viewport backward
746 *
747 * @param {String} pattern
748 * @return {Glide}
749 */
750
751 }, {
752 key: "go",
753 value: function go(pattern) {
754 this._c.Run.make(pattern);
755
756 return this;
757 }
758 /**
759 * Move track by specified distance.
760 *
761 * @param {String} distance
762 * @return {Glide}
763 */
764
765 }, {
766 key: "move",
767 value: function move(distance) {
768 this._c.Transition.disable();
769
770 this._c.Move.make(distance);
771
772 return this;
773 }
774 /**
775 * Destroy instance and revert all changes done by this._c.
776 *
777 * @return {Glide}
778 */
779
780 }, {
781 key: "destroy",
782 value: function destroy() {
783 this._e.emit('destroy');
784
785 return this;
786 }
787 /**
788 * Start instance autoplaying.
789 *
790 * @param {Boolean|Number} interval Run autoplaying with passed interval regardless of `autoplay` settings
791 * @return {Glide}
792 */
793
794 }, {
795 key: "play",
796 value: function play() {
797 var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
798
799 if (interval) {
800 this.settings.autoplay = interval;
801 }
802
803 this._e.emit('play');
804
805 return this;
806 }
807 /**
808 * Stop instance autoplaying.
809 *
810 * @return {Glide}
811 */
812
813 }, {
814 key: "pause",
815 value: function pause() {
816 this._e.emit('pause');
817
818 return this;
819 }
820 /**
821 * Sets glide into a idle status.
822 *
823 * @return {Glide}
824 */
825
826 }, {
827 key: "disable",
828 value: function disable() {
829 this.disabled = true;
830 return this;
831 }
832 /**
833 * Sets glide into a active status.
834 *
835 * @return {Glide}
836 */
837
838 }, {
839 key: "enable",
840 value: function enable() {
841 this.disabled = false;
842 return this;
843 }
844 /**
845 * Adds cuutom event listener with handler.
846 *
847 * @param {String|Array} event
848 * @param {Function} handler
849 * @return {Glide}
850 */
851
852 }, {
853 key: "on",
854 value: function on(event, handler) {
855 this._e.on(event, handler);
856
857 return this;
858 }
859 /**
860 * Checks if glide is a precised type.
861 *
862 * @param {String} name
863 * @return {Boolean}
864 */
865
866 }, {
867 key: "isType",
868 value: function isType(name) {
869 return this.settings.type === name;
870 }
871 /**
872 * Gets value of the core options.
873 *
874 * @return {Object}
875 */
876
877 }, {
878 key: "settings",
879 get: function get() {
880 return this._o;
881 }
882 /**
883 * Sets value of the core options.
884 *
885 * @param {Object} o
886 * @return {Void}
887 */
888 ,
889 set: function set(o) {
890 if (isObject(o)) {
891 this._o = o;
892 } else {
893 warn('Options must be an `object` instance.');
894 }
895 }
896 /**
897 * Gets current index of the slider.
898 *
899 * @return {Object}
900 */
901
902 }, {
903 key: "index",
904 get: function get() {
905 return this._i;
906 }
907 /**
908 * Sets current index a slider.
909 *
910 * @return {Object}
911 */
912 ,
913 set: function set(i) {
914 this._i = toInt(i);
915 }
916 /**
917 * Gets type name of the slider.
918 *
919 * @return {String}
920 */
921
922 }, {
923 key: "type",
924 get: function get() {
925 return this.settings.type;
926 }
927 /**
928 * Gets value of the idle status.
929 *
930 * @return {Boolean}
931 */
932
933 }, {
934 key: "disabled",
935 get: function get() {
936 return this._d;
937 }
938 /**
939 * Sets value of the idle status.
940 *
941 * @return {Boolean}
942 */
943 ,
944 set: function set(status) {
945 this._d = !!status;
946 }
947 }]);
948
949 return Glide;
950}();
951
952function Run (Glide, Components, Events) {
953 var Run = {
954 /**
955 * Initializes autorunning of the glide.
956 *
957 * @return {Void}
958 */
959 mount: function mount() {
960 this._o = false;
961 },
962
963 /**
964 * Makes glides running based on the passed moving schema.
965 *
966 * @param {String} move
967 */
968 make: function make(move) {
969 var _this = this;
970
971 if (!Glide.disabled) {
972 !Glide.settings.waitForTransition || Glide.disable();
973 this.move = move;
974 Events.emit('run.before', this.move);
975 this.calculate();
976 Events.emit('run', this.move);
977 Components.Transition.after(function () {
978 if (_this.isStart()) {
979 Events.emit('run.start', _this.move);
980 }
981
982 if (_this.isEnd()) {
983 Events.emit('run.end', _this.move);
984 }
985
986 if (_this.isOffset()) {
987 _this._o = false;
988 Events.emit('run.offset', _this.move);
989 }
990
991 Events.emit('run.after', _this.move);
992 Glide.enable();
993 });
994 }
995 },
996
997 /**
998 * Calculates current index based on defined move.
999 *
1000 * @return {Number|Undefined}
1001 */
1002 calculate: function calculate() {
1003 var move = this.move,
1004 length = this.length;
1005 var steps = move.steps,
1006 direction = move.direction; // By default assume that size of view is equal to one slide
1007
1008 var viewSize = 1; // While direction is `=` we want jump to
1009 // a specified index described in steps.
1010
1011 if (direction === '=') {
1012 // Check if bound is true,
1013 // as we want to avoid whitespaces.
1014 if (Glide.settings.bound && toInt(steps) > length) {
1015 Glide.index = length;
1016 return;
1017 }
1018
1019 Glide.index = steps;
1020 return;
1021 } // When pattern is equal to `>>` we want
1022 // fast forward to the last slide.
1023
1024
1025 if (direction === '>' && steps === '>') {
1026 Glide.index = length;
1027 return;
1028 } // When pattern is equal to `<<` we want
1029 // fast forward to the first slide.
1030
1031
1032 if (direction === '<' && steps === '<') {
1033 Glide.index = 0;
1034 return;
1035 } // pagination movement
1036
1037
1038 if (direction === '|') {
1039 viewSize = Glide.settings.perView || 1;
1040 } // we are moving forward
1041
1042
1043 if (direction === '>' || direction === '|' && steps === '>') {
1044 var index = calculateForwardIndex(viewSize);
1045
1046 if (index > length) {
1047 this._o = true;
1048 }
1049
1050 Glide.index = normalizeForwardIndex(index, viewSize);
1051 return;
1052 } // we are moving backward
1053
1054
1055 if (direction === '<' || direction === '|' && steps === '<') {
1056 var _index = calculateBackwardIndex(viewSize);
1057
1058 if (_index < 0) {
1059 this._o = true;
1060 }
1061
1062 Glide.index = normalizeBackwardIndex(_index, viewSize);
1063 return;
1064 }
1065
1066 warn("Invalid direction pattern [".concat(direction).concat(steps, "] has been used"));
1067 },
1068
1069 /**
1070 * Checks if we are on the first slide.
1071 *
1072 * @return {Boolean}
1073 */
1074 isStart: function isStart() {
1075 return Glide.index <= 0;
1076 },
1077
1078 /**
1079 * Checks if we are on the last slide.
1080 *
1081 * @return {Boolean}
1082 */
1083 isEnd: function isEnd() {
1084 return Glide.index >= this.length;
1085 },
1086
1087 /**
1088 * Checks if we are making a offset run.
1089 *
1090 * @param {String} direction
1091 * @return {Boolean}
1092 */
1093 isOffset: function isOffset() {
1094 var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
1095
1096 if (!direction) {
1097 return this._o;
1098 }
1099
1100 if (!this._o) {
1101 return false;
1102 } // did we view to the right?
1103
1104
1105 if (direction === '|>') {
1106 return this.move.direction === '|' && this.move.steps === '>';
1107 } // did we view to the left?
1108
1109
1110 if (direction === '|<') {
1111 return this.move.direction === '|' && this.move.steps === '<';
1112 }
1113
1114 return this.move.direction === direction;
1115 },
1116
1117 /**
1118 * Checks if bound mode is active
1119 *
1120 * @return {Boolean}
1121 */
1122 isBound: function isBound() {
1123 return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound;
1124 }
1125 };
1126 /**
1127 * Returns index value to move forward/to the right
1128 *
1129 * @param viewSize
1130 * @returns {Number}
1131 */
1132
1133 function calculateForwardIndex(viewSize) {
1134 var index = Glide.index;
1135
1136 if (Glide.isType('carousel')) {
1137 return index + viewSize;
1138 }
1139
1140 return index + (viewSize - index % viewSize);
1141 }
1142 /**
1143 * Normalizes the given forward index based on glide settings, preventing it to exceed certain boundaries
1144 *
1145 * @param index
1146 * @param length
1147 * @param viewSize
1148 * @returns {Number}
1149 */
1150
1151
1152 function normalizeForwardIndex(index, viewSize) {
1153 var length = Run.length;
1154
1155 if (index <= length) {
1156 return index;
1157 }
1158
1159 if (Glide.isType('carousel')) {
1160 return index - (length + 1);
1161 }
1162
1163 if (Glide.settings.rewind) {
1164 // bound does funny things with the length, therefor we have to be certain
1165 // that we are on the last possible index value given by bound
1166 if (Run.isBound() && !Run.isEnd()) {
1167 return length;
1168 }
1169
1170 return 0;
1171 }
1172
1173 if (Run.isBound()) {
1174 return length;
1175 }
1176
1177 return Math.floor(length / viewSize) * viewSize;
1178 }
1179 /**
1180 * Calculates index value to move backward/to the left
1181 *
1182 * @param viewSize
1183 * @returns {Number}
1184 */
1185
1186
1187 function calculateBackwardIndex(viewSize) {
1188 var index = Glide.index;
1189
1190 if (Glide.isType('carousel')) {
1191 return index - viewSize;
1192 } // ensure our back navigation results in the same index as a forward navigation
1193 // to experience a homogeneous paging
1194
1195
1196 var view = Math.ceil(index / viewSize);
1197 return (view - 1) * viewSize;
1198 }
1199 /**
1200 * Normalizes the given backward index based on glide settings, preventing it to exceed certain boundaries
1201 *
1202 * @param index
1203 * @param length
1204 * @param viewSize
1205 * @returns {*}
1206 */
1207
1208
1209 function normalizeBackwardIndex(index, viewSize) {
1210 var length = Run.length;
1211
1212 if (index >= 0) {
1213 return index;
1214 }
1215
1216 if (Glide.isType('carousel')) {
1217 return index + (length + 1);
1218 }
1219
1220 if (Glide.settings.rewind) {
1221 // bound does funny things with the length, therefor we have to be certain
1222 // that we are on first possible index value before we to rewind to the length given by bound
1223 if (Run.isBound() && Run.isStart()) {
1224 return length;
1225 }
1226
1227 return Math.floor(length / viewSize) * viewSize;
1228 }
1229
1230 return 0;
1231 }
1232
1233 define(Run, 'move', {
1234 /**
1235 * Gets value of the move schema.
1236 *
1237 * @returns {Object}
1238 */
1239 get: function get() {
1240 return this._m;
1241 },
1242
1243 /**
1244 * Sets value of the move schema.
1245 *
1246 * @returns {Object}
1247 */
1248 set: function set(value) {
1249 var step = value.substr(1);
1250 this._m = {
1251 direction: value.substr(0, 1),
1252 steps: step ? toInt(step) ? toInt(step) : step : 0
1253 };
1254 }
1255 });
1256 define(Run, 'length', {
1257 /**
1258 * Gets value of the running distance based
1259 * on zero-indexing number of slides.
1260 *
1261 * @return {Number}
1262 */
1263 get: function get() {
1264 var settings = Glide.settings;
1265 var length = Components.Html.slides.length; // If the `bound` option is active, a maximum running distance should be
1266 // reduced by `perView` and `focusAt` settings. Running distance
1267 // should end before creating an empty space after instance.
1268
1269 if (this.isBound()) {
1270 return length - 1 - (toInt(settings.perView) - 1) + toInt(settings.focusAt);
1271 }
1272
1273 return length - 1;
1274 }
1275 });
1276 define(Run, 'offset', {
1277 /**
1278 * Gets status of the offsetting flag.
1279 *
1280 * @return {Boolean}
1281 */
1282 get: function get() {
1283 return this._o;
1284 }
1285 });
1286 return Run;
1287}
1288
1289/**
1290 * Returns a current time.
1291 *
1292 * @return {Number}
1293 */
1294function now() {
1295 return new Date().getTime();
1296}
1297
1298/**
1299 * Returns a function, that, when invoked, will only be triggered
1300 * at most once during a given window of time.
1301 *
1302 * @param {Function} func
1303 * @param {Number} wait
1304 * @param {Object=} options
1305 * @return {Function}
1306 *
1307 * @see https://github.com/jashkenas/underscore
1308 */
1309
1310function throttle(func, wait, options) {
1311 var timeout, context, args, result;
1312 var previous = 0;
1313 if (!options) options = {};
1314
1315 var later = function later() {
1316 previous = options.leading === false ? 0 : now();
1317 timeout = null;
1318 result = func.apply(context, args);
1319 if (!timeout) context = args = null;
1320 };
1321
1322 var throttled = function throttled() {
1323 var at = now();
1324 if (!previous && options.leading === false) previous = at;
1325 var remaining = wait - (at - previous);
1326 context = this;
1327 args = arguments;
1328
1329 if (remaining <= 0 || remaining > wait) {
1330 if (timeout) {
1331 clearTimeout(timeout);
1332 timeout = null;
1333 }
1334
1335 previous = at;
1336 result = func.apply(context, args);
1337 if (!timeout) context = args = null;
1338 } else if (!timeout && options.trailing !== false) {
1339 timeout = setTimeout(later, remaining);
1340 }
1341
1342 return result;
1343 };
1344
1345 throttled.cancel = function () {
1346 clearTimeout(timeout);
1347 previous = 0;
1348 timeout = context = args = null;
1349 };
1350
1351 return throttled;
1352}
1353
1354var MARGIN_TYPE = {
1355 ltr: ['marginLeft', 'marginRight'],
1356 rtl: ['marginRight', 'marginLeft']
1357};
1358function Gaps (Glide, Components, Events) {
1359 var Gaps = {
1360 /**
1361 * Applies gaps between slides. First and last
1362 * slides do not receive it's edge margins.
1363 *
1364 * @param {HTMLCollection} slides
1365 * @return {Void}
1366 */
1367 apply: function apply(slides) {
1368 for (var i = 0, len = slides.length; i < len; i++) {
1369 var style = slides[i].style;
1370 var direction = Components.Direction.value;
1371
1372 if (i !== 0) {
1373 style[MARGIN_TYPE[direction][0]] = "".concat(this.value / 2, "px");
1374 } else {
1375 style[MARGIN_TYPE[direction][0]] = '';
1376 }
1377
1378 if (i !== slides.length - 1) {
1379 style[MARGIN_TYPE[direction][1]] = "".concat(this.value / 2, "px");
1380 } else {
1381 style[MARGIN_TYPE[direction][1]] = '';
1382 }
1383 }
1384 },
1385
1386 /**
1387 * Removes gaps from the slides.
1388 *
1389 * @param {HTMLCollection} slides
1390 * @returns {Void}
1391 */
1392 remove: function remove(slides) {
1393 for (var i = 0, len = slides.length; i < len; i++) {
1394 var style = slides[i].style;
1395 style.marginLeft = '';
1396 style.marginRight = '';
1397 }
1398 }
1399 };
1400 define(Gaps, 'value', {
1401 /**
1402 * Gets value of the gap.
1403 *
1404 * @returns {Number}
1405 */
1406 get: function get() {
1407 return toInt(Glide.settings.gap);
1408 }
1409 });
1410 define(Gaps, 'grow', {
1411 /**
1412 * Gets additional dimensions value caused by gaps.
1413 * Used to increase width of the slides wrapper.
1414 *
1415 * @returns {Number}
1416 */
1417 get: function get() {
1418 return Gaps.value * Components.Sizes.length;
1419 }
1420 });
1421 define(Gaps, 'reductor', {
1422 /**
1423 * Gets reduction value caused by gaps.
1424 * Used to subtract width of the slides.
1425 *
1426 * @returns {Number}
1427 */
1428 get: function get() {
1429 var perView = Glide.settings.perView;
1430 return Gaps.value * (perView - 1) / perView;
1431 }
1432 });
1433 /**
1434 * Apply calculated gaps:
1435 * - after building, so slides (including clones) will receive proper margins
1436 * - on updating via API, to recalculate gaps with new options
1437 */
1438
1439 Events.on(['build.after', 'update'], throttle(function () {
1440 Gaps.apply(Components.Html.wrapper.children);
1441 }, 30));
1442 /**
1443 * Remove gaps:
1444 * - on destroying to bring markup to its inital state
1445 */
1446
1447 Events.on('destroy', function () {
1448 Gaps.remove(Components.Html.wrapper.children);
1449 });
1450 return Gaps;
1451}
1452
1453/**
1454 * Finds siblings nodes of the passed node.
1455 *
1456 * @param {Element} node
1457 * @return {Array}
1458 */
1459function siblings(node) {
1460 if (node && node.parentNode) {
1461 var n = node.parentNode.firstChild;
1462 var matched = [];
1463
1464 for (; n; n = n.nextSibling) {
1465 if (n.nodeType === 1 && n !== node) {
1466 matched.push(n);
1467 }
1468 }
1469
1470 return matched;
1471 }
1472
1473 return [];
1474}
1475/**
1476 * Checks if passed node exist and is a valid element.
1477 *
1478 * @param {Element} node
1479 * @return {Boolean}
1480 */
1481
1482function exist(node) {
1483 if (node && node instanceof window.HTMLElement) {
1484 return true;
1485 }
1486
1487 return false;
1488}
1489/**
1490 * Coerces a NodeList to an Array.
1491 *
1492 * @param {NodeList} nodeList
1493 * @return {Array}
1494 */
1495
1496function toArray(nodeList) {
1497 return Array.prototype.slice.call(nodeList);
1498}
1499
1500var TRACK_SELECTOR = '[data-glide-el="track"]';
1501function Html (Glide, Components, Events) {
1502 var Html = {
1503 /**
1504 * Setup slider HTML nodes.
1505 *
1506 * @param {Glide} glide
1507 */
1508 mount: function mount() {
1509 this.root = Glide.selector;
1510 this.track = this.root.querySelector(TRACK_SELECTOR);
1511 this.collectSlides();
1512 },
1513
1514 /**
1515 * Collect slides
1516 */
1517 collectSlides: function collectSlides() {
1518 this.slides = toArray(this.wrapper.children).filter(function (slide) {
1519 return !slide.classList.contains(Glide.settings.classes.slide.clone);
1520 });
1521 }
1522 };
1523 define(Html, 'root', {
1524 /**
1525 * Gets node of the glide main element.
1526 *
1527 * @return {Object}
1528 */
1529 get: function get() {
1530 return Html._r;
1531 },
1532
1533 /**
1534 * Sets node of the glide main element.
1535 *
1536 * @return {Object}
1537 */
1538 set: function set(r) {
1539 if (isString(r)) {
1540 r = document.querySelector(r);
1541 }
1542
1543 if (exist(r)) {
1544 Html._r = r;
1545 } else {
1546 warn('Root element must be a existing Html node');
1547 }
1548 }
1549 });
1550 define(Html, 'track', {
1551 /**
1552 * Gets node of the glide track with slides.
1553 *
1554 * @return {Object}
1555 */
1556 get: function get() {
1557 return Html._t;
1558 },
1559
1560 /**
1561 * Sets node of the glide track with slides.
1562 *
1563 * @return {Object}
1564 */
1565 set: function set(t) {
1566 if (exist(t)) {
1567 Html._t = t;
1568 } else {
1569 warn("Could not find track element. Please use ".concat(TRACK_SELECTOR, " attribute."));
1570 }
1571 }
1572 });
1573 define(Html, 'wrapper', {
1574 /**
1575 * Gets node of the slides wrapper.
1576 *
1577 * @return {Object}
1578 */
1579 get: function get() {
1580 return Html.track.children[0];
1581 }
1582 });
1583 /**
1584 * Add/remove/reorder dynamic slides
1585 */
1586
1587 Events.on('update', function () {
1588 Html.collectSlides();
1589 });
1590 return Html;
1591}
1592
1593function Peek (Glide, Components, Events) {
1594 var Peek = {
1595 /**
1596 * Setups how much to peek based on settings.
1597 *
1598 * @return {Void}
1599 */
1600 mount: function mount() {
1601 this.value = Glide.settings.peek;
1602 }
1603 };
1604 define(Peek, 'value', {
1605 /**
1606 * Gets value of the peek.
1607 *
1608 * @returns {Number|Object}
1609 */
1610 get: function get() {
1611 return Peek._v;
1612 },
1613
1614 /**
1615 * Sets value of the peek.
1616 *
1617 * @param {Number|Object} value
1618 * @return {Void}
1619 */
1620 set: function set(value) {
1621 if (isObject(value)) {
1622 value.before = toInt(value.before);
1623 value.after = toInt(value.after);
1624 } else {
1625 value = toInt(value);
1626 }
1627
1628 Peek._v = value;
1629 }
1630 });
1631 define(Peek, 'reductor', {
1632 /**
1633 * Gets reduction value caused by peek.
1634 *
1635 * @returns {Number}
1636 */
1637 get: function get() {
1638 var value = Peek.value;
1639 var perView = Glide.settings.perView;
1640
1641 if (isObject(value)) {
1642 return value.before / perView + value.after / perView;
1643 }
1644
1645 return value * 2 / perView;
1646 }
1647 });
1648 /**
1649 * Recalculate peeking sizes on:
1650 * - when resizing window to update to proper percents
1651 */
1652
1653 Events.on(['resize', 'update'], function () {
1654 Peek.mount();
1655 });
1656 return Peek;
1657}
1658
1659function Move (Glide, Components, Events) {
1660 var Move = {
1661 /**
1662 * Constructs move component.
1663 *
1664 * @returns {Void}
1665 */
1666 mount: function mount() {
1667 this._o = 0;
1668 },
1669
1670 /**
1671 * Calculates a movement value based on passed offset and currently active index.
1672 *
1673 * @param {Number} offset
1674 * @return {Void}
1675 */
1676 make: function make() {
1677 var _this = this;
1678
1679 var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
1680 this.offset = offset;
1681 Events.emit('move', {
1682 movement: this.value
1683 });
1684 Components.Transition.after(function () {
1685 Events.emit('move.after', {
1686 movement: _this.value
1687 });
1688 });
1689 }
1690 };
1691 define(Move, 'offset', {
1692 /**
1693 * Gets an offset value used to modify current translate.
1694 *
1695 * @return {Object}
1696 */
1697 get: function get() {
1698 return Move._o;
1699 },
1700
1701 /**
1702 * Sets an offset value used to modify current translate.
1703 *
1704 * @return {Object}
1705 */
1706 set: function set(value) {
1707 Move._o = !isUndefined(value) ? toInt(value) : 0;
1708 }
1709 });
1710 define(Move, 'translate', {
1711 /**
1712 * Gets a raw movement value.
1713 *
1714 * @return {Number}
1715 */
1716 get: function get() {
1717 return Components.Sizes.slideWidth * Glide.index;
1718 }
1719 });
1720 define(Move, 'value', {
1721 /**
1722 * Gets an actual movement value corrected by offset.
1723 *
1724 * @return {Number}
1725 */
1726 get: function get() {
1727 var offset = this.offset;
1728 var translate = this.translate;
1729
1730 if (Components.Direction.is('rtl')) {
1731 return translate + offset;
1732 }
1733
1734 return translate - offset;
1735 }
1736 });
1737 /**
1738 * Make movement to proper slide on:
1739 * - before build, so glide will start at `startAt` index
1740 * - on each standard run to move to newly calculated index
1741 */
1742
1743 Events.on(['build.before', 'run'], function () {
1744 Move.make();
1745 });
1746 return Move;
1747}
1748
1749function Sizes (Glide, Components, Events) {
1750 var Sizes = {
1751 /**
1752 * Setups dimensions of slides.
1753 *
1754 * @return {Void}
1755 */
1756 setupSlides: function setupSlides() {
1757 var width = "".concat(this.slideWidth, "px");
1758 var slides = Components.Html.slides;
1759
1760 for (var i = 0; i < slides.length; i++) {
1761 slides[i].style.width = width;
1762 }
1763 },
1764
1765 /**
1766 * Setups dimensions of slides wrapper.
1767 *
1768 * @return {Void}
1769 */
1770 setupWrapper: function setupWrapper() {
1771 Components.Html.wrapper.style.width = "".concat(this.wrapperSize, "px");
1772 },
1773
1774 /**
1775 * Removes applied styles from HTML elements.
1776 *
1777 * @returns {Void}
1778 */
1779 remove: function remove() {
1780 var slides = Components.Html.slides;
1781
1782 for (var i = 0; i < slides.length; i++) {
1783 slides[i].style.width = '';
1784 }
1785
1786 Components.Html.wrapper.style.width = '';
1787 }
1788 };
1789 define(Sizes, 'length', {
1790 /**
1791 * Gets count number of the slides.
1792 *
1793 * @return {Number}
1794 */
1795 get: function get() {
1796 return Components.Html.slides.length;
1797 }
1798 });
1799 define(Sizes, 'width', {
1800 /**
1801 * Gets width value of the slider (visible area).
1802 *
1803 * @return {Number}
1804 */
1805 get: function get() {
1806 return Components.Html.track.offsetWidth;
1807 }
1808 });
1809 define(Sizes, 'wrapperSize', {
1810 /**
1811 * Gets size of the slides wrapper.
1812 *
1813 * @return {Number}
1814 */
1815 get: function get() {
1816 return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow;
1817 }
1818 });
1819 define(Sizes, 'slideWidth', {
1820 /**
1821 * Gets width value of a single slide.
1822 *
1823 * @return {Number}
1824 */
1825 get: function get() {
1826 return Sizes.width / Glide.settings.perView - Components.Peek.reductor - Components.Gaps.reductor;
1827 }
1828 });
1829 /**
1830 * Apply calculated glide's dimensions:
1831 * - before building, so other dimensions (e.g. translate) will be calculated propertly
1832 * - when resizing window to recalculate sildes dimensions
1833 * - on updating via API, to calculate dimensions based on new options
1834 */
1835
1836 Events.on(['build.before', 'resize', 'update'], function () {
1837 Sizes.setupSlides();
1838 Sizes.setupWrapper();
1839 });
1840 /**
1841 * Remove calculated glide's dimensions:
1842 * - on destoting to bring markup to its inital state
1843 */
1844
1845 Events.on('destroy', function () {
1846 Sizes.remove();
1847 });
1848 return Sizes;
1849}
1850
1851function Build (Glide, Components, Events) {
1852 var Build = {
1853 /**
1854 * Init glide building. Adds classes, sets
1855 * dimensions and setups initial state.
1856 *
1857 * @return {Void}
1858 */
1859 mount: function mount() {
1860 Events.emit('build.before');
1861 this.typeClass();
1862 this.activeClass();
1863 Events.emit('build.after');
1864 },
1865
1866 /**
1867 * Adds `type` class to the glide element.
1868 *
1869 * @return {Void}
1870 */
1871 typeClass: function typeClass() {
1872 Components.Html.root.classList.add(Glide.settings.classes.type[Glide.settings.type]);
1873 },
1874
1875 /**
1876 * Sets active class to current slide.
1877 *
1878 * @return {Void}
1879 */
1880 activeClass: function activeClass() {
1881 var classes = Glide.settings.classes;
1882 var slide = Components.Html.slides[Glide.index];
1883
1884 if (slide) {
1885 slide.classList.add(classes.slide.active);
1886 siblings(slide).forEach(function (sibling) {
1887 sibling.classList.remove(classes.slide.active);
1888 });
1889 }
1890 },
1891
1892 /**
1893 * Removes HTML classes applied at building.
1894 *
1895 * @return {Void}
1896 */
1897 removeClasses: function removeClasses() {
1898 var _Glide$settings$class = Glide.settings.classes,
1899 type = _Glide$settings$class.type,
1900 slide = _Glide$settings$class.slide;
1901 Components.Html.root.classList.remove(type[Glide.settings.type]);
1902 Components.Html.slides.forEach(function (sibling) {
1903 sibling.classList.remove(slide.active);
1904 });
1905 }
1906 };
1907 /**
1908 * Clear building classes:
1909 * - on destroying to bring HTML to its initial state
1910 * - on updating to remove classes before remounting component
1911 */
1912
1913 Events.on(['destroy', 'update'], function () {
1914 Build.removeClasses();
1915 });
1916 /**
1917 * Remount component:
1918 * - on resizing of the window to calculate new dimensions
1919 * - on updating settings via API
1920 */
1921
1922 Events.on(['resize', 'update'], function () {
1923 Build.mount();
1924 });
1925 /**
1926 * Swap active class of current slide:
1927 * - after each move to the new index
1928 */
1929
1930 Events.on('move.after', function () {
1931 Build.activeClass();
1932 });
1933 return Build;
1934}
1935
1936function Clones (Glide, Components, Events) {
1937 var Clones = {
1938 /**
1939 * Create pattern map and collect slides to be cloned.
1940 */
1941 mount: function mount() {
1942 this.items = [];
1943
1944 if (Glide.isType('carousel')) {
1945 this.items = this.collect();
1946 }
1947 },
1948
1949 /**
1950 * Collect clones with pattern.
1951 *
1952 * @return {[]}
1953 */
1954 collect: function collect() {
1955 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1956 var slides = Components.Html.slides;
1957 var _Glide$settings = Glide.settings,
1958 perView = _Glide$settings.perView,
1959 classes = _Glide$settings.classes,
1960 cloningRatio = _Glide$settings.cloningRatio;
1961
1962 if (slides.length !== 0) {
1963 var peekIncrementer = +!!Glide.settings.peek;
1964 var cloneCount = perView + peekIncrementer + Math.round(perView / 2);
1965 var append = slides.slice(0, cloneCount).reverse();
1966 var prepend = slides.slice(cloneCount * -1);
1967
1968 for (var r = 0; r < Math.max(cloningRatio, Math.floor(perView / slides.length)); r++) {
1969 for (var i = 0; i < append.length; i++) {
1970 var clone = append[i].cloneNode(true);
1971 clone.classList.add(classes.slide.clone);
1972 items.push(clone);
1973 }
1974
1975 for (var _i = 0; _i < prepend.length; _i++) {
1976 var _clone = prepend[_i].cloneNode(true);
1977
1978 _clone.classList.add(classes.slide.clone);
1979
1980 items.unshift(_clone);
1981 }
1982 }
1983 }
1984
1985 return items;
1986 },
1987
1988 /**
1989 * Append cloned slides with generated pattern.
1990 *
1991 * @return {Void}
1992 */
1993 append: function append() {
1994 var items = this.items;
1995 var _Components$Html = Components.Html,
1996 wrapper = _Components$Html.wrapper,
1997 slides = _Components$Html.slides;
1998 var half = Math.floor(items.length / 2);
1999 var prepend = items.slice(0, half).reverse();
2000 var append = items.slice(half * -1).reverse();
2001 var width = "".concat(Components.Sizes.slideWidth, "px");
2002
2003 for (var i = 0; i < append.length; i++) {
2004 wrapper.appendChild(append[i]);
2005 }
2006
2007 for (var _i2 = 0; _i2 < prepend.length; _i2++) {
2008 wrapper.insertBefore(prepend[_i2], slides[0]);
2009 }
2010
2011 for (var _i3 = 0; _i3 < items.length; _i3++) {
2012 items[_i3].style.width = width;
2013 }
2014 },
2015
2016 /**
2017 * Remove all cloned slides.
2018 *
2019 * @return {Void}
2020 */
2021 remove: function remove() {
2022 var items = this.items;
2023
2024 for (var i = 0; i < items.length; i++) {
2025 Components.Html.wrapper.removeChild(items[i]);
2026 }
2027 }
2028 };
2029 define(Clones, 'grow', {
2030 /**
2031 * Gets additional dimensions value caused by clones.
2032 *
2033 * @return {Number}
2034 */
2035 get: function get() {
2036 return (Components.Sizes.slideWidth + Components.Gaps.value) * Clones.items.length;
2037 }
2038 });
2039 /**
2040 * Append additional slide's clones:
2041 * - while glide's type is `carousel`
2042 */
2043
2044 Events.on('update', function () {
2045 Clones.remove();
2046 Clones.mount();
2047 Clones.append();
2048 });
2049 /**
2050 * Append additional slide's clones:
2051 * - while glide's type is `carousel`
2052 */
2053
2054 Events.on('build.before', function () {
2055 if (Glide.isType('carousel')) {
2056 Clones.append();
2057 }
2058 });
2059 /**
2060 * Remove clones HTMLElements:
2061 * - on destroying, to bring HTML to its initial state
2062 */
2063
2064 Events.on('destroy', function () {
2065 Clones.remove();
2066 });
2067 return Clones;
2068}
2069
2070var EventsBinder = /*#__PURE__*/function () {
2071 /**
2072 * Construct a EventsBinder instance.
2073 */
2074 function EventsBinder() {
2075 var listeners = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2076
2077 _classCallCheck(this, EventsBinder);
2078
2079 this.listeners = listeners;
2080 }
2081 /**
2082 * Adds events listeners to arrows HTML elements.
2083 *
2084 * @param {String|Array} events
2085 * @param {Element|Window|Document} el
2086 * @param {Function} closure
2087 * @param {Boolean|Object} capture
2088 * @return {Void}
2089 */
2090
2091
2092 _createClass(EventsBinder, [{
2093 key: "on",
2094 value: function on(events, el, closure) {
2095 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
2096
2097 if (isString(events)) {
2098 events = [events];
2099 }
2100
2101 for (var i = 0; i < events.length; i++) {
2102 this.listeners[events[i]] = closure;
2103 el.addEventListener(events[i], this.listeners[events[i]], capture);
2104 }
2105 }
2106 /**
2107 * Removes event listeners from arrows HTML elements.
2108 *
2109 * @param {String|Array} events
2110 * @param {Element|Window|Document} el
2111 * @param {Boolean|Object} capture
2112 * @return {Void}
2113 */
2114
2115 }, {
2116 key: "off",
2117 value: function off(events, el) {
2118 var capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
2119
2120 if (isString(events)) {
2121 events = [events];
2122 }
2123
2124 for (var i = 0; i < events.length; i++) {
2125 el.removeEventListener(events[i], this.listeners[events[i]], capture);
2126 }
2127 }
2128 /**
2129 * Destroy collected listeners.
2130 *
2131 * @returns {Void}
2132 */
2133
2134 }, {
2135 key: "destroy",
2136 value: function destroy() {
2137 delete this.listeners;
2138 }
2139 }]);
2140
2141 return EventsBinder;
2142}();
2143
2144function Resize (Glide, Components, Events) {
2145 /**
2146 * Instance of the binder for DOM Events.
2147 *
2148 * @type {EventsBinder}
2149 */
2150 var Binder = new EventsBinder();
2151 var Resize = {
2152 /**
2153 * Initializes window bindings.
2154 */
2155 mount: function mount() {
2156 this.bind();
2157 },
2158
2159 /**
2160 * Binds `rezsize` listener to the window.
2161 * It's a costly event, so we are debouncing it.
2162 *
2163 * @return {Void}
2164 */
2165 bind: function bind() {
2166 Binder.on('resize', window, throttle(function () {
2167 Events.emit('resize');
2168 }, Glide.settings.throttle));
2169 },
2170
2171 /**
2172 * Unbinds listeners from the window.
2173 *
2174 * @return {Void}
2175 */
2176 unbind: function unbind() {
2177 Binder.off('resize', window);
2178 }
2179 };
2180 /**
2181 * Remove bindings from window:
2182 * - on destroying, to remove added EventListener
2183 */
2184
2185 Events.on('destroy', function () {
2186 Resize.unbind();
2187 Binder.destroy();
2188 });
2189 return Resize;
2190}
2191
2192var VALID_DIRECTIONS = ['ltr', 'rtl'];
2193var FLIPED_MOVEMENTS = {
2194 '>': '<',
2195 '<': '>',
2196 '=': '='
2197};
2198function Direction (Glide, Components, Events) {
2199 var Direction = {
2200 /**
2201 * Setups gap value based on settings.
2202 *
2203 * @return {Void}
2204 */
2205 mount: function mount() {
2206 this.value = Glide.settings.direction;
2207 },
2208
2209 /**
2210 * Resolves pattern based on direction value
2211 *
2212 * @param {String} pattern
2213 * @returns {String}
2214 */
2215 resolve: function resolve(pattern) {
2216 var token = pattern.slice(0, 1);
2217
2218 if (this.is('rtl')) {
2219 return pattern.split(token).join(FLIPED_MOVEMENTS[token]);
2220 }
2221
2222 return pattern;
2223 },
2224
2225 /**
2226 * Checks value of direction mode.
2227 *
2228 * @param {String} direction
2229 * @returns {Boolean}
2230 */
2231 is: function is(direction) {
2232 return this.value === direction;
2233 },
2234
2235 /**
2236 * Applies direction class to the root HTML element.
2237 *
2238 * @return {Void}
2239 */
2240 addClass: function addClass() {
2241 Components.Html.root.classList.add(Glide.settings.classes.direction[this.value]);
2242 },
2243
2244 /**
2245 * Removes direction class from the root HTML element.
2246 *
2247 * @return {Void}
2248 */
2249 removeClass: function removeClass() {
2250 Components.Html.root.classList.remove(Glide.settings.classes.direction[this.value]);
2251 }
2252 };
2253 define(Direction, 'value', {
2254 /**
2255 * Gets value of the direction.
2256 *
2257 * @returns {Number}
2258 */
2259 get: function get() {
2260 return Direction._v;
2261 },
2262
2263 /**
2264 * Sets value of the direction.
2265 *
2266 * @param {String} value
2267 * @return {Void}
2268 */
2269 set: function set(value) {
2270 if (VALID_DIRECTIONS.indexOf(value) > -1) {
2271 Direction._v = value;
2272 } else {
2273 warn('Direction value must be `ltr` or `rtl`');
2274 }
2275 }
2276 });
2277 /**
2278 * Clear direction class:
2279 * - on destroy to bring HTML to its initial state
2280 * - on update to remove class before reappling bellow
2281 */
2282
2283 Events.on(['destroy', 'update'], function () {
2284 Direction.removeClass();
2285 });
2286 /**
2287 * Remount component:
2288 * - on update to reflect changes in direction value
2289 */
2290
2291 Events.on('update', function () {
2292 Direction.mount();
2293 });
2294 /**
2295 * Apply direction class:
2296 * - before building to apply class for the first time
2297 * - on updating to reapply direction class that may changed
2298 */
2299
2300 Events.on(['build.before', 'update'], function () {
2301 Direction.addClass();
2302 });
2303 return Direction;
2304}
2305
2306/**
2307 * Reflects value of glide movement.
2308 *
2309 * @param {Object} Glide
2310 * @param {Object} Components
2311 * @return {Object}
2312 */
2313function Rtl (Glide, Components) {
2314 return {
2315 /**
2316 * Negates the passed translate if glide is in RTL option.
2317 *
2318 * @param {Number} translate
2319 * @return {Number}
2320 */
2321 modify: function modify(translate) {
2322 if (Components.Direction.is('rtl')) {
2323 return -translate;
2324 }
2325
2326 return translate;
2327 }
2328 };
2329}
2330
2331/**
2332 * Updates glide movement with a `gap` settings.
2333 *
2334 * @param {Object} Glide
2335 * @param {Object} Components
2336 * @return {Object}
2337 */
2338function Gap (Glide, Components) {
2339 return {
2340 /**
2341 * Modifies passed translate value with number in the `gap` settings.
2342 *
2343 * @param {Number} translate
2344 * @return {Number}
2345 */
2346 modify: function modify(translate) {
2347 var multiplier = Math.floor(translate / Components.Sizes.slideWidth);
2348 return translate + Components.Gaps.value * multiplier;
2349 }
2350 };
2351}
2352
2353/**
2354 * Updates glide movement with width of additional clones width.
2355 *
2356 * @param {Object} Glide
2357 * @param {Object} Components
2358 * @return {Object}
2359 */
2360function Grow (Glide, Components) {
2361 return {
2362 /**
2363 * Adds to the passed translate width of the half of clones.
2364 *
2365 * @param {Number} translate
2366 * @return {Number}
2367 */
2368 modify: function modify(translate) {
2369 return translate + Components.Clones.grow / 2;
2370 }
2371 };
2372}
2373
2374/**
2375 * Updates glide movement with a `peek` settings.
2376 *
2377 * @param {Object} Glide
2378 * @param {Object} Components
2379 * @return {Object}
2380 */
2381
2382function Peeking (Glide, Components) {
2383 return {
2384 /**
2385 * Modifies passed translate value with a `peek` setting.
2386 *
2387 * @param {Number} translate
2388 * @return {Number}
2389 */
2390 modify: function modify(translate) {
2391 if (Glide.settings.focusAt >= 0) {
2392 var peek = Components.Peek.value;
2393
2394 if (isObject(peek)) {
2395 return translate - peek.before;
2396 }
2397
2398 return translate - peek;
2399 }
2400
2401 return translate;
2402 }
2403 };
2404}
2405
2406/**
2407 * Updates glide movement with a `focusAt` settings.
2408 *
2409 * @param {Object} Glide
2410 * @param {Object} Components
2411 * @return {Object}
2412 */
2413function Focusing (Glide, Components) {
2414 return {
2415 /**
2416 * Modifies passed translate value with index in the `focusAt` setting.
2417 *
2418 * @param {Number} translate
2419 * @return {Number}
2420 */
2421 modify: function modify(translate) {
2422 var gap = Components.Gaps.value;
2423 var width = Components.Sizes.width;
2424 var focusAt = Glide.settings.focusAt;
2425 var slideWidth = Components.Sizes.slideWidth;
2426
2427 if (focusAt === 'center') {
2428 return translate - (width / 2 - slideWidth / 2);
2429 }
2430
2431 return translate - slideWidth * focusAt - gap * focusAt;
2432 }
2433 };
2434}
2435
2436/**
2437 * Applies diffrent transformers on translate value.
2438 *
2439 * @param {Object} Glide
2440 * @param {Object} Components
2441 * @return {Object}
2442 */
2443
2444function mutator (Glide, Components, Events) {
2445 /**
2446 * Merge instance transformers with collection of default transformers.
2447 * It's important that the Rtl component be last on the list,
2448 * so it reflects all previous transformations.
2449 *
2450 * @type {Array}
2451 */
2452 var TRANSFORMERS = [Gap, Grow, Peeking, Focusing].concat(Glide._t, [Rtl]);
2453 return {
2454 /**
2455 * Piplines translate value with registered transformers.
2456 *
2457 * @param {Number} translate
2458 * @return {Number}
2459 */
2460 mutate: function mutate(translate) {
2461 for (var i = 0; i < TRANSFORMERS.length; i++) {
2462 var transformer = TRANSFORMERS[i];
2463
2464 if (isFunction(transformer) && isFunction(transformer().modify)) {
2465 translate = transformer(Glide, Components, Events).modify(translate);
2466 } else {
2467 warn('Transformer should be a function that returns an object with `modify()` method');
2468 }
2469 }
2470
2471 return translate;
2472 }
2473 };
2474}
2475
2476function Translate (Glide, Components, Events) {
2477 var Translate = {
2478 /**
2479 * Sets value of translate on HTML element.
2480 *
2481 * @param {Number} value
2482 * @return {Void}
2483 */
2484 set: function set(value) {
2485 var transform = mutator(Glide, Components).mutate(value);
2486 var translate3d = "translate3d(".concat(-1 * transform, "px, 0px, 0px)");
2487 Components.Html.wrapper.style.mozTransform = translate3d; // needed for supported Firefox 10-15
2488
2489 Components.Html.wrapper.style.webkitTransform = translate3d; // needed for supported Chrome 10-35, Safari 5.1-8, and Opera 15-22
2490
2491 Components.Html.wrapper.style.transform = translate3d;
2492 },
2493
2494 /**
2495 * Removes value of translate from HTML element.
2496 *
2497 * @return {Void}
2498 */
2499 remove: function remove() {
2500 Components.Html.wrapper.style.transform = '';
2501 },
2502
2503 /**
2504 * @return {number}
2505 */
2506 getStartIndex: function getStartIndex() {
2507 var length = Components.Sizes.length;
2508 var index = Glide.index;
2509 var perView = Glide.settings.perView;
2510
2511 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {
2512 return length + (index - perView);
2513 } // "modulo length" converts an index that equals length to zero
2514
2515
2516 return (index + perView) % length;
2517 },
2518
2519 /**
2520 * @return {number}
2521 */
2522 getTravelDistance: function getTravelDistance() {
2523 var travelDistance = Components.Sizes.slideWidth * Glide.settings.perView;
2524
2525 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) {
2526 // reverse travel distance so that we don't have to change subtract operations
2527 return travelDistance * -1;
2528 }
2529
2530 return travelDistance;
2531 }
2532 };
2533 /**
2534 * Set new translate value:
2535 * - on move to reflect index change
2536 * - on updating via API to reflect possible changes in options
2537 */
2538
2539 Events.on('move', function (context) {
2540 if (!Glide.isType('carousel') || !Components.Run.isOffset()) {
2541 return Translate.set(context.movement);
2542 }
2543
2544 Components.Transition.after(function () {
2545 Events.emit('translate.jump');
2546 Translate.set(Components.Sizes.slideWidth * Glide.index);
2547 });
2548 var startWidth = Components.Sizes.slideWidth * Components.Translate.getStartIndex();
2549 return Translate.set(startWidth - Components.Translate.getTravelDistance());
2550 });
2551 /**
2552 * Remove translate:
2553 * - on destroying to bring markup to its inital state
2554 */
2555
2556 Events.on('destroy', function () {
2557 Translate.remove();
2558 });
2559 return Translate;
2560}
2561
2562function Transition (Glide, Components, Events) {
2563 /**
2564 * Holds inactivity status of transition.
2565 * When true transition is not applied.
2566 *
2567 * @type {Boolean}
2568 */
2569 var disabled = false;
2570 var Transition = {
2571 /**
2572 * Composes string of the CSS transition.
2573 *
2574 * @param {String} property
2575 * @return {String}
2576 */
2577 compose: function compose(property) {
2578 var settings = Glide.settings;
2579
2580 if (!disabled) {
2581 return "".concat(property, " ").concat(this.duration, "ms ").concat(settings.animationTimingFunc);
2582 }
2583
2584 return "".concat(property, " 0ms ").concat(settings.animationTimingFunc);
2585 },
2586
2587 /**
2588 * Sets value of transition on HTML element.
2589 *
2590 * @param {String=} property
2591 * @return {Void}
2592 */
2593 set: function set() {
2594 var property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform';
2595 Components.Html.wrapper.style.transition = this.compose(property);
2596 },
2597
2598 /**
2599 * Removes value of transition from HTML element.
2600 *
2601 * @return {Void}
2602 */
2603 remove: function remove() {
2604 Components.Html.wrapper.style.transition = '';
2605 },
2606
2607 /**
2608 * Runs callback after animation.
2609 *
2610 * @param {Function} callback
2611 * @return {Void}
2612 */
2613 after: function after(callback) {
2614 setTimeout(function () {
2615 callback();
2616 }, this.duration);
2617 },
2618
2619 /**
2620 * Enable transition.
2621 *
2622 * @return {Void}
2623 */
2624 enable: function enable() {
2625 disabled = false;
2626 this.set();
2627 },
2628
2629 /**
2630 * Disable transition.
2631 *
2632 * @return {Void}
2633 */
2634 disable: function disable() {
2635 disabled = true;
2636 this.set();
2637 }
2638 };
2639 define(Transition, 'duration', {
2640 /**
2641 * Gets duration of the transition based
2642 * on currently running animation type.
2643 *
2644 * @return {Number}
2645 */
2646 get: function get() {
2647 var settings = Glide.settings;
2648
2649 if (Glide.isType('slider') && Components.Run.offset) {
2650 return settings.rewindDuration;
2651 }
2652
2653 return settings.animationDuration;
2654 }
2655 });
2656 /**
2657 * Set transition `style` value:
2658 * - on each moving, because it may be cleared by offset move
2659 */
2660
2661 Events.on('move', function () {
2662 Transition.set();
2663 });
2664 /**
2665 * Disable transition:
2666 * - before initial build to avoid transitioning from `0` to `startAt` index
2667 * - while resizing window and recalculating dimensions
2668 * - on jumping from offset transition at start and end edges in `carousel` type
2669 */
2670
2671 Events.on(['build.before', 'resize', 'translate.jump'], function () {
2672 Transition.disable();
2673 });
2674 /**
2675 * Enable transition:
2676 * - on each running, because it may be disabled by offset move
2677 */
2678
2679 Events.on('run', function () {
2680 Transition.enable();
2681 });
2682 /**
2683 * Remove transition:
2684 * - on destroying to bring markup to its inital state
2685 */
2686
2687 Events.on('destroy', function () {
2688 Transition.remove();
2689 });
2690 return Transition;
2691}
2692
2693/**
2694 * Test via a getter in the options object to see
2695 * if the passive property is accessed.
2696 *
2697 * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
2698 */
2699var supportsPassive = false;
2700
2701try {
2702 var opts = Object.defineProperty({}, 'passive', {
2703 get: function get() {
2704 supportsPassive = true;
2705 }
2706 });
2707 window.addEventListener('testPassive', null, opts);
2708 window.removeEventListener('testPassive', null, opts);
2709} catch (e) {}
2710
2711var supportsPassive$1 = supportsPassive;
2712
2713var START_EVENTS = ['touchstart', 'mousedown'];
2714var MOVE_EVENTS = ['touchmove', 'mousemove'];
2715var END_EVENTS = ['touchend', 'touchcancel', 'mouseup', 'mouseleave'];
2716var MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseleave'];
2717function Swipe (Glide, Components, Events) {
2718 /**
2719 * Instance of the binder for DOM Events.
2720 *
2721 * @type {EventsBinder}
2722 */
2723 var Binder = new EventsBinder();
2724 var swipeSin = 0;
2725 var swipeStartX = 0;
2726 var swipeStartY = 0;
2727 var disabled = false;
2728 var capture = supportsPassive$1 ? {
2729 passive: true
2730 } : false;
2731 var Swipe = {
2732 /**
2733 * Initializes swipe bindings.
2734 *
2735 * @return {Void}
2736 */
2737 mount: function mount() {
2738 this.bindSwipeStart();
2739 },
2740
2741 /**
2742 * Handler for `swipestart` event. Calculates entry points of the user's tap.
2743 *
2744 * @param {Object} event
2745 * @return {Void}
2746 */
2747 start: function start(event) {
2748 if (!disabled && !Glide.disabled) {
2749 this.disable();
2750 var swipe = this.touches(event);
2751 swipeSin = null;
2752 swipeStartX = toInt(swipe.pageX);
2753 swipeStartY = toInt(swipe.pageY);
2754 this.bindSwipeMove();
2755 this.bindSwipeEnd();
2756 Events.emit('swipe.start');
2757 }
2758 },
2759
2760 /**
2761 * Handler for `swipemove` event. Calculates user's tap angle and distance.
2762 *
2763 * @param {Object} event
2764 */
2765 move: function move(event) {
2766 if (!Glide.disabled) {
2767 var _Glide$settings = Glide.settings,
2768 touchAngle = _Glide$settings.touchAngle,
2769 touchRatio = _Glide$settings.touchRatio,
2770 classes = _Glide$settings.classes;
2771 var swipe = this.touches(event);
2772 var subExSx = toInt(swipe.pageX) - swipeStartX;
2773 var subEySy = toInt(swipe.pageY) - swipeStartY;
2774 var powEX = Math.abs(subExSx << 2);
2775 var powEY = Math.abs(subEySy << 2);
2776 var swipeHypotenuse = Math.sqrt(powEX + powEY);
2777 var swipeCathetus = Math.sqrt(powEY);
2778 swipeSin = Math.asin(swipeCathetus / swipeHypotenuse);
2779
2780 if (swipeSin * 180 / Math.PI < touchAngle) {
2781 event.stopPropagation();
2782 Components.Move.make(subExSx * toFloat(touchRatio));
2783 Components.Html.root.classList.add(classes.dragging);
2784 Events.emit('swipe.move');
2785 } else {
2786 return false;
2787 }
2788 }
2789 },
2790
2791 /**
2792 * Handler for `swipeend` event. Finitializes user's tap and decides about glide move.
2793 *
2794 * @param {Object} event
2795 * @return {Void}
2796 */
2797 end: function end(event) {
2798 if (!Glide.disabled) {
2799 var _Glide$settings2 = Glide.settings,
2800 perSwipe = _Glide$settings2.perSwipe,
2801 touchAngle = _Glide$settings2.touchAngle,
2802 classes = _Glide$settings2.classes;
2803 var swipe = this.touches(event);
2804 var threshold = this.threshold(event);
2805 var swipeDistance = swipe.pageX - swipeStartX;
2806 var swipeDeg = swipeSin * 180 / Math.PI;
2807 this.enable();
2808
2809 if (swipeDistance > threshold && swipeDeg < touchAngle) {
2810 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<")));
2811 } else if (swipeDistance < -threshold && swipeDeg < touchAngle) {
2812 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">")));
2813 } else {
2814 // While swipe don't reach distance apply previous transform.
2815 Components.Move.make();
2816 }
2817
2818 Components.Html.root.classList.remove(classes.dragging);
2819 this.unbindSwipeMove();
2820 this.unbindSwipeEnd();
2821 Events.emit('swipe.end');
2822 }
2823 },
2824
2825 /**
2826 * Binds swipe's starting event.
2827 *
2828 * @return {Void}
2829 */
2830 bindSwipeStart: function bindSwipeStart() {
2831 var _this = this;
2832
2833 var _Glide$settings3 = Glide.settings,
2834 swipeThreshold = _Glide$settings3.swipeThreshold,
2835 dragThreshold = _Glide$settings3.dragThreshold;
2836
2837 if (swipeThreshold) {
2838 Binder.on(START_EVENTS[0], Components.Html.wrapper, function (event) {
2839 _this.start(event);
2840 }, capture);
2841 }
2842
2843 if (dragThreshold) {
2844 Binder.on(START_EVENTS[1], Components.Html.wrapper, function (event) {
2845 _this.start(event);
2846 }, capture);
2847 }
2848 },
2849
2850 /**
2851 * Unbinds swipe's starting event.
2852 *
2853 * @return {Void}
2854 */
2855 unbindSwipeStart: function unbindSwipeStart() {
2856 Binder.off(START_EVENTS[0], Components.Html.wrapper, capture);
2857 Binder.off(START_EVENTS[1], Components.Html.wrapper, capture);
2858 },
2859
2860 /**
2861 * Binds swipe's moving event.
2862 *
2863 * @return {Void}
2864 */
2865 bindSwipeMove: function bindSwipeMove() {
2866 var _this2 = this;
2867
2868 Binder.on(MOVE_EVENTS, Components.Html.wrapper, throttle(function (event) {
2869 _this2.move(event);
2870 }, Glide.settings.throttle), capture);
2871 },
2872
2873 /**
2874 * Unbinds swipe's moving event.
2875 *
2876 * @return {Void}
2877 */
2878 unbindSwipeMove: function unbindSwipeMove() {
2879 Binder.off(MOVE_EVENTS, Components.Html.wrapper, capture);
2880 },
2881
2882 /**
2883 * Binds swipe's ending event.
2884 *
2885 * @return {Void}
2886 */
2887 bindSwipeEnd: function bindSwipeEnd() {
2888 var _this3 = this;
2889
2890 Binder.on(END_EVENTS, Components.Html.wrapper, function (event) {
2891 _this3.end(event);
2892 });
2893 },
2894
2895 /**
2896 * Unbinds swipe's ending event.
2897 *
2898 * @return {Void}
2899 */
2900 unbindSwipeEnd: function unbindSwipeEnd() {
2901 Binder.off(END_EVENTS, Components.Html.wrapper);
2902 },
2903
2904 /**
2905 * Normalizes event touches points accorting to different types.
2906 *
2907 * @param {Object} event
2908 */
2909 touches: function touches(event) {
2910 if (MOUSE_EVENTS.indexOf(event.type) > -1) {
2911 return event;
2912 }
2913
2914 return event.touches[0] || event.changedTouches[0];
2915 },
2916
2917 /**
2918 * Gets value of minimum swipe distance settings based on event type.
2919 *
2920 * @return {Number}
2921 */
2922 threshold: function threshold(event) {
2923 var settings = Glide.settings;
2924
2925 if (MOUSE_EVENTS.indexOf(event.type) > -1) {
2926 return settings.dragThreshold;
2927 }
2928
2929 return settings.swipeThreshold;
2930 },
2931
2932 /**
2933 * Enables swipe event.
2934 *
2935 * @return {self}
2936 */
2937 enable: function enable() {
2938 disabled = false;
2939 Components.Transition.enable();
2940 return this;
2941 },
2942
2943 /**
2944 * Disables swipe event.
2945 *
2946 * @return {self}
2947 */
2948 disable: function disable() {
2949 disabled = true;
2950 Components.Transition.disable();
2951 return this;
2952 }
2953 };
2954 /**
2955 * Add component class:
2956 * - after initial building
2957 */
2958
2959 Events.on('build.after', function () {
2960 Components.Html.root.classList.add(Glide.settings.classes.swipeable);
2961 });
2962 /**
2963 * Remove swiping bindings:
2964 * - on destroying, to remove added EventListeners
2965 */
2966
2967 Events.on('destroy', function () {
2968 Swipe.unbindSwipeStart();
2969 Swipe.unbindSwipeMove();
2970 Swipe.unbindSwipeEnd();
2971 Binder.destroy();
2972 });
2973 return Swipe;
2974}
2975
2976function Images (Glide, Components, Events) {
2977 /**
2978 * Instance of the binder for DOM Events.
2979 *
2980 * @type {EventsBinder}
2981 */
2982 var Binder = new EventsBinder();
2983 var Images = {
2984 /**
2985 * Binds listener to glide wrapper.
2986 *
2987 * @return {Void}
2988 */
2989 mount: function mount() {
2990 this.bind();
2991 },
2992
2993 /**
2994 * Binds `dragstart` event on wrapper to prevent dragging images.
2995 *
2996 * @return {Void}
2997 */
2998 bind: function bind() {
2999 Binder.on('dragstart', Components.Html.wrapper, this.dragstart);
3000 },
3001
3002 /**
3003 * Unbinds `dragstart` event on wrapper.
3004 *
3005 * @return {Void}
3006 */
3007 unbind: function unbind() {
3008 Binder.off('dragstart', Components.Html.wrapper);
3009 },
3010
3011 /**
3012 * Event handler. Prevents dragging.
3013 *
3014 * @return {Void}
3015 */
3016 dragstart: function dragstart(event) {
3017 event.preventDefault();
3018 }
3019 };
3020 /**
3021 * Remove bindings from images:
3022 * - on destroying, to remove added EventListeners
3023 */
3024
3025 Events.on('destroy', function () {
3026 Images.unbind();
3027 Binder.destroy();
3028 });
3029 return Images;
3030}
3031
3032function Anchors (Glide, Components, Events) {
3033 /**
3034 * Instance of the binder for DOM Events.
3035 *
3036 * @type {EventsBinder}
3037 */
3038 var Binder = new EventsBinder();
3039 /**
3040 * Holds detaching status of anchors.
3041 * Prevents detaching of already detached anchors.
3042 *
3043 * @private
3044 * @type {Boolean}
3045 */
3046
3047 var detached = false;
3048 /**
3049 * Holds preventing status of anchors.
3050 * If `true` redirection after click will be disabled.
3051 *
3052 * @private
3053 * @type {Boolean}
3054 */
3055
3056 var prevented = false;
3057 var Anchors = {
3058 /**
3059 * Setups a initial state of anchors component.
3060 *
3061 * @returns {Void}
3062 */
3063 mount: function mount() {
3064 /**
3065 * Holds collection of anchors elements.
3066 *
3067 * @private
3068 * @type {HTMLCollection}
3069 */
3070 this._a = Components.Html.wrapper.querySelectorAll('a');
3071 this.bind();
3072 },
3073
3074 /**
3075 * Binds events to anchors inside a track.
3076 *
3077 * @return {Void}
3078 */
3079 bind: function bind() {
3080 Binder.on('click', Components.Html.wrapper, this.click);
3081 },
3082
3083 /**
3084 * Unbinds events attached to anchors inside a track.
3085 *
3086 * @return {Void}
3087 */
3088 unbind: function unbind() {
3089 Binder.off('click', Components.Html.wrapper);
3090 },
3091
3092 /**
3093 * Handler for click event. Prevents clicks when glide is in `prevent` status.
3094 *
3095 * @param {Object} event
3096 * @return {Void}
3097 */
3098 click: function click(event) {
3099 if (prevented) {
3100 event.stopPropagation();
3101 event.preventDefault();
3102 }
3103 },
3104
3105 /**
3106 * Detaches anchors click event inside glide.
3107 *
3108 * @return {self}
3109 */
3110 detach: function detach() {
3111 prevented = true;
3112
3113 if (!detached) {
3114 for (var i = 0; i < this.items.length; i++) {
3115 this.items[i].draggable = false;
3116 }
3117
3118 detached = true;
3119 }
3120
3121 return this;
3122 },
3123
3124 /**
3125 * Attaches anchors click events inside glide.
3126 *
3127 * @return {self}
3128 */
3129 attach: function attach() {
3130 prevented = false;
3131
3132 if (detached) {
3133 for (var i = 0; i < this.items.length; i++) {
3134 this.items[i].draggable = true;
3135 }
3136
3137 detached = false;
3138 }
3139
3140 return this;
3141 }
3142 };
3143 define(Anchors, 'items', {
3144 /**
3145 * Gets collection of the arrows HTML elements.
3146 *
3147 * @return {HTMLElement[]}
3148 */
3149 get: function get() {
3150 return Anchors._a;
3151 }
3152 });
3153 /**
3154 * Detach anchors inside slides:
3155 * - on swiping, so they won't redirect to its `href` attributes
3156 */
3157
3158 Events.on('swipe.move', function () {
3159 Anchors.detach();
3160 });
3161 /**
3162 * Attach anchors inside slides:
3163 * - after swiping and transitions ends, so they can redirect after click again
3164 */
3165
3166 Events.on('swipe.end', function () {
3167 Components.Transition.after(function () {
3168 Anchors.attach();
3169 });
3170 });
3171 /**
3172 * Unbind anchors inside slides:
3173 * - on destroying, to bring anchors to its initial state
3174 */
3175
3176 Events.on('destroy', function () {
3177 Anchors.attach();
3178 Anchors.unbind();
3179 Binder.destroy();
3180 });
3181 return Anchors;
3182}
3183
3184var NAV_SELECTOR = '[data-glide-el="controls[nav]"]';
3185var CONTROLS_SELECTOR = '[data-glide-el^="controls"]';
3186var PREVIOUS_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\"<\"]");
3187var NEXT_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\">\"]");
3188function Controls (Glide, Components, Events) {
3189 /**
3190 * Instance of the binder for DOM Events.
3191 *
3192 * @type {EventsBinder}
3193 */
3194 var Binder = new EventsBinder();
3195 var capture = supportsPassive$1 ? {
3196 passive: true
3197 } : false;
3198 var Controls = {
3199 /**
3200 * Inits arrows. Binds events listeners
3201 * to the arrows HTML elements.
3202 *
3203 * @return {Void}
3204 */
3205 mount: function mount() {
3206 /**
3207 * Collection of navigation HTML elements.
3208 *
3209 * @private
3210 * @type {HTMLCollection}
3211 */
3212 this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR);
3213 /**
3214 * Collection of controls HTML elements.
3215 *
3216 * @private
3217 * @type {HTMLCollection}
3218 */
3219
3220 this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR);
3221 /**
3222 * Collection of arrow control HTML elements.
3223 *
3224 * @private
3225 * @type {Object}
3226 */
3227
3228 this._arrowControls = {
3229 previous: Components.Html.root.querySelectorAll(PREVIOUS_CONTROLS_SELECTOR),
3230 next: Components.Html.root.querySelectorAll(NEXT_CONTROLS_SELECTOR)
3231 };
3232 this.addBindings();
3233 },
3234
3235 /**
3236 * Sets active class to current slide.
3237 *
3238 * @return {Void}
3239 */
3240 setActive: function setActive() {
3241 for (var i = 0; i < this._n.length; i++) {
3242 this.addClass(this._n[i].children);
3243 }
3244 },
3245
3246 /**
3247 * Removes active class to current slide.
3248 *
3249 * @return {Void}
3250 */
3251 removeActive: function removeActive() {
3252 for (var i = 0; i < this._n.length; i++) {
3253 this.removeClass(this._n[i].children);
3254 }
3255 },
3256
3257 /**
3258 * Toggles active class on items inside navigation.
3259 *
3260 * @param {HTMLElement} controls
3261 * @return {Void}
3262 */
3263 addClass: function addClass(controls) {
3264 var settings = Glide.settings;
3265 var item = controls[Glide.index];
3266
3267 if (!item) {
3268 return;
3269 }
3270
3271 if (item) {
3272 item.classList.add(settings.classes.nav.active);
3273 siblings(item).forEach(function (sibling) {
3274 sibling.classList.remove(settings.classes.nav.active);
3275 });
3276 }
3277 },
3278
3279 /**
3280 * Removes active class from active control.
3281 *
3282 * @param {HTMLElement} controls
3283 * @return {Void}
3284 */
3285 removeClass: function removeClass(controls) {
3286 var item = controls[Glide.index];
3287
3288 if (item) {
3289 item.classList.remove(Glide.settings.classes.nav.active);
3290 }
3291 },
3292
3293 /**
3294 * Calculates, removes or adds `Glide.settings.classes.disabledArrow` class on the control arrows
3295 */
3296 setArrowState: function setArrowState() {
3297 if (Glide.settings.rewind) {
3298 return;
3299 }
3300
3301 var next = Controls._arrowControls.next;
3302 var previous = Controls._arrowControls.previous;
3303 this.resetArrowState(next, previous);
3304
3305 if (Glide.index === 0) {
3306 this.disableArrow(previous);
3307 }
3308
3309 if (Glide.index === Components.Run.length) {
3310 this.disableArrow(next);
3311 }
3312 },
3313
3314 /**
3315 * Removes `Glide.settings.classes.disabledArrow` from given NodeList elements
3316 *
3317 * @param {NodeList[]} lists
3318 */
3319 resetArrowState: function resetArrowState() {
3320 var settings = Glide.settings;
3321
3322 for (var _len = arguments.length, lists = new Array(_len), _key = 0; _key < _len; _key++) {
3323 lists[_key] = arguments[_key];
3324 }
3325
3326 lists.forEach(function (list) {
3327 toArray(list).forEach(function (element) {
3328 element.classList.remove(settings.classes.arrow.disabled);
3329 });
3330 });
3331 },
3332
3333 /**
3334 * Adds `Glide.settings.classes.disabledArrow` to given NodeList elements
3335 *
3336 * @param {NodeList[]} lists
3337 */
3338 disableArrow: function disableArrow() {
3339 var settings = Glide.settings;
3340
3341 for (var _len2 = arguments.length, lists = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
3342 lists[_key2] = arguments[_key2];
3343 }
3344
3345 lists.forEach(function (list) {
3346 toArray(list).forEach(function (element) {
3347 element.classList.add(settings.classes.arrow.disabled);
3348 });
3349 });
3350 },
3351
3352 /**
3353 * Adds handles to the each group of controls.
3354 *
3355 * @return {Void}
3356 */
3357 addBindings: function addBindings() {
3358 for (var i = 0; i < this._c.length; i++) {
3359 this.bind(this._c[i].children);
3360 }
3361 },
3362
3363 /**
3364 * Removes handles from the each group of controls.
3365 *
3366 * @return {Void}
3367 */
3368 removeBindings: function removeBindings() {
3369 for (var i = 0; i < this._c.length; i++) {
3370 this.unbind(this._c[i].children);
3371 }
3372 },
3373
3374 /**
3375 * Binds events to arrows HTML elements.
3376 *
3377 * @param {HTMLCollection} elements
3378 * @return {Void}
3379 */
3380 bind: function bind(elements) {
3381 for (var i = 0; i < elements.length; i++) {
3382 Binder.on('click', elements[i], this.click);
3383 Binder.on('touchstart', elements[i], this.click, capture);
3384 }
3385 },
3386
3387 /**
3388 * Unbinds events binded to the arrows HTML elements.
3389 *
3390 * @param {HTMLCollection} elements
3391 * @return {Void}
3392 */
3393 unbind: function unbind(elements) {
3394 for (var i = 0; i < elements.length; i++) {
3395 Binder.off(['click', 'touchstart'], elements[i]);
3396 }
3397 },
3398
3399 /**
3400 * Handles `click` event on the arrows HTML elements.
3401 * Moves slider in direction given via the
3402 * `data-glide-dir` attribute.
3403 *
3404 * @param {Object} event
3405 * @return {void}
3406 */
3407 click: function click(event) {
3408 if (!supportsPassive$1 && event.type === 'touchstart') {
3409 event.preventDefault();
3410 }
3411
3412 var direction = event.currentTarget.getAttribute('data-glide-dir');
3413 Components.Run.make(Components.Direction.resolve(direction));
3414 }
3415 };
3416 define(Controls, 'items', {
3417 /**
3418 * Gets collection of the controls HTML elements.
3419 *
3420 * @return {HTMLElement[]}
3421 */
3422 get: function get() {
3423 return Controls._c;
3424 }
3425 });
3426 /**
3427 * Swap active class of current navigation item:
3428 * - after mounting to set it to initial index
3429 * - after each move to the new index
3430 */
3431
3432 Events.on(['mount.after', 'move.after'], function () {
3433 Controls.setActive();
3434 });
3435 /**
3436 * Add or remove disabled class of arrow elements
3437 */
3438
3439 Events.on(['mount.after', 'run'], function () {
3440 Controls.setArrowState();
3441 });
3442 /**
3443 * Remove bindings and HTML Classes:
3444 * - on destroying, to bring markup to its initial state
3445 */
3446
3447 Events.on('destroy', function () {
3448 Controls.removeBindings();
3449 Controls.removeActive();
3450 Binder.destroy();
3451 });
3452 return Controls;
3453}
3454
3455function Keyboard (Glide, Components, Events) {
3456 /**
3457 * Instance of the binder for DOM Events.
3458 *
3459 * @type {EventsBinder}
3460 */
3461 var Binder = new EventsBinder();
3462 var Keyboard = {
3463 /**
3464 * Binds keyboard events on component mount.
3465 *
3466 * @return {Void}
3467 */
3468 mount: function mount() {
3469 if (Glide.settings.keyboard) {
3470 this.bind();
3471 }
3472 },
3473
3474 /**
3475 * Adds keyboard press events.
3476 *
3477 * @return {Void}
3478 */
3479 bind: function bind() {
3480 Binder.on('keyup', document, this.press);
3481 },
3482
3483 /**
3484 * Removes keyboard press events.
3485 *
3486 * @return {Void}
3487 */
3488 unbind: function unbind() {
3489 Binder.off('keyup', document);
3490 },
3491
3492 /**
3493 * Handles keyboard's arrows press and moving glide foward and backward.
3494 *
3495 * @param {Object} event
3496 * @return {Void}
3497 */
3498 press: function press(event) {
3499 var perSwipe = Glide.settings.perSwipe;
3500
3501 if (event.code === 'ArrowRight') {
3502 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">")));
3503 }
3504
3505 if (event.code === 'ArrowLeft') {
3506 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<")));
3507 }
3508 }
3509 };
3510 /**
3511 * Remove bindings from keyboard:
3512 * - on destroying to remove added events
3513 * - on updating to remove events before remounting
3514 */
3515
3516 Events.on(['destroy', 'update'], function () {
3517 Keyboard.unbind();
3518 });
3519 /**
3520 * Remount component
3521 * - on updating to reflect potential changes in settings
3522 */
3523
3524 Events.on('update', function () {
3525 Keyboard.mount();
3526 });
3527 /**
3528 * Destroy binder:
3529 * - on destroying to remove listeners
3530 */
3531
3532 Events.on('destroy', function () {
3533 Binder.destroy();
3534 });
3535 return Keyboard;
3536}
3537
3538function Autoplay (Glide, Components, Events) {
3539 /**
3540 * Instance of the binder for DOM Events.
3541 *
3542 * @type {EventsBinder}
3543 */
3544 var Binder = new EventsBinder();
3545 var Autoplay = {
3546 /**
3547 * Initializes autoplaying and events.
3548 *
3549 * @return {Void}
3550 */
3551 mount: function mount() {
3552 this.enable();
3553 this.start();
3554
3555 if (Glide.settings.hoverpause) {
3556 this.bind();
3557 }
3558 },
3559
3560 /**
3561 * Enables autoplaying
3562 *
3563 * @returns {Void}
3564 */
3565 enable: function enable() {
3566 this._e = true;
3567 },
3568
3569 /**
3570 * Disables autoplaying.
3571 *
3572 * @returns {Void}
3573 */
3574 disable: function disable() {
3575 this._e = false;
3576 },
3577
3578 /**
3579 * Starts autoplaying in configured interval.
3580 *
3581 * @param {Boolean|Number} force Run autoplaying with passed interval regardless of `autoplay` settings
3582 * @return {Void}
3583 */
3584 start: function start() {
3585 var _this = this;
3586
3587 if (!this._e) {
3588 return;
3589 }
3590
3591 this.enable();
3592
3593 if (Glide.settings.autoplay) {
3594 if (isUndefined(this._i)) {
3595 this._i = setInterval(function () {
3596 _this.stop();
3597
3598 Components.Run.make('>');
3599
3600 _this.start();
3601
3602 Events.emit('autoplay');
3603 }, this.time);
3604 }
3605 }
3606 },
3607
3608 /**
3609 * Stops autorunning of the glide.
3610 *
3611 * @return {Void}
3612 */
3613 stop: function stop() {
3614 this._i = clearInterval(this._i);
3615 },
3616
3617 /**
3618 * Stops autoplaying while mouse is over glide's area.
3619 *
3620 * @return {Void}
3621 */
3622 bind: function bind() {
3623 var _this2 = this;
3624
3625 Binder.on('mouseover', Components.Html.root, function () {
3626 if (_this2._e) {
3627 _this2.stop();
3628 }
3629 });
3630 Binder.on('mouseout', Components.Html.root, function () {
3631 if (_this2._e) {
3632 _this2.start();
3633 }
3634 });
3635 },
3636
3637 /**
3638 * Unbind mouseover events.
3639 *
3640 * @returns {Void}
3641 */
3642 unbind: function unbind() {
3643 Binder.off(['mouseover', 'mouseout'], Components.Html.root);
3644 }
3645 };
3646 define(Autoplay, 'time', {
3647 /**
3648 * Gets time period value for the autoplay interval. Prioritizes
3649 * times in `data-glide-autoplay` attrubutes over options.
3650 *
3651 * @return {Number}
3652 */
3653 get: function get() {
3654 var autoplay = Components.Html.slides[Glide.index].getAttribute('data-glide-autoplay');
3655
3656 if (autoplay) {
3657 return toInt(autoplay);
3658 }
3659
3660 return toInt(Glide.settings.autoplay);
3661 }
3662 });
3663 /**
3664 * Stop autoplaying and unbind events:
3665 * - on destroying, to clear defined interval
3666 * - on updating via API to reset interval that may changed
3667 */
3668
3669 Events.on(['destroy', 'update'], function () {
3670 Autoplay.unbind();
3671 });
3672 /**
3673 * Stop autoplaying:
3674 * - before each run, to restart autoplaying
3675 * - on pausing via API
3676 * - on destroying, to clear defined interval
3677 * - while starting a swipe
3678 * - on updating via API to reset interval that may changed
3679 */
3680
3681 Events.on(['run.before', 'swipe.start', 'update'], function () {
3682 Autoplay.stop();
3683 });
3684 Events.on(['pause', 'destroy'], function () {
3685 Autoplay.disable();
3686 Autoplay.stop();
3687 });
3688 /**
3689 * Start autoplaying:
3690 * - after each run, to restart autoplaying
3691 * - on playing via API
3692 * - while ending a swipe
3693 */
3694
3695 Events.on(['run.after', 'swipe.end'], function () {
3696 Autoplay.start();
3697 });
3698 /**
3699 * Start autoplaying:
3700 * - after each run, to restart autoplaying
3701 * - on playing via API
3702 * - while ending a swipe
3703 */
3704
3705 Events.on(['play'], function () {
3706 Autoplay.enable();
3707 Autoplay.start();
3708 });
3709 /**
3710 * Remount autoplaying:
3711 * - on updating via API to reset interval that may changed
3712 */
3713
3714 Events.on('update', function () {
3715 Autoplay.mount();
3716 });
3717 /**
3718 * Destroy a binder:
3719 * - on destroying glide instance to clearup listeners
3720 */
3721
3722 Events.on('destroy', function () {
3723 Binder.destroy();
3724 });
3725 return Autoplay;
3726}
3727
3728/**
3729 * Sorts keys of breakpoint object so they will be ordered from lower to bigger.
3730 *
3731 * @param {Object} points
3732 * @returns {Object}
3733 */
3734
3735function sortBreakpoints(points) {
3736 if (isObject(points)) {
3737 return sortKeys(points);
3738 } else {
3739 warn("Breakpoints option must be an object");
3740 }
3741
3742 return {};
3743}
3744
3745function Breakpoints (Glide, Components, Events) {
3746 /**
3747 * Instance of the binder for DOM Events.
3748 *
3749 * @type {EventsBinder}
3750 */
3751 var Binder = new EventsBinder();
3752 /**
3753 * Holds reference to settings.
3754 *
3755 * @type {Object}
3756 */
3757
3758 var settings = Glide.settings;
3759 /**
3760 * Holds reference to breakpoints object in settings. Sorts breakpoints
3761 * from smaller to larger. It is required in order to proper
3762 * matching currently active breakpoint settings.
3763 *
3764 * @type {Object}
3765 */
3766
3767 var points = sortBreakpoints(settings.breakpoints);
3768 /**
3769 * Cache initial settings before overwritting.
3770 *
3771 * @type {Object}
3772 */
3773
3774 var defaults = Object.assign({}, settings);
3775 var Breakpoints = {
3776 /**
3777 * Matches settings for currectly matching media breakpoint.
3778 *
3779 * @param {Object} points
3780 * @returns {Object}
3781 */
3782 match: function match(points) {
3783 if (typeof window.matchMedia !== 'undefined') {
3784 for (var point in points) {
3785 if (points.hasOwnProperty(point)) {
3786 if (window.matchMedia("(max-width: ".concat(point, "px)")).matches) {
3787 return points[point];
3788 }
3789 }
3790 }
3791 }
3792
3793 return defaults;
3794 }
3795 };
3796 /**
3797 * Overwrite instance settings with currently matching breakpoint settings.
3798 * This happens right after component initialization.
3799 */
3800
3801 Object.assign(settings, Breakpoints.match(points));
3802 /**
3803 * Update glide with settings of matched brekpoint:
3804 * - window resize to update slider
3805 */
3806
3807 Binder.on('resize', window, throttle(function () {
3808 Glide.settings = mergeOptions(settings, Breakpoints.match(points));
3809 }, Glide.settings.throttle));
3810 /**
3811 * Resort and update default settings:
3812 * - on reinit via API, so breakpoint matching will be performed with options
3813 */
3814
3815 Events.on('update', function () {
3816 points = sortBreakpoints(points);
3817 defaults = Object.assign({}, settings);
3818 });
3819 /**
3820 * Unbind resize listener:
3821 * - on destroying, to bring markup to its initial state
3822 */
3823
3824 Events.on('destroy', function () {
3825 Binder.off('resize', window);
3826 });
3827 return Breakpoints;
3828}
3829
3830var COMPONENTS = {
3831 // Required
3832 Html: Html,
3833 Translate: Translate,
3834 Transition: Transition,
3835 Direction: Direction,
3836 Peek: Peek,
3837 Sizes: Sizes,
3838 Gaps: Gaps,
3839 Move: Move,
3840 Clones: Clones,
3841 Resize: Resize,
3842 Build: Build,
3843 Run: Run,
3844 // Optional
3845 Swipe: Swipe,
3846 Images: Images,
3847 Anchors: Anchors,
3848 Controls: Controls,
3849 Keyboard: Keyboard,
3850 Autoplay: Autoplay,
3851 Breakpoints: Breakpoints
3852};
3853
3854var Glide = /*#__PURE__*/function (_Core) {
3855 _inherits(Glide, _Core);
3856
3857 var _super = _createSuper(Glide);
3858
3859 function Glide() {
3860 _classCallCheck(this, Glide);
3861
3862 return _super.apply(this, arguments);
3863 }
3864
3865 _createClass(Glide, [{
3866 key: "mount",
3867 value: function mount() {
3868 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3869 return _get(_getPrototypeOf(Glide.prototype), "mount", this).call(this, Object.assign({}, COMPONENTS, extensions));
3870 }
3871 }]);
3872
3873 return Glide;
3874}(Glide$1);
3875
3876export { Glide as default };