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