{"version":3,"file":"splide.js","sources":["../../src/js/core/event.js","../../src/js/core/state.js","../../src/js/utils/object.js","../../src/js/utils/utils.js","../../src/js/utils/dom.js","../../src/js/constants/types.js","../../src/js/transitions/slide/index.js","../../src/js/transitions/fade/index.js","../../src/js/core/composer.js","../../src/js/utils/error.js","../../src/js/constants/classes.js","../../src/js/constants/i18n.js","../../src/js/constants/defaults.js","../../src/js/constants/states.js","../../src/js/splide.js","../../src/js/components/options/index.js","../../src/js/constants/directions.js","../../src/js/components/elements/slide.js","../../src/js/components/elements/index.js","../../src/js/components/controller/index.js","../../src/js/components/track/index.js","../../src/js/components/clones/index.js","../../src/js/components/layout/directions/horizontal.js","../../src/js/components/layout/directions/vertical.js","../../src/js/utils/time.js","../../src/js/components/layout/index.js","../../src/js/components/drag/index.js","../../src/js/components/click/index.js","../../src/js/components/autoplay/index.js","../../src/js/components/cover/index.js","../../src/js/components/arrows/path.js","../../src/js/components/arrows/index.js","../../src/js/components/pagination/index.js","../../src/js/components/lazyload/index.js","../../src/js/constants/a11y.js","../../src/js/components/keyboard/index.js","../../src/js/components/a11y/index.js","../../src/js/components/sync/index.js","../../src/js/components/breakpoints/index.js","../../src/js/components/index.js","../../src/js/build/default/default.js"],"sourcesContent":["/**\r\n * The function for providing an Event object simply managing events.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n\r\n/**\r\n * The function for providing an Event object simply managing events.\r\n */\r\nexport default () => {\r\n\t/**\r\n\t * Store all event data.\r\n\t *\r\n\t * @type {Array}\r\n\t */\r\n\tlet data = [];\r\n\r\n\tconst Event = {\r\n\t\t/**\r\n\t\t * Subscribe the given event(s).\r\n\t\t *\r\n\t\t * @param {string} events - An event name. Use space to separate multiple events.\r\n\t\t * Also, namespace is accepted by dot, such as 'resize.{namespace}'.\r\n\t\t * @param {function} handler - A callback function.\r\n\t\t * @param {Element} elm - Optional. Native event will be listened to when this arg is provided.\r\n\t\t * @param {Object} options - Optional. Options for addEventListener.\r\n\t\t */\r\n\t\ton( events, handler, elm = null, options = {} ) {\r\n\t\t\tevents.split( ' ' ).forEach( event => {\r\n\t\t\t\tif ( elm ) {\r\n\t\t\t\t\telm.addEventListener( event, handler, options );\r\n\t\t\t\t}\r\n\r\n\t\t\t\tdata.push( { event, handler, elm, options } );\r\n\t\t\t} );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Unsubscribe the given event(s).\r\n\t\t *\r\n\t\t * @param {string} events - A event name or names split by space.\r\n\t\t * @param {Element} elm - Optional. removeEventListener() will be called when this arg is provided.\r\n\t\t */\r\n\t\toff( events, elm = null ) {\r\n\t\t\tevents.split( ' ' ).forEach( event => {\r\n\t\t\t\tdata = data.filter( item => {\r\n\t\t\t\t\tif ( item && item.event === event && item.elm === elm ) {\r\n\t\t\t\t\t\tunsubscribe( item );\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t} );\r\n\t\t\t} );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Emit an event.\r\n\t\t * This method is only for custom events.\r\n\t\t *\r\n\t\t * @param {string} event - An event name.\r\n\t\t * @param {*} args - Any number of arguments passed to handlers.\r\n\t\t */\r\n\t\temit( event, ...args ) {\r\n\t\t\tdata.forEach( item => {\r\n\t\t\t\tif ( ! item.elm && item.event.split( '.' )[0] === event ) {\r\n\t\t\t\t\titem.handler( ...args );\r\n\t\t\t\t}\r\n\t\t\t} );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Clear event data.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tdata.forEach( unsubscribe );\r\n\t\t\tdata = [];\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Remove the registered event listener.\r\n\t *\r\n\t * @param {Object} item - An object containing event data.\r\n\t */\r\n\tfunction unsubscribe( item ) {\r\n\t\tif ( item.elm ) {\r\n\t\t\titem.elm.removeEventListener( item.event, item.handler, item.options );\r\n\t\t}\r\n\t}\r\n\r\n\treturn Event;\r\n}","/**\r\n * The function providing a super simple state system.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * The function providing a super simple state system.\r\n *\r\n * @param {string|number} initialState - Provide the initial state value.\r\n */\r\nexport default initialState => {\r\n\t/**\r\n\t * Store the current state.\r\n\t *\r\n\t * @type {string|number}\r\n\t */\r\n\tlet curr = initialState;\r\n\r\n\treturn {\r\n\t\t/**\r\n\t\t * Change state.\r\n\t\t *\r\n\t\t * @param {string|number} state - A new state.\r\n\t\t */\r\n\t\tset( state ) {\r\n\t\t\tcurr = state;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Verify if the current state is given one or not.\r\n\t\t *\r\n\t\t * @param {string|number} state - A state name to be verified.\r\n\t\t *\r\n\t\t * @return {boolean} - True if the current state is the given one.\r\n\t\t */\r\n\t\tis( state ) {\r\n\t\t\treturn state === curr;\r\n\t\t},\r\n\t}\r\n}","/**\r\n * Some utility functions related with Object, supporting IE.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nconst { keys } = Object;\r\n\r\n/**\r\n * Iterate an object like Array.forEach.\r\n * IE doesn't support forEach of HTMLCollection.\r\n *\r\n * @param {Object} obj - An object.\r\n * @param {function} callback - A function handling each value. Arguments are value, property and index.\r\n */\r\nexport function each( obj, callback ) {\r\n\tkeys( obj ).some( ( key, index ) => {\r\n\t\treturn callback( obj[ key ], key, index );\r\n\t} );\r\n}\r\n\r\n/**\r\n * Return values of the given object as an array.\r\n * IE doesn't support Object.values.\r\n *\r\n * @param {Object} obj - An object.\r\n *\r\n * @return {Array} - An array containing all values of the given object.\r\n */\r\nexport function values( obj ) {\r\n\treturn keys( obj ).map( key => obj[ key ] );\r\n}\r\n\r\n/**\r\n * Check if the given subject is object or not.\r\n *\r\n * @param {*} subject - A subject to be verified.\r\n *\r\n * @return {boolean} - True if object, false otherwise.\r\n */\r\nexport function isObject( subject ) {\r\n\treturn typeof subject === 'object';\r\n}\r\n\r\n/**\r\n * Merge two objects deeply.\r\n *\r\n * @param {Object} to - An object where \"from\" is merged.\r\n * @param {Object} from - An object merged to \"to\".\r\n *\r\n * @return {Object} - A merged object.\r\n */\r\nexport function merge( { ...to }, from ) {\r\n\teach( from, ( value, key ) => {\r\n\t\tif ( isObject( value ) ) {\r\n\t\t\tif ( ! isObject( to[ key ] ) ) {\r\n\t\t\t\tto[ key ] = {};\r\n\t\t\t}\r\n\r\n\t\t\tto[ key ] = merge( to[ key ], value );\r\n\t\t} else {\r\n\t\t\tto[ key ] = value;\r\n\t\t}\r\n\t} );\r\n\r\n\treturn to;\r\n}\r\n\r\n/**\r\n * Assign all properties \"from\" to \"to\" object.\r\n *\r\n * @param {Object} to - An object where properties are assigned.\r\n * @param {Object} from - An object whose properties are assigned to \"to\".\r\n *\r\n * @return {Object} - An assigned object.\r\n */\r\nexport function assign( to, from ) {\r\n\tkeys( from ).forEach( key => {\r\n\t\tif ( ! to[ key ] ) {\r\n\t\t\tObject.defineProperty( to, key, Object.getOwnPropertyDescriptor( from, key ) );\r\n\t\t}\r\n\t} );\r\n\r\n\treturn to;\r\n}","/**\r\n * A package of some miscellaneous utility functions.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { create, append, remove, applyStyle } from \"./dom\";\r\n\r\n/**\r\n * Convert the given value to array.\r\n *\r\n * @param {*} value - Any value.\r\n *\r\n * @return {*[]} - Array containing the given value.\r\n */\r\nexport function toArray( value ) {\r\n\treturn Array.isArray( value ) ? value : [ value ];\r\n}\r\n\r\n/**\r\n * Check if the given value is between min and max.\r\n * Min will be returned when the value is less than min or max will do when greater than max.\r\n *\r\n * @param {number} value - A number to be checked.\r\n * @param {number} m1 - Minimum or maximum number.\r\n * @param {number} m2 - Maximum or minimum number.\r\n *\r\n * @return {number} - A value itself, min or max.\r\n */\r\nexport function between( value, m1, m2 ) {\r\n\treturn Math.min( Math.max( value, m1 > m2 ? m2 : m1 ), m1 > m2 ? m1 : m2 );\r\n}\r\n\r\n/**\r\n * The sprintf method with minimum functionality.\r\n *\r\n * @param {string} format - The string format.\r\n * @param {string|Array} replacements - Replacements accepting multiple arguments.\r\n *\r\n * @returns {string} - Converted string.\r\n */\r\nexport function sprintf( format, replacements ) {\r\n\tlet i = 0;\r\n\treturn format.replace( /%s/g, () => toArray( replacements )[ i++ ] );\r\n}\r\n\r\n/**\r\n * Append px unit to the given subject if necessary.\r\n *\r\n * @param {number|string} value - A value that may not include an unit.\r\n *\r\n * @return {string} - If the value is string, return itself.\r\n * If number, do value + \"px\". An empty string, otherwise.\r\n */\r\nexport function unit( value ) {\r\n\tconst type = typeof value;\r\n\r\n\tif ( type === 'number' && value > 0 ) {\r\n\t\treturn parseFloat( value ) + 'px';\r\n\t}\r\n\r\n\treturn type === 'string' ? value : '';\r\n}\r\n\r\n/**\r\n * Pad start with 0.\r\n *\r\n * @param {number} number - A number to be filled with 0.\r\n *\r\n * @return {string|number} - Padded number.\r\n */\r\nexport function pad( number ) {\r\n\treturn number < 10 ? '0' + number : number\r\n}\r\n\r\n/**\r\n * Convert the given value to pixel.\r\n *\r\n * @param {Element} root - Root element where a dummy div is appended.\r\n * @param {string|number} value - CSS value to be converted, such as 10rem.\r\n *\r\n * @return {number} - Pixel.\r\n */\r\nexport function toPixel( root, value ) {\r\n\tif ( typeof value === 'string' ) {\r\n\t\tconst div = create( 'div', {} );\r\n\r\n\t\tapplyStyle( div, {\r\n\t\t\tposition: 'absolute',\r\n\t\t\twidth: value,\r\n\t\t} );\r\n\r\n\t\tappend( root, div );\r\n\r\n\t\tvalue = div.clientWidth;\r\n\r\n\t\tremove( div );\r\n\t}\r\n\r\n\treturn +value || 0;\r\n}","/**\r\n * Some utility functions related with DOM.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { each, values } from './object';\r\nimport { toArray } from \"./utils\";\r\n\r\n\r\n/**\r\n * Find the first element matching the given selector.\r\n * Be aware that all selectors after a space are ignored.\r\n *\r\n * @param {Element|Node} elm - An ancestor element.\r\n * @param {string} selector - DOMString.\r\n *\r\n * @return {Element|null} - A found element or null.\r\n */\r\nexport function find( elm, selector ) {\r\n\treturn elm ? elm.querySelector( selector.split( ' ' )[0] ) : null;\r\n}\r\n\r\n/**\r\n * Find a first child having the given tag or class name.\r\n *\r\n * @param {Element} parent - A parent element.\r\n * @param {string} tagOrClassName - A tag or class name.\r\n *\r\n * @return {Element|undefined} - A found element on success or undefined on failure.\r\n */\r\nexport function child( parent, tagOrClassName ) {\r\n\treturn children( parent, tagOrClassName )[0];\r\n}\r\n\r\n/**\r\n * Return chile elements that matches the provided tag or class name.\r\n *\r\n * @param {Element} parent - A parent element.\r\n * @param {string} tagOrClassName - A tag or class name.\r\n *\r\n * @return {Element[]} - Found elements.\r\n */\r\nexport function children( parent, tagOrClassName ) {\r\n\tif ( parent ) {\r\n\t\treturn values( parent.children ).filter( child => {\r\n\t\t\treturn hasClass( child, tagOrClassName.split( ' ' )[0] ) || child.tagName === tagOrClassName;\r\n\t\t} );\r\n\t}\r\n\r\n\treturn [];\r\n}\r\n\r\n/**\r\n * Create an element with some optional attributes.\r\n *\r\n * @param {string} tag - A tag name.\r\n * @param {Object} attrs - An object any attribute pairs of name and value.\r\n *\r\n * @return {Element} - A created element.\r\n */\r\nexport function create( tag, attrs ) {\r\n\tconst elm = document.createElement( tag );\r\n\teach( attrs, ( value, key ) => setAttribute( elm, key, value ) );\r\n\r\n\treturn elm;\r\n}\r\n\r\n/**\r\n * Convert HTML string to DOM node.\r\n *\r\n * @param {string} html - HTML string.\r\n *\r\n * @return {Node} - A created node.\r\n */\r\nexport function domify( html ) {\r\n\tconst div = create( 'div', {} );\r\n\tdiv.innerHTML = html;\r\n\r\n\treturn div.firstChild;\r\n}\r\n\r\n/**\r\n * Remove a given element from a DOM tree.\r\n *\r\n * @param {Element|Element[]} elms - Element(s) to be removed.\r\n */\r\nexport function remove( elms ) {\r\n\ttoArray( elms ).forEach( elm => {\r\n\t\tif ( elm ) {\r\n\t\t\tconst parent = elm.parentElement;\r\n\t\t\tparent && parent.removeChild( elm );\r\n\t\t}\r\n\t} );\r\n}\r\n\r\n/**\r\n * Append a child to a given element.\r\n *\r\n * @param {Element} parent - A parent element.\r\n * @param {Element} child - An element to be appended.\r\n */\r\nexport function append( parent, child ) {\r\n\tif ( parent ) {\r\n\t\tparent.appendChild( child );\r\n\t}\r\n}\r\n\r\n/**\r\n * Insert an element before the reference element.\r\n *\r\n * @param {Element|Node} ref - A reference element.\r\n * @param {Element} elm - An element to be inserted.\r\n */\r\nexport function before( elm, ref ) {\r\n\tif ( elm && ref ) {\r\n\t\tconst parent = ref.parentElement;\r\n\t\tparent && parent.insertBefore( elm, ref );\r\n\t}\r\n}\r\n\r\n/**\r\n * Apply styles to the given element.\r\n *\r\n * @param {Element} elm - An element where styles are applied.\r\n * @param {Object} styles - Object containing styles.\r\n */\r\nexport function applyStyle( elm, styles ) {\r\n\tif ( elm ) {\r\n\t\teach( styles, ( value, prop ) => {\r\n\t\t\tif ( value !== null ) {\r\n\t\t\t\telm.style[ prop ] = value;\r\n\t\t\t}\r\n\t\t} );\r\n\t}\r\n}\r\n\r\n/**\r\n * Add or remove classes to/from the element.\r\n * This function is for internal usage.\r\n *\r\n * @param {Element} elm - An element where classes are added.\r\n * @param {string|string[]} classes - Class names being added.\r\n * @param {boolean} remove - Whether to remove or add classes.\r\n */\r\nfunction addOrRemoveClasses( elm, classes, remove ) {\r\n\tif ( elm ) {\r\n\t\ttoArray( classes ).forEach( name => {\r\n\t\t\tif ( name ) {\r\n\t\t\t\telm.classList[ remove ? 'remove' : 'add' ]( name );\r\n\t\t\t}\r\n\t\t} );\r\n\t}\r\n}\r\n\r\n/**\r\n * Add classes to the element.\r\n *\r\n * @param {Element} elm - An element where classes are added.\r\n * @param {string|string[]} classes - Class names being added.\r\n */\r\nexport function addClass( elm, classes ) {\r\n\taddOrRemoveClasses( elm, classes, false );\r\n}\r\n\r\n/**\r\n * Remove a class from the element.\r\n *\r\n * @param {Element} elm - An element where classes are removed.\r\n * @param {string|string[]} classes - A class name being removed.\r\n */\r\nexport function removeClass( elm, classes ) {\r\n\taddOrRemoveClasses( elm, classes, true );\r\n}\r\n\r\n/**\r\n * Verify if the provided element has the class or not.\r\n *\r\n * @param {Element} elm - An element.\r\n * @param {string} className - A class name.\r\n *\r\n * @return {boolean} - True if the element has the class or false if not.\r\n */\r\nexport function hasClass( elm, className ) {\r\n\treturn !! elm && elm.classList.contains( className );\r\n}\r\n\r\n/**\r\n * Set attribute to the given element.\r\n *\r\n * @param {Element} elm - An element where an attribute is assigned.\r\n * @param {string} name - Attribute name.\r\n * @param {string|number|boolean} value - Attribute value.\r\n */\r\nexport function setAttribute( elm, name, value ) {\r\n\tif ( elm ) {\r\n\t\telm.setAttribute( name, value );\r\n\t}\r\n}\r\n\r\n/**\r\n * Get attribute from the given element.\r\n *\r\n * @param {Element} elm - An element where an attribute is assigned.\r\n * @param {string} name - Attribute name.\r\n *\r\n * @return {string} - The value of the given attribute if available. An empty string if not.\r\n */\r\nexport function getAttribute( elm, name ) {\r\n\treturn elm ? elm.getAttribute( name ) : '';\r\n}\r\n\r\n/**\r\n * Remove attribute from the given element.\r\n *\r\n * @param {Element|Element[]} elms - An element where an attribute is removed.\r\n * @param {string|string[]} names - Attribute name.\r\n */\r\nexport function removeAttribute( elms, names ) {\r\n\ttoArray( names ).forEach( name => {\r\n\t\ttoArray( elms ).forEach( elm => elm && elm.removeAttribute( name ) );\r\n\t} );\r\n}\r\n\r\n/**\r\n * Return the Rect object of the provided object.\r\n *\r\n * @param {Element} elm - An element.\r\n *\r\n * @return {ClientRect|DOMRect} - A rect object.\r\n */\r\nexport function getRect( elm ) {\r\n\treturn elm.getBoundingClientRect();\r\n}\r\n\r\n/**\r\n * Trigger the given callback after all images contained by the element are loaded.\r\n *\r\n * @param {Element} elm - Element that may contain images.\r\n * @param {Function} callback - Callback function fired right after all images are loaded.\r\n */\r\nexport function loaded( elm, callback ) {\r\n\tconst images = elm.querySelectorAll( 'img' );\r\n\tconst length = images.length;\r\n\r\n\tif ( length ) {\r\n\t\tlet count = 0;\r\n\r\n\t\teach( images, img => {\r\n\t\t\timg.onload = img.onerror = () => {\r\n\t\t\t\tif ( ++count === length ) {\r\n\t\t\t\t\tcallback();\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t} );\r\n\t} else {\r\n\t\t// Trigger the callback immediately if there is no image.\r\n\t\tcallback();\r\n\t}\r\n}","/**\r\n * Export slider types.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Normal slider.\r\n *\r\n * @type {string}\r\n */\r\nexport const SLIDE = 'slide';\r\n\r\n/**\r\n * Loop after the last slide and before the first one.\r\n *\r\n * @type {string}\r\n */\r\nexport const LOOP = 'loop';\r\n\r\n/**\r\n * The track doesn't move.\r\n *\r\n * @type {string}\r\n */\r\nexport const FADE = 'fade';","/**\r\n * The component for general slide effect transition.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle } from '../../utils/dom';\r\nimport { SLIDE } from \"../../constants/types\";\r\n\r\n\r\n/**\r\n * The component for general slide effect transition.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Hold the list element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tlet list;\r\n\r\n\t/**\r\n\t * Hold the onEnd callback function.\r\n\t *\r\n\t * @type {function}\r\n\t */\r\n\tlet endCallback;\r\n\r\n\treturn {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tlist = Components.Elements.list;\r\n\r\n\t\t\tSplide.on( 'transitionend', e => {\r\n\t\t\t\tif ( e.target === list && endCallback ) {\r\n\t\t\t\t\tendCallback();\r\n\t\t\t\t}\r\n\t\t\t}, list );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Start transition.\r\n\t\t *\r\n\t\t * @param {number} destIndex - Destination slide index that might be clone's.\r\n\t\t * @param {number} newIndex - New index.\r\n\t\t * @param {number} prevIndex - Previous index.\r\n\t\t * @param {Object} coord - Destination coordinates.\r\n\t\t * @param {function} done - Callback function must be invoked when transition is completed.\r\n\t\t */\r\n\t\tstart( destIndex, newIndex, prevIndex, coord, done ) {\r\n\t\t\tconst options = Splide.options;\r\n\t\t\tconst edgeIndex = Components.Controller.edgeIndex;\r\n\t\t\tlet speed = options.speed;\r\n\t\t\tendCallback = done;\r\n\r\n\t\t\tif ( Splide.is( SLIDE ) ) {\r\n\t\t\t\tif ( ( prevIndex === 0 && newIndex >= edgeIndex ) || ( prevIndex >= edgeIndex && newIndex === 0 ) ) {\r\n\t\t\t\t\tspeed = options.rewindSpeed || speed;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tapplyStyle( list, {\r\n\t\t\t\ttransition: `transform ${ speed }ms ${ options.easing }`,\r\n\t\t\t\ttransform : `translate(${ coord.x }px,${ coord.y }px)`,\r\n\t\t\t} );\r\n\t\t},\r\n\t};\r\n}","/**\r\n * The component for fade transition.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle } from '../../utils/dom';\r\nimport { unit } from \"../../utils/utils\";\r\n\r\n\r\n/**\r\n * The component for fade transition.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\tconst Fade = {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t * Apply transition style to the first slide.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tapply( Splide.index );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Start transition.\r\n\t\t *\r\n\t\t * @param {number} destIndex - Destination slide index that might be clone's.\r\n\t\t * @param {number} newIndex - New index.\r\n\t\t * @param {number} prevIndex - Previous index.\r\n\t\t * @param {Object} coord - Destination coordinates.\r\n\t\t * @param {function} done - Callback function must be invoked when transition is completed.\r\n\t\t */\r\n\t\tstart( destIndex, newIndex, prevIndex, coord, done ) {\r\n\t\t\tconst track = Components.Elements.track;\r\n\r\n\t\t\tapplyStyle( track, { height: unit( track.clientHeight ) } );\r\n\r\n\t\t\tapply( newIndex );\r\n\r\n\t\t\tsetTimeout( () => {\r\n\t\t\t\tdone();\r\n\t\t\t\tapplyStyle( track, { height: '' } );\r\n\t\t\t} );\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Apply transition style to the slide specified by the given index.\r\n\t *\r\n\t * @param {number} index - A slide index.\r\n\t */\r\n\tfunction apply( index ) {\r\n\t\tconst options = Splide.options;\r\n\r\n\t\tapplyStyle( Components.Elements.slides[ index ], {\r\n\t\t\ttransition: `opacity ${ options.speed }ms ${ options.easing }`,\r\n\t\t} );\r\n\t}\r\n\r\n\treturn Fade;\r\n}","/**\r\n * Provide a function for composing components.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { each } from '../utils/object';\r\nimport { Slide, Fade } from '../transitions';\r\nimport { FADE } from '../constants/types';\r\n\r\n\r\n/**\r\n * Compose components.\r\n *\r\n * @param {Splide} Splide - Splide instance.\r\n * @param {Object} Components - Additional components.\r\n * @param {function} Transition - Change component for transition.\r\n *\r\n * @return {Object} - An object containing all components.\r\n */\r\nexport default function compose( Splide, Components, Transition ) {\r\n\tconst components = {};\r\n\r\n\teach( Components, ( Component, name ) => {\r\n\t\tcomponents[ name ] = Component( Splide, components, name.toLowerCase() );\r\n\t} );\r\n\r\n\tif ( ! Transition ) {\r\n\t\tTransition = Splide.is( FADE ) ? Fade : Slide;\r\n\t}\r\n\r\n\tcomponents.Transition = Transition( Splide, components );\r\n\r\n\treturn components;\r\n}","/**\r\n * Utility functions for outputting logs.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Prefix of an error massage.\r\n *\r\n * @type {string}\r\n */\r\nconst MESSAGE_PREFIX = '[SPLIDE]';\r\n\r\n\r\n/**\r\n * Display an error message on the browser console.\r\n *\r\n * @param {string} message - An error message.\r\n */\r\nexport function error( message ) {\r\n\tconsole.error( `${ MESSAGE_PREFIX } ${ message }` );\r\n}\r\n\r\n/**\r\n * Check existence of the given object and throw an error if it doesn't.\r\n *\r\n * @throws {Error}\r\n *\r\n * @param {*} subject - A subject to be confirmed.\r\n * @param {string} message - An error message.\r\n */\r\nexport function exist( subject, message ) {\r\n\tif ( ! subject ) {\r\n\t\tthrow new Error( message );\r\n\t}\r\n}","/**\r\n * Export class names.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * A root class name.\r\n *\r\n * @type {string}\r\n */\r\nconst ROOT = 'splide';\r\n\r\n/**\r\n * The definition table of all classes for elements.\r\n * They might be modified by options.\r\n *\r\n * @type {Object}\r\n */\r\nexport const ELEMENT_CLASSES = {\r\n\troot : ROOT,\r\n\tslider : `${ ROOT }__slider`,\r\n\ttrack : `${ ROOT }__track`,\r\n\tlist : `${ ROOT }__list`,\r\n\tslide : `${ ROOT }__slide`,\r\n\tcontainer : `${ ROOT }__slide__container`,\r\n\tarrows : `${ ROOT }__arrows`,\r\n\tarrow : `${ ROOT }__arrow`,\r\n\tprev : `${ ROOT }__arrow--prev`,\r\n\tnext : `${ ROOT }__arrow--next`,\r\n\tpagination: `${ ROOT }__pagination`,\r\n\tpage : `${ ROOT }__pagination__page`,\r\n\tclone : `${ ROOT }__slide--clone`,\r\n\tprogress : `${ ROOT }__progress`,\r\n\tbar : `${ ROOT }__progress__bar`,\r\n\tautoplay : `${ ROOT }__autoplay`,\r\n\tplay : `${ ROOT }__play`,\r\n\tpause : `${ ROOT }__pause`,\r\n\tspinner : `${ ROOT }__spinner`,\r\n\tsr : `${ ROOT }__sr`,\r\n};\r\n\r\n/**\r\n * Definitions of status classes.\r\n *\r\n * @type {Object}\r\n */\r\nexport const STATUS_CLASSES = {\r\n\tactive : 'is-active',\r\n\tvisible: 'is-visible',\r\n\tloading: 'is-loading',\r\n};","/**\r\n * Export i18n texts as object.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Texts for i18n.\r\n *\r\n * @type {Object}\r\n */\r\nexport const I18N = {\r\n\tprev : 'Previous slide',\r\n\tnext : 'Next slide',\r\n\tfirst : 'Go to first slide',\r\n\tlast : 'Go to last slide',\r\n\tslideX: 'Go to slide %s',\r\n\tpageX : 'Go to page %s',\r\n\tplay : 'Start autoplay',\r\n\tpause : 'Pause autoplay',\r\n};","/**\r\n * Export default options.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { ELEMENT_CLASSES as classes } from \"./classes\";\r\nimport { I18N as i18n } from './i18n';\r\n\r\n\r\nexport const DEFAULTS = {\r\n\t/**\r\n\t * Determine a slider type.\r\n\t * - 'slide': Regular slider.\r\n\t * - 'loop' : Carousel slider.\r\n\t * - 'fade' : Change slides with fade transition. perPage, drag options are ignored.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\ttype: 'slide',\r\n\r\n\t/**\r\n\t * Whether to rewind a slider before the first slide or after the last one.\r\n\t * In \"loop\" mode, this option is ignored.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\trewind: false,\r\n\r\n\t/**\r\n\t * Transition speed in milliseconds.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tspeed: 400,\r\n\r\n\t/**\r\n\t * Transition speed on rewind in milliseconds.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\trewindSpeed: 0,\r\n\r\n\t/**\r\n\t * Whether to prevent any actions while a slider is transitioning.\r\n\t * If false, navigation, drag and swipe work while the slider is running.\r\n\t * Even so, it will be forced to wait for transition in some cases in the loop mode to shift a slider.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\twaitForTransition: true,\r\n\r\n\t/**\r\n\t * Define slider max width.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\twidth: 0,\r\n\r\n\t/**\r\n\t * Define slider height.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\theight: 0,\r\n\r\n\t/**\r\n\t * Fix width of slides. CSS format is allowed such as 10em, 80% or 80vw.\r\n\t * perPage number will be ignored when this option is falsy.\r\n\t *\r\n\t * @type {number|string}\r\n\t */\r\n\tfixedWidth: 0,\r\n\r\n\t/**\r\n\t * Fix height of slides. CSS format is allowed such as 10em, 80vh but % unit is not accepted.\r\n\t * heightRatio option will be ignored when this option is falsy.\r\n\t *\r\n\t * @type {number|string}\r\n\t */\r\n\tfixedHeight: 0,\r\n\r\n\t/**\r\n\t * Determine height of slides by ratio to a slider width.\r\n\t * This will be ignored when the fixedHeight is provided.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\theightRatio: 0,\r\n\r\n\t/**\r\n\t * If true, slide width will be determined by the element width itself.\r\n\t * - perPage/perMove should be 1.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tautoWidth: false,\r\n\r\n\t/**\r\n\t * If true, slide height will be determined by the element width itself.\r\n\t * - perPage/perMove should be 1.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tautoHeight: false,\r\n\r\n\t/**\r\n\t * Determine how many slides should be displayed per page.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tperPage: 1,\r\n\r\n\t/**\r\n\t * Determine how many slides should be moved when a slider goes to next or perv.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tperMove: 0,\r\n\r\n\t/**\r\n\t * Determine manually how many clones should be generated on the left and right side.\r\n\t * The total number of clones will be twice of this number.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tclones: 0,\r\n\r\n\t/**\r\n\t * Start index.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tstart: 0,\r\n\r\n\t/**\r\n\t * Determine which slide should be focused if there are multiple slides in a page.\r\n\t * A string \"center\" is acceptable for centering slides.\r\n\t *\r\n\t * @type {boolean|number|string}\r\n\t */\r\n\tfocus: false,\r\n\r\n\t/**\r\n\t * Gap between slides. CSS format is allowed such as 1em.\r\n\t *\r\n\t * @type {number|string}\r\n\t */\r\n\tgap: 0,\r\n\r\n\t/**\r\n\t * Set padding-left/right in horizontal mode or padding-top/bottom in vertical one.\r\n\t * Give a single value to set a same size for both sides or\r\n\t * do an object for different sizes.\r\n\t * Also, CSS format is allowed such as 1em.\r\n\t *\r\n\t * @example\r\n\t * - 10: Number\r\n\t * - '1em': CSS format.\r\n\t * - { left: 0, right: 20 }: Object for different sizes in horizontal mode.\r\n\t * - { top: 0, bottom: 20 }: Object for different sizes in vertical mode.\r\n\t *\r\n\t * @type {number|string|Object}\r\n\t */\r\n\tpadding: 0,\r\n\r\n\t/**\r\n\t * Whether to append arrows.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tarrows: true,\r\n\r\n\t/**\r\n\t * Change the arrow SVG path like 'm7.61 0.807-2.12...'.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tarrowPath: '',\r\n\r\n\t/**\r\n\t * Whether to append pagination(indicator dots) or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tpagination: true,\r\n\r\n\t/**\r\n\t * Activate autoplay.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tautoplay: false,\r\n\r\n\t/**\r\n\t * Autoplay interval in milliseconds.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tinterval: 5000,\r\n\r\n\t/**\r\n\t * Whether to stop autoplay when a slider is hovered.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tpauseOnHover: true,\r\n\r\n\t/**\r\n\t * Whether to stop autoplay when a slider elements are focused.\r\n\t * True is recommended for accessibility.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tpauseOnFocus: true,\r\n\r\n\t/**\r\n\t * Whether to reset progress of the autoplay timer when resumed.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tresetProgress: true,\r\n\r\n\t/**\r\n\t * Loading images lazily.\r\n\t * Image src must be provided by a data-splide-lazy attribute.\r\n\t *\r\n\t * - false: Do nothing.\r\n\t * - 'nearby': Only images around an active slide will be loaded.\r\n\t * - 'sequential': All images will be sequentially loaded.\r\n\t *\r\n\t * @type {boolean|string}\r\n\t */\r\n\tlazyLoad: false,\r\n\r\n\t/**\r\n\t * This option works only when a lazyLoad option is \"nearby\".\r\n\t * Determine how many pages(not slides) around an active slide should be loaded beforehand.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tpreloadPages: 1,\r\n\r\n\t/**\r\n\t * Easing for CSS transition. For example, linear, ease or cubic-bezier().\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\teasing: 'cubic-bezier(.42,.65,.27,.99)',\r\n\r\n\t/**\r\n\t * Whether to enable keyboard shortcuts\r\n\t * - true or 'global': Listen to keydown event of the document.\r\n\t * - 'focused': Listen to the keydown event of the slider root element. tabindex=\"0\" will be added to the element.\r\n\t * - false: Disable keyboard shortcuts.\r\n\t *\r\n\t * @type {boolean|string}\r\n\t */\r\n\tkeyboard: 'global',\r\n\r\n\t/**\r\n\t * Whether to allow mouse drag and touch swipe.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tdrag: true,\r\n\r\n\t/**\r\n\t * The angle threshold for drag.\r\n\t * The slider starts moving only when the drag angle is less than this threshold.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tdragAngleThreshold: 30,\r\n\r\n\t/**\r\n\t * Distance threshold for determining if the action is \"flick\" or \"swipe\".\r\n\t * When a drag distance is over this value, the action will be treated as \"swipe\", not \"flick\".\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tswipeDistanceThreshold: 150,\r\n\r\n\t/**\r\n\t * Velocity threshold for determining if the action is \"flick\" or \"swipe\".\r\n\t * Around 0.5 is recommended.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tflickVelocityThreshold: .6,\r\n\r\n\t/**\r\n\t * Determine power of flick. The larger number this is, the farther a slider runs by flick.\r\n\t * Around 500 is recommended.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tflickPower: 600,\r\n\r\n\t/**\r\n\t * Limit a number of pages to move by flick.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tflickMaxPages: 1,\r\n\r\n\t/**\r\n\t * Slider direction.\r\n\t * - 'ltr': Left to right.\r\n\t * - 'rtl': Right to left.\r\n\t * - 'ttb': Top to bottom.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tdirection: 'ltr',\r\n\r\n\t/**\r\n\t * Set img src to background-image of its parent element.\r\n\t * Images with various sizes can be displayed as same dimension without cropping work.\r\n\t * fixedHeight or heightRatio is required.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tcover: false,\r\n\r\n\t/**\r\n\t * Whether to enable accessibility(aria and screen reader texts) or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\taccessibility: true,\r\n\r\n\t/**\r\n\t * Whether to add tabindex=\"0\" to visible slides or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tslideFocus: true,\r\n\r\n\t/**\r\n\t * Determine if a slider is navigation for another.\r\n\t * Use \"sync\" API to synchronize two sliders.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tisNavigation: false,\r\n\r\n\t/**\r\n\t * Whether to trim spaces before the fist slide or after the last one when \"focus\" is not 0.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\ttrimSpace: true,\r\n\r\n\t/**\r\n\t * The \"is-active\" class is added after transition as default.\r\n\t * If true, it will be added before move.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tupdateOnMove: false,\r\n\r\n\t/**\r\n\t * Throttle duration in milliseconds for the resize event.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tthrottle: 100,\r\n\r\n\t/**\r\n\t * Whether to destroy a slider or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tdestroy: false,\r\n\r\n\t/**\r\n\t * Options for specific breakpoints.\r\n\t *\r\n\t * @example\r\n\t * {\r\n\t * 1000: {\r\n\t * perPage: 3,\r\n\t * gap: 20\r\n\t * },\r\n\t * 600: {\r\n\t * perPage: 1,\r\n\t * gap: 5,\r\n\t * }\r\n\t * }\r\n\t *\r\n\t * @type {boolean|Object}\r\n\t */\r\n\tbreakpoints: false,\r\n\r\n\t/**\r\n\t * Collection of class names.\r\n\t *\r\n\t * @see ./classes.js\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tclasses,\r\n\r\n\t/**\r\n\t * Collection of i18n texts.\r\n\t *\r\n\t * @see ./i18n.js\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\ti18n,\r\n};","/**\r\n * Export state constants.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Splide has been just created.\r\n *\r\n * @type {number}\r\n */\r\nexport const CREATED = 1;\r\n\r\n/**\r\n * All components have been mounted and initialized.\r\n *\r\n * @type {number}\r\n */\r\nexport const MOUNTED = 2;\r\n\r\n/**\r\n * Splide is ready for transition.\r\n *\r\n * @type {number}\r\n */\r\nexport const IDLE = 3;\r\n\r\n/**\r\n * Splide is moving.\r\n *\r\n * @type {number}\r\n */\r\nexport const MOVING = 4;\r\n\r\n/**\r\n * Splide is moving.\r\n *\r\n * @type {number}\r\n */\r\nexport const DESTROYED = 5;","/**\r\n * The main class for applying Splide to an element.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport Event from './core/event';\r\nimport State from './core/state';\r\nimport compose from './core/composer';\r\nimport { error, exist } from './utils/error';\r\nimport { applyStyle } from './utils/dom';\r\nimport { merge, each, values } from './utils/object';\r\nimport { DEFAULTS } from './constants/defaults';\r\nimport * as STATES from './constants/states';\r\n\r\n\r\n/**\r\n * The main class for applying Splide to an element,\r\n * providing some APIs to control the behavior.\r\n */\r\nexport default class Splide {\r\n\t/**\r\n\t * Splide constructor.\r\n\t *\r\n\t * @throws {Error} When the given root element or selector is invalid.\r\n\t *\r\n\t * @param {Element|string} root - A selector for a root element or an element itself.\r\n\t * @param {Object} options - Optional. Options to change default behaviour.\r\n\t * @param {Object} Components - Optional. Components.\r\n\t */\r\n\tconstructor( root, options = {}, Components = {} ) {\r\n\t\tthis.root = root instanceof Element ? root : document.querySelector( root );\r\n\t\texist( this.root, 'An invalid element/selector was given.' );\r\n\r\n\t\tthis.Components = null;\r\n\t\tthis.Event = Event();\r\n\t\tthis.State = State( STATES.CREATED );\r\n\t\tthis.STATES = STATES;\r\n\r\n\t\tthis._o = merge( DEFAULTS, options );\r\n\t\tthis._i = 0;\r\n\t\tthis._c = Components;\r\n\t\tthis._e = {}; // Extensions\r\n\t\tthis._t = null; // Transition\r\n\t}\r\n\r\n\t/**\r\n\t * Compose and mount components.\r\n\t *\r\n\t * @param {Object} Extensions - Optional. Additional components.\r\n\t * @param {function} Transition - Optional. Set a custom transition component.\r\n\t *\r\n\t * @return {Splide|undefined} - This instance or undefined if an exception occurred.\r\n\t */\r\n\tmount( Extensions = this._e, Transition = this._t ) {\r\n\t\t// Reset the state.\r\n\t\tthis.State.set( STATES.CREATED );\r\n\r\n\t\tthis._e = Extensions;\r\n\t\tthis._t = Transition;\r\n\r\n\t\tthis.Components = compose( this, merge( this._c, Extensions ), Transition );\r\n\r\n\t\ttry {\r\n\t\t\teach( this.Components, ( component, key ) => {\r\n\t\t\t\tconst required = component.required;\r\n\r\n\t\t\t\tif ( required === undefined || required ) {\r\n\t\t\t\t\tcomponent.mount && component.mount();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tdelete this.Components[ key ];\r\n\t\t\t\t}\r\n\t\t\t} );\r\n\t\t} catch ( e ) {\r\n\t\t\terror( e.message );\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst { State } = this;\r\n\t\tState.set( STATES.MOUNTED );\r\n\r\n\t\teach( this.Components, component => {\r\n\t\t\tcomponent.mounted && component.mounted();\r\n\t\t} );\r\n\r\n\t\tthis.emit( 'mounted' );\r\n\t\tState.set( STATES.IDLE );\r\n\t\tthis.emit( 'ready' );\r\n\r\n\t\tapplyStyle( this.root, { visibility: 'visible' } );\r\n\r\n\t\tthis\r\n\t\t\t.on( 'move drag', () => State.set( STATES.MOVING ) )\r\n\t\t\t.on( 'moved dragged', () => State.set( STATES.IDLE ) );\r\n\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Set sync target.\r\n\t *\r\n\t * @param {Splide} splide - A Splide instance.\r\n\t *\r\n\t * @return {Splide} - This instance.\r\n\t */\r\n\tsync( splide ) {\r\n\t\tthis.sibling = splide;\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Register callback fired on the given event(s).\r\n\t *\r\n\t * @param {string} events - An event name. Use space to separate multiple events.\r\n\t * Also, namespace is accepted by dot, such as 'resize.{namespace}'.\r\n\t * @param {function} handler - A callback function.\r\n\t * @param {Element} elm - Optional. Native event will be listened to when this arg is provided.\r\n\t * @param {Object} options - Optional. Options for addEventListener.\r\n\t *\r\n\t * @return {Splide} - This instance.\r\n\t */\r\n\ton( events, handler, elm = null, options = {} ) {\r\n\t\tthis.Event.on( events, handler, elm, options );\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Unsubscribe the given event.\r\n\t *\r\n\t * @param {string} events - A event name.\r\n\t * @param {Element} elm - Optional. removeEventListener() will be called when this arg is provided.\r\n\t *\r\n\t * @return {Splide} - This instance.\r\n\t */\r\n\toff( events, elm = null ) {\r\n\t\tthis.Event.off( events, elm );\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Emit an event.\r\n\t *\r\n\t * @param {string} event - An event name.\r\n\t * @param {*} args - Any number of arguments passed to handlers.\r\n\t */\r\n\temit( event, ...args ) {\r\n\t\tthis.Event.emit( event, ...args );\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Go to the slide specified by the given control.\r\n\t *\r\n\t * @param {string|number} control - A control pattern.\r\n\t * @param {boolean} wait - Optional. Whether to wait for transition.\r\n\t */\r\n\tgo( control, wait = this.options.waitForTransition ) {\r\n\t\tif ( this.State.is( STATES.IDLE ) || ( this.State.is( STATES.MOVING ) && ! wait ) ) {\r\n\t\t\tthis.Components.Controller.go( control, false );\r\n\t\t}\r\n\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Verify whether the slider type is the given one or not.\r\n\t *\r\n\t * @param {string} type - A slider type.\r\n\t *\r\n\t * @return {boolean} - True if the slider type is the provided type or false if not.\r\n\t */\r\n\tis( type ) {\r\n\t\treturn type === this._o.type;\r\n\t}\r\n\r\n\t/**\r\n\t * Insert a slide.\r\n\t *\r\n\t * @param {Element|string} slide - A slide element to be added.\r\n\t * @param {number} index - A slide will be added at the position.\r\n\t */\r\n\tadd( slide, index = -1 ) {\r\n\t\tthis.Components.Elements.add( slide, index, this.refresh.bind( this ) );\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Remove the slide designated by the index.\r\n\t *\r\n\t * @param {number} index - A slide index.\r\n\t */\r\n\tremove( index ) {\r\n\t\tthis.Components.Elements.remove( index );\r\n\t\tthis.refresh();\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroy all Slide objects and clones and recreate them again.\r\n\t */\r\n\trefresh() {\r\n\t\tthis.emit( 'refresh:before' ).emit( 'refresh' ).emit( 'resize' );\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroy the Splide.\r\n\t * \"Completely\" boolean is mainly for breakpoints.\r\n\t *\r\n\t * @param {boolean} completely - Destroy completely.\r\n\t */\r\n\tdestroy( completely = true ) {\r\n\t\t// Postpone destroy because it should be done after mount.\r\n\t\tif ( this.State.is( STATES.CREATED ) ) {\r\n\t\t\tthis.on( 'ready', () => this.destroy( completely ) );\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvalues( this.Components ).reverse().forEach( component => {\r\n\t\t\tcomponent.destroy && component.destroy( completely );\r\n\t\t} );\r\n\r\n\t\tthis.emit( 'destroy', completely );\r\n\r\n\t\t// Destroy all event handlers, including ones for native events.\r\n\t\tthis.Event.destroy();\r\n\t\tthis.State.set( STATES.DESTROYED );\r\n\r\n\t\treturn this;\r\n\t}\r\n\r\n\t/**\r\n\t * Return the current slide index.\r\n\t *\r\n\t * @return {number} - The current slide index.\r\n\t // */\r\n\tget index() {\r\n\t\treturn this._i;\r\n\t}\r\n\r\n\t/**\r\n\t * Set the current slide index.\r\n\t *\r\n\t * @param {number|string} index - A new index.\r\n\t */\r\n\tset index( index ) {\r\n\t\tthis._i = parseInt( index );\r\n\t}\r\n\r\n\t/**\r\n\t * Return length of slides.\r\n\t * This is an alias of Elements.length.\r\n\t *\r\n\t * @return {number} - A number of slides.\r\n\t */\r\n\tget length() {\r\n\t\treturn this.Components.Elements.length;\r\n\t}\r\n\r\n\t/**\r\n\t * Return options.\r\n\t *\r\n\t * @return {Object} - Options object.\r\n\t */\r\n\tget options() {\r\n\t\treturn this._o;\r\n\t}\r\n\r\n\t/**\r\n\t * Set options with merging the given object to the current one.\r\n\t *\r\n\t * @param {Object} options - New options.\r\n\t */\r\n\tset options( options ) {\r\n\t\tconst created = this.State.is( STATES.CREATED );\r\n\r\n\t\tif ( ! created ) {\r\n\t\t\tthis.emit( 'update' );\r\n\t\t}\r\n\r\n\t\tthis._o = merge( this._o, options );\r\n\r\n\t\tif ( ! created ) {\r\n\t\t\tthis.emit( 'updated', this._o );\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Return the class list.\r\n\t * This is an alias of Splide.options.classList.\r\n\t *\r\n\t * @return {Object} - An object containing all class list.\r\n\t */\r\n\tget classes() {\r\n\t\treturn this._o.classes;\r\n\t}\r\n\r\n\t/**\r\n\t * Return the i18n strings.\r\n\t * This is an alias of Splide.options.i18n.\r\n\t *\r\n\t * @return {Object} - An object containing all i18n strings.\r\n\t */\r\n\tget i18n() {\r\n\t\treturn this._o.i18n;\r\n\t}\r\n}","/**\r\n * The component for initializing options.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { error } from '../../utils/error';\r\nimport { getAttribute } from \"../../utils/dom\";\r\nimport { CREATED } from \"../../constants/states\";\r\n\r\n\r\n/**\r\n * The component for initializing options.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide ) => {\r\n\t/**\r\n\t * Retrieve options from the data attribute.\r\n\t * Note that IE10 doesn't support dataset property.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst options = getAttribute( Splide.root, 'data-splide' );\r\n\r\n\tif ( options ) {\r\n\t\ttry {\r\n\t\t\tSplide.options = JSON.parse( options );\r\n\t\t} catch ( e ) {\r\n\t\t\terror( e.message );\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tif ( Splide.State.is( CREATED ) ) {\r\n\t\t\t\tSplide.index = Splide.options.start;\r\n\t\t\t}\r\n\t\t},\r\n\t};\r\n}","/**\r\n * Export layout modes.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Enumerate slides from left to right.\r\n *\r\n * @type {string}\r\n */\r\nexport const LTR = 'ltr';\r\n\r\n/**\r\n * Enumerate slides from right to left.\r\n *\r\n * @type {string}\r\n */\r\nexport const RTL = 'rtl';\r\n\r\n/**\r\n * Enumerate slides in a col.\r\n *\r\n * @type {string}\r\n */\r\nexport const TTB = 'ttb';","/**\r\n * The sub component for handling each slide.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport {\r\n\tchild,\r\n\taddClass,\r\n\tremoveClass,\r\n\thasClass,\r\n\tgetAttribute,\r\n\tsetAttribute,\r\n\tremoveAttribute,\r\n\tapplyStyle,\r\n\tgetRect,\r\n} from '../../utils/dom';\r\nimport { FADE, SLIDE } from '../../constants/types';\r\nimport { STATUS_CLASSES } from '../../constants/classes';\r\nimport { values } from \"../../utils/object\";\r\nimport { pad } from \"../../utils/utils\";\r\nimport { TTB } from \"../../constants/directions\";\r\n\r\n/**\r\n * Events for restoring original styles.\r\n *\r\n * @type {string}\r\n */\r\nconst STYLE_RESTORE_EVENTS = 'update.slide';\r\n\r\n\r\n/**\r\n * The sub component for handling each slide.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {number} index - An unique slide index.\r\n * @param {number} realIndex - Clones should pass a real slide index.\r\n * @param {Element} slide - A slide element.\r\n *\r\n * @return {Object} - The sub component object.\r\n */\r\nexport default ( Splide, index, realIndex, slide ) => {\r\n\t/**\r\n\t * Whether to update \"is-active\" class before or after transition.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tconst updateOnMove = Splide.options.updateOnMove;\r\n\r\n\t/**\r\n\t * Events when the slide status is updated.\r\n\t * Append a namespace to remove listeners later.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst STATUS_UPDATE_EVENTS = 'ready.slide updated.slide resized.slide moved.slide'\r\n\t\t+ ( updateOnMove ? ' move.slide' : '' );\r\n\r\n\t/**\r\n\t * Slide sub component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Slide = {\r\n\t\t/**\r\n\t\t * Slide element.\r\n\t\t *\r\n\t\t * @type {Element}\r\n\t\t */\r\n\t\tslide,\r\n\r\n\t\t/**\r\n\t\t * Slide index.\r\n\t\t *\r\n\t\t * @type {number}\r\n\t\t */\r\n\t\tindex,\r\n\r\n\t\t/**\r\n\t\t * Real index for clones.\r\n\t\t *\r\n\t\t * @type {number}\r\n\t\t */\r\n\t\trealIndex,\r\n\r\n\t\t/**\r\n\t\t * Container element if available.\r\n\t\t *\r\n\t\t * @type {Element|undefined}\r\n\t\t */\r\n\t\tcontainer: child( slide, Splide.classes.container ),\r\n\r\n\t\t/**\r\n\t\t * Whether this is a cloned slide or not.\r\n\t\t *\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\tisClone: realIndex > -1,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tif ( ! this.isClone ) {\r\n\t\t\t\tslide.id = `${ Splide.root.id }-slide${ pad( index + 1 ) }`;\r\n\t\t\t}\r\n\r\n\t\t\tSplide\r\n\t\t\t\t.on( STATUS_UPDATE_EVENTS, () => this.update() )\r\n\t\t\t\t.on( STYLE_RESTORE_EVENTS, restoreStyles )\r\n\t\t\t\t.on( 'click', () => Splide.emit( 'click', this ), slide );\r\n\r\n\t\t\t/*\r\n\t\t\t * Add \"is-active\" class to a clone element temporarily\r\n\t\t\t * and it will be removed on \"moved\" event.\r\n\t\t\t */\r\n\t\t\tif ( updateOnMove ) {\r\n\t\t\t\tSplide.on( 'move.slide', newIndex => {\r\n\t\t\t\t\tif ( newIndex === realIndex ) {\r\n\t\t\t\t\t\tupdate( true, false );\r\n\t\t\t\t\t}\r\n\t\t\t\t} );\r\n\t\t\t}\r\n\r\n\t\t\t// Make sure the slide is shown.\r\n\t\t\tapplyStyle( slide, { display: '' } );\r\n\r\n\t\t\t// Hold the original styles.\r\n\t\t\tthis.styles = getAttribute( slide, 'style' ) || '';\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Destroy.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tSplide.off( STATUS_UPDATE_EVENTS ).off( STYLE_RESTORE_EVENTS ).off( 'click', slide );\r\n\t\t\tremoveClass( slide, values( STATUS_CLASSES ) );\r\n\t\t\trestoreStyles();\r\n\t\t\tremoveAttribute( this.container, 'style' );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Update active and visible status.\r\n\t\t */\r\n\t\tupdate() {\r\n\t\t\tupdate( this.isActive(), false );\r\n\t\t\tupdate( this.isVisible(), true );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Check whether this slide is active or not.\r\n\t\t *\r\n\t\t * @return {boolean} - True if the slide is active or false if not.\r\n\t\t */\r\n\t\tisActive() {\r\n\t\t\treturn Splide.index === index;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Check whether this slide is visible in the viewport or not.\r\n\t\t *\r\n\t\t * @return {boolean} - True if the slide is visible or false if not.\r\n\t\t */\r\n\t\tisVisible() {\r\n\t\t\tconst active = this.isActive();\r\n\r\n\t\t\tif ( Splide.is( FADE ) || active ) {\r\n\t\t\t\treturn active;\r\n\t\t\t}\r\n\r\n\t\t\tconst { ceil } = Math;\r\n\t\t\tconst trackRect = getRect( Splide.Components.Elements.track );\r\n\t\t\tconst slideRect = getRect( slide );\r\n\r\n\t\t\tif ( Splide.options.direction === TTB ) {\r\n\t\t\t\treturn trackRect.top <= slideRect.top && slideRect.bottom <= ceil( trackRect.bottom );\r\n\t\t\t}\r\n\r\n\t\t\treturn trackRect.left <= slideRect.left && slideRect.right <= ceil( trackRect.right );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Calculate how far this slide is from another slide and\r\n\t\t * return true if the distance is within the given number.\r\n\t\t *\r\n\t\t * @param {number} from - Index of a target slide.\r\n\t\t * @param {number} within - True if the slide is within this number.\r\n\t\t *\r\n\t\t * @return {boolean} - True if the slide is within the number or false otherwise.\r\n\t\t */\r\n\t\tisWithin( from, within ) {\r\n\t\t\tlet diff = Math.abs( from - index );\r\n\r\n\t\t\tif ( ! Splide.is( SLIDE ) && ! this.isClone ) {\r\n\t\t\t\tdiff = Math.min( diff, Splide.length - diff );\r\n\t\t\t}\r\n\r\n\t\t\treturn diff < within;\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Update classes for activity or visibility.\r\n\t *\r\n\t * @param {boolean} active - Is active/visible or not.\r\n\t * @param {boolean} forVisibility - Toggle classes for activity or visibility.\r\n\t */\r\n\tfunction update( active, forVisibility ) {\r\n\t\tconst type = forVisibility ? 'visible' : 'active';\r\n\t\tconst className = STATUS_CLASSES[ type ];\r\n\r\n\t\tif ( active ) {\r\n\t\t\taddClass( slide, className );\r\n\t\t\tSplide.emit( `${ type }`, Slide );\r\n\t\t} else {\r\n\t\t\tif ( hasClass( slide, className ) ) {\r\n\t\t\t\tremoveClass( slide, className );\r\n\t\t\t\tSplide.emit( `${ forVisibility ? 'hidden' : 'inactive' }`, Slide );\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Restore the original styles.\r\n\t */\r\n\tfunction restoreStyles() {\r\n\t\tsetAttribute( slide, 'style', Slide.styles );\r\n\t}\r\n\r\n\treturn Slide;\r\n}","/**\r\n * The component for main elements.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport Slide from './slide';\r\nimport {\r\n\tfind,\r\n\taddClass,\r\n\tremoveClass,\r\n\tchild,\r\n\tchildren,\r\n\tremove,\r\n\tappend,\r\n\tbefore,\r\n\tdomify,\r\n\tapplyStyle,\r\n\tloaded,\r\n} from '../../utils/dom';\r\nimport { exist } from '../../utils/error';\r\nimport { pad } from \"../../utils/utils\";\r\nimport { STATUS_CLASSES } from \"../../constants/classes\";\r\n\r\n\r\n/**\r\n * The property name for UID stored in a window object.\r\n *\r\n * @type {string}\r\n */\r\nconst UID_NAME = 'uid';\r\n\r\n\r\n/**\r\n * The component for main elements.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Hold the root element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tconst root = Splide.root;\r\n\r\n\t/**\r\n\t * Hold the class list.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst classes = Splide.classes;\r\n\r\n\t/**\r\n\t * Store Slide objects.\r\n\t *\r\n\t * @type {Array}\r\n\t */\r\n\tlet Slides = [];\r\n\r\n\t/*\r\n\t * Assign unique ID to the root element if it doesn't have the one.\r\n\t * Note that IE doesn't support padStart() to fill the uid by 0.\r\n\t */\r\n\tif ( ! root.id ) {\r\n\t\twindow.splide = window.splide || {};\r\n\t\tlet uid = window.splide[ UID_NAME ] || 0;\r\n\t\twindow.splide[ UID_NAME ] = ++uid;\r\n\t\troot.id = `splide${ pad( uid ) }`;\r\n\t}\r\n\r\n\t/**\r\n\t * Elements component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Elements = {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t * Collect main elements and store them as member properties.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tthis.init();\r\n\r\n\t\t\tSplide\r\n\t\t\t\t.on( 'refresh', () => {\r\n\t\t\t\t\tthis.destroy();\r\n\t\t\t\t\tthis.init();\r\n\t\t\t\t} ).on( 'updated', () => {\r\n\t\t\t\t\tremoveClass( root, getClasses() );\r\n\t\t\t\t\taddClass( root, getClasses() );\r\n\t\t\t\t} );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Destroy.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tSlides.forEach( Slide => { Slide.destroy() } );\r\n\t\t\tSlides = [];\r\n\t\t\tremoveClass( root, getClasses() );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Initialization.\r\n\t\t */\r\n\t\tinit() {\r\n\t\t\tcollect();\r\n\t\t\taddClass( root, getClasses() );\r\n\r\n\t\t\tthis.slides.forEach( ( slide, index ) => {\r\n\t\t\t\tthis.register( slide, index, -1 );\r\n\t\t\t} );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Register a slide to create a Slide object and handle its behavior.\r\n\t\t *\r\n\t\t * @param {Element} slide - A slide element.\r\n\t\t * @param {number} index - A unique index. This can be negative.\r\n\t\t * @param {number} realIndex - A real index for clones. Set -1 for real slides.\r\n\t\t */\r\n\t\tregister( slide, index, realIndex ) {\r\n\t\t\tconst SlideObject = Slide( Splide, index, realIndex, slide );\r\n\t\t\tSlideObject.mount();\r\n\t\t\tSlides.push( SlideObject );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the Slide object designated by the index.\r\n\t\t * Note that \"find\" is not supported by IE.\r\n\t\t *\r\n\t\t * @return {Object|undefined} - A Slide object if available. Undefined if not.\r\n\t\t */\r\n\t\tgetSlide( index ) {\r\n\t\t\treturn Slides.filter( Slide => Slide.index === index )[0];\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return all Slide objects.\r\n\t\t *\r\n\t\t * @param {boolean} includeClones - Whether to include cloned slides or not.\r\n\t\t *\r\n\t\t * @return {Object[]} - Slide objects.\r\n\t\t */\r\n\t\tgetSlides( includeClones ) {\r\n\t\t\treturn includeClones ? Slides : Slides.filter( Slide => ! Slide.isClone );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return Slide objects belonging to the given page.\r\n\t\t *\r\n\t\t * @param {number} page - A page number.\r\n\t\t *\r\n\t\t * @return {Object[]} - An array containing Slide objects.\r\n\t\t */\r\n\t\tgetSlidesByPage( page ) {\r\n\t\t\tconst idx = Components.Controller.toIndex( page );\r\n\t\t\tconst options = Splide.options;\r\n\t\t\tconst max = options.focus !== false ? 1 : options.perPage;\r\n\r\n\t\t\treturn Slides.filter( ( { index } ) => idx <= index && index < idx + max );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Insert a slide to a slider.\r\n\t\t * Need to refresh Splide after adding a slide.\r\n\t\t *\r\n\t\t * @param {Node|string} slide - A slide element to be added.\r\n\t\t * @param {number} index - A slide will be added at the position.\r\n\t\t * @param {Function} callback - Called right after the slide is added to the DOM tree.\r\n\t\t */\r\n\t\tadd( slide, index, callback ) {\r\n\t\t\tif ( typeof slide === 'string' ) {\r\n\t\t\t\tslide = domify( slide );\r\n\t\t\t}\r\n\r\n\t\t\tif ( slide instanceof Element ) {\r\n\t\t\t\tconst ref = this.slides[ index ];\r\n\r\n\t\t\t\t// This will be removed in mount() of a Slide component.\r\n\t\t\t\tapplyStyle( slide, { display: 'none' } );\r\n\r\n\t\t\t\tif ( ref ) {\r\n\t\t\t\t\tbefore( slide, ref );\r\n\t\t\t\t\tthis.slides.splice( index, 0, slide );\r\n\t\t\t\t} else {\r\n\t\t\t\t\tappend( this.list, slide );\r\n\t\t\t\t\tthis.slides.push( slide );\r\n\t\t\t\t}\r\n\r\n\t\t\t\tloaded( slide, () => { callback && callback( slide ) } );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Remove a slide from a slider.\r\n\t\t * Need to refresh Splide after removing a slide.\r\n\t\t *\r\n\t\t * @param index - Slide index.\r\n\t\t */\r\n\t\tremove( index ) {\r\n\t\t\tremove( this.slides.splice( index, 1 )[0] );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Trigger the provided callback for each Slide object.\r\n\t\t *\r\n\t\t * @param {Function} callback - A callback function. The first argument will be the Slide object.\r\n\t\t */\r\n\t\teach( callback ) {\r\n\t\t\tSlides.forEach( callback );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return slides length without clones.\r\n\t\t *\r\n\t\t * @return {number} - Slide length.\r\n\t\t */\r\n\t\tget length() {\r\n\t\t\treturn this.slides.length;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return \"SlideObjects\" length including clones.\r\n\t\t *\r\n\t\t * @return {number} - Slide length including clones.\r\n\t\t */\r\n\t\tget total() {\r\n\t\t\treturn Slides.length;\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Collect elements.\r\n\t */\r\n\tfunction collect() {\r\n\t\tElements.slider = child( root, classes.slider );\r\n\t\tElements.track = find( root, `.${ classes.track }` );\r\n\t\tElements.list = child( Elements.track, classes.list );\r\n\r\n\t\texist( Elements.track && Elements.list, 'Track or list was not found.' );\r\n\r\n\t\tElements.slides = children( Elements.list, classes.slide );\r\n\r\n\t\tconst arrows = findParts( classes.arrows );\r\n\t\tElements.arrows = {\r\n\t\t\tprev: find( arrows, `.${ classes.prev }` ),\r\n\t\t\tnext: find( arrows, `.${ classes.next }` ),\r\n\t\t};\r\n\r\n\t\tconst autoplay = findParts( classes.autoplay );\r\n\t\tElements.bar = find( findParts( classes.progress ), `.${ classes.bar }` );\r\n\t\tElements.play = find( autoplay, `.${ classes.play }` );\r\n\t\tElements.pause = find( autoplay, `.${ classes.pause }` );\r\n\r\n\t\tElements.track.id = Elements.track.id || `${ root.id }-track`;\r\n\t\tElements.list.id = Elements.list.id || `${ root.id }-list`;\r\n\t}\r\n\r\n\t/**\r\n\t * Return class names for the root element.\r\n\t */\r\n\tfunction getClasses() {\r\n\t\tconst rootClass = classes.root;\r\n\t\tconst options = Splide.options;\r\n\r\n\t\treturn [\r\n\t\t\t`${ rootClass }--${ options.type }`,\r\n\t\t\t`${ rootClass }--${ options.direction }`,\r\n\t\t\toptions.drag ? `${ rootClass }--draggable` : '',\r\n\t\t\toptions.isNavigation ? `${ rootClass }--nav` : '',\r\n\t\t\tSTATUS_CLASSES.active,\r\n\t\t];\r\n\t}\r\n\r\n\t/**\r\n\t * Find parts only from children of the root or track.\r\n\t *\r\n\t * @return {Element} - A found element or undefined.\r\n\t */\r\n\tfunction findParts( className ) {\r\n\t\treturn child( root, className ) || child( Elements.slider, className );\r\n\t}\r\n\r\n\treturn Elements;\r\n}","/**\r\n * The component for controlling the track.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { LOOP } from \"../../constants/types\";\r\nimport { RTL } from '../../constants/directions';\r\nimport { between } from '../../utils/utils';\r\n\r\nconst { floor } = Math;\r\n\r\n\r\n/**\r\n * The component for controlling the track.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Store current options.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tlet options;\r\n\r\n\t/**\r\n\t * True if the slide is LOOP mode.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tlet isLoop;\r\n\r\n\t/**\r\n\t * Controller component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Controller = {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\toptions = Splide.options;\r\n\t\t\tisLoop = Splide.is( LOOP );\r\n\t\t\tbind();\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Make track run by the given control.\r\n\t\t * - \"+{i}\" : Increment the slide index by i.\r\n\t\t * - \"-{i}\" : Decrement the slide index by i.\r\n\t\t * - \"{i}\" : Go to the slide whose index is i.\r\n\t\t * - \">\" : Go to next page.\r\n\t\t * - \"<\" : Go to prev page.\r\n\t\t * - \">{i}\" : Go to page i.\r\n\t\t *\r\n\t\t * @param {string|number} control - A control pattern.\r\n\t\t * @param {boolean} silently - Go to the destination without event emission.\r\n\t\t */\r\n\t\tgo( control, silently ) {\r\n\t\t\tconst destIndex = this.trim( this.parse( control ) );\r\n\t\t\tComponents.Track.go( destIndex, this.rewind( destIndex ), silently );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Parse the given control and return the destination index for the track.\r\n\t\t *\r\n\t\t * @param {string} control - A control target pattern.\r\n\t\t *\r\n\t\t * @return {number} - A parsed target.\r\n\t\t */\r\n\t\tparse( control ) {\r\n\t\t\tlet index = Splide.index;\r\n\r\n\t\t\tconst matches = String( control ).match( /([+\\-<>]+)(\\d+)?/ );\r\n\t\t\tconst indicator = matches ? matches[1] : '';\r\n\t\t\tconst number = matches ? parseInt( matches[2] ) : 0;\r\n\r\n\t\t\tswitch ( indicator ) {\r\n\t\t\t\tcase '+':\r\n\t\t\t\t\tindex += number || 1;\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase '-':\r\n\t\t\t\t\tindex -= number || 1;\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase '>':\r\n\t\t\t\tcase '<':\r\n\t\t\t\t\tindex = parsePage( number, index, indicator === '<' );\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tindex = parseInt( control );\r\n\t\t\t}\r\n\r\n\t\t\treturn index;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Compute index from the given page number.\r\n\t\t *\r\n\t\t * @param {number} page - Page number.\r\n\t\t *\r\n\t\t * @return {number} - A computed page number.\r\n\t\t */\r\n\t\ttoIndex( page ) {\r\n\t\t\tif ( hasFocus() ) {\r\n\t\t\t\treturn page;\r\n\t\t\t}\r\n\r\n\t\t\tconst length = Splide.length;\r\n\t\t\tconst perPage = options.perPage;\r\n\r\n\t\t\tlet index = page * perPage;\r\n\t\t\tindex = index - ( this.pageLength * perPage - length ) * floor( index / length );\r\n\r\n\t\t\t// Adjustment for the last page.\r\n\t\t\tif ( length - perPage <= index && index < length ) {\r\n\t\t\t\tindex = length - perPage;\r\n\t\t\t}\r\n\r\n\t\t\treturn index;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Compute page number from the given slide index.\r\n\t\t *\r\n\t\t * @param {number} index - Slide index.\r\n\t\t *\r\n\t\t * @return {number} - A computed page number.\r\n\t\t */\r\n\t\ttoPage( index ) {\r\n\t\t\tif ( hasFocus() ) {\r\n\t\t\t\treturn index;\r\n\t\t\t}\r\n\r\n\t\t\tconst length = Splide.length;\r\n\t\t\tconst perPage = options.perPage;\r\n\r\n\t\t\t// Make the last \"perPage\" number of slides belong to the last page.\r\n\t\t\tif ( length - perPage <= index && index < length ) {\r\n\t\t\t\treturn floor( ( length - 1 ) / perPage );\r\n\t\t\t}\r\n\r\n\t\t\treturn floor( index / perPage );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Trim the given index according to the current mode.\r\n\t\t * Index being returned could be less than 0 or greater than the length in Loop mode.\r\n\t\t *\r\n\t\t * @param {number} index - An index being trimmed.\r\n\t\t *\r\n\t\t * @return {number} - A trimmed index.\r\n\t\t */\r\n\t\ttrim( index ) {\r\n\t\t\tif ( ! isLoop ) {\r\n\t\t\t\tindex = options.rewind ? this.rewind( index ) : between( index, 0, this.edgeIndex );\r\n\t\t\t}\r\n\r\n\t\t\treturn index;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Rewind the given index if it's out of range.\r\n\t\t *\r\n\t\t * @param {number} index - An index.\r\n\t\t *\r\n\t\t * @return {number} - A rewound index.\r\n\t\t */\r\n\t\trewind( index ) {\r\n\t\t\tconst edge = this.edgeIndex;\r\n\r\n\t\t\tif ( isLoop ) {\r\n\t\t\t\twhile( index > edge ) {\r\n\t\t\t\t\tindex -= edge + 1;\r\n\t\t\t\t}\r\n\r\n\t\t\t\twhile( index < 0 ) {\r\n\t\t\t\t\tindex += edge + 1;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif ( index > edge ) {\r\n\t\t\t\t\tindex = 0;\r\n\t\t\t\t} else if ( index < 0 ) {\r\n\t\t\t\t\tindex = edge;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn index;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Check if the direction is \"rtl\" or not.\r\n\t\t *\r\n\t\t * @return {boolean} - True if \"rtl\" or false if not.\r\n\t\t */\r\n\t\tisRtl() {\r\n\t\t\treturn options.direction === RTL;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the page length.\r\n\t\t *\r\n\t\t * @return {number} - Max page number.\r\n\t\t */\r\n\t\tget pageLength() {\r\n\t\t\tconst length = Splide.length;\r\n\t\t\treturn hasFocus() ? length : Math.ceil( length / options.perPage );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the edge index.\r\n\t\t *\r\n\t\t * @return {number} - Edge index.\r\n\t\t */\r\n\t\tget edgeIndex() {\r\n\t\t\tconst length = Splide.length;\r\n\r\n\t\t\tif ( ! length ) {\r\n\t\t\t\treturn 0;\r\n\t\t\t}\r\n\r\n\t\t\tif ( hasFocus() || options.isNavigation || isLoop ) {\r\n\t\t\t\treturn length - 1;\r\n\t\t\t}\r\n\r\n\t\t\treturn length - options.perPage;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the index of the previous slide.\r\n\t\t *\r\n\t\t * @return {number} - The index of the previous slide if available. -1 otherwise.\r\n\t\t */\r\n\t\tget prevIndex() {\r\n\t\t\tlet prev = Splide.index - 1;\r\n\r\n\t\t\tif ( isLoop || options.rewind ) {\r\n\t\t\t\tprev = this.rewind( prev );\r\n\t\t\t}\r\n\r\n\t\t\treturn prev > -1 ? prev : -1;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the index of the next slide.\r\n\t\t *\r\n\t\t * @return {number} - The index of the next slide if available. -1 otherwise.\r\n\t\t */\r\n\t\tget nextIndex() {\r\n\t\t\tlet next = Splide.index + 1;\r\n\r\n\t\t\tif ( isLoop || options.rewind ) {\r\n\t\t\t\tnext = this.rewind( next );\r\n\t\t\t}\r\n\r\n\t\t\treturn ( Splide.index < next && next <= this.edgeIndex ) || next === 0 ? next : -1;\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Listen to some events.\r\n\t */\r\n\tfunction bind() {\r\n\t\tSplide\r\n\t\t\t.on( 'move', newIndex => { Splide.index = newIndex } )\r\n\t\t\t.on( 'updated refresh', newOptions => {\r\n\t\t\t\toptions = newOptions || options;\r\n\t\t\t\tSplide.index = between( Splide.index, 0, Controller.edgeIndex );\r\n\t\t\t} );\r\n\t}\r\n\r\n\t/**\r\n\t * Verify if the focus option is available or not.\r\n\t *\r\n\t * @return {boolean} - True if a slider has the focus option.\r\n\t */\r\n\tfunction hasFocus() {\r\n\t\treturn options.focus !== false;\r\n\t}\r\n\r\n\t/**\r\n\t * Return the next or previous page index computed by the page number and current index.\r\n\t *\r\n\t * @param {number} number - Specify the page number.\r\n\t * @param {number} index - Current index.\r\n\t * @param {boolean} prev - Prev or next.\r\n\t *\r\n\t * @return {number} - Slide index.\r\n\t */\r\n\tfunction parsePage( number, index, prev ) {\r\n\t\tif ( number > -1 ) {\r\n\t\t\treturn Controller.toIndex( number );\r\n\t\t}\r\n\r\n\t\tconst perMove = options.perMove;\r\n\t\tconst sign = prev ? -1 : 1;\r\n\r\n\t\tif ( perMove ) {\r\n\t\t\treturn index + perMove * sign;\r\n\t\t}\r\n\r\n\t\treturn Controller.toIndex( Controller.toPage( index ) + sign );\r\n\t}\r\n\r\n\treturn Controller;\r\n}","/**\r\n * The component for moving list in the track.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle, getRect } from '../../utils/dom';\r\nimport { between } from \"../../utils/utils\";\r\nimport { LOOP, FADE } from '../../constants/types';\r\nimport { RTL, TTB } from '../../constants/directions';\r\nimport { MOVING } from \"../../constants/states\";\r\n\r\nconst { abs } = Math;\r\n\r\n\r\n/**\r\n * The component for moving list in the track.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Hold the Layout component.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tlet Layout;\r\n\r\n\t/**\r\n\t * Hold the Layout component.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tlet Elements;\r\n\r\n\t/**\r\n\t * Store the list element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tlet list;\r\n\r\n\t/**\r\n\t * Whether the current direction is vertical or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tconst isVertical = Splide.options.direction === TTB;\r\n\r\n\t/**\r\n\t * Whether the slider type is FADE or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tconst isFade = Splide.is( FADE );\r\n\r\n\t/**\r\n\t * Whether the slider direction is RTL or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tconst isRTL = Splide.options.direction === RTL;\r\n\r\n\t/**\r\n\t * This will be true while transitioning from the last index to the first one.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tlet isLoopPending = false;\r\n\r\n\t/**\r\n\t * Sign for the direction. Only RTL mode uses the positive sign.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tconst sign = isRTL ? 1 : -1;\r\n\r\n\t/**\r\n\t * Track component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Track = {\r\n\t\t/**\r\n\t\t * Make public the sign defined locally.\r\n\t\t *\r\n\t\t * @type {number}\r\n\t\t */\r\n\t\tsign,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tElements = Components.Elements;\r\n\t\t\tLayout = Components.Layout;\r\n\t\t\tlist = Elements.list;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Called after the component is mounted.\r\n\t\t * The resize event must be registered after the Layout's one is done.\r\n\t\t */\r\n\t\tmounted() {\r\n\t\t\tif ( ! isFade ) {\r\n\t\t\t\tthis.jump( 0 );\r\n\t\t\t\tSplide.on( 'mounted resize updated', () => { this.jump( Splide.index ) } );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Go to the given destination index.\r\n\t\t * After arriving there, the track is jump to the new index without animation, mainly for loop mode.\r\n\t\t *\r\n\t\t * @param {number} destIndex - A destination index.\r\n\t\t * This can be negative or greater than slides length for reaching clones.\r\n\t\t * @param {number} newIndex - An actual new index. They are always same in Slide and Rewind mode.\r\n\t\t * @param {boolean} silently - If true, suppress emitting events.\r\n\t\t */\r\n\t\tgo( destIndex, newIndex, silently ) {\r\n\t\t\tconst newPosition = getTrimmedPosition( destIndex );\r\n\t\t\tconst prevIndex = Splide.index;\r\n\r\n\t\t\t// Prevent any actions while transitioning from the last index to the first one for jump.\r\n\t\t\tif ( Splide.State.is( MOVING ) && isLoopPending ) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tisLoopPending = destIndex !== newIndex;\r\n\r\n\t\t\tif ( ! silently ) {\r\n\t\t\t\tSplide.emit( 'move', newIndex, prevIndex, destIndex );\r\n\t\t\t}\r\n\r\n\t\t\tif ( Math.abs( newPosition - this.position ) >= 1 || isFade ) {\r\n\t\t\t\tComponents.Transition.start( destIndex, newIndex, prevIndex, this.toCoord( newPosition ), () => {\r\n\t\t\t\t\tonTransitionEnd( destIndex, newIndex, prevIndex, silently );\r\n\t\t\t\t} );\r\n\t\t\t} else {\r\n\t\t\t\tif ( destIndex !== prevIndex && Splide.options.trimSpace === 'move' ) {\r\n\t\t\t\t\tComponents.Controller.go( destIndex + destIndex - prevIndex, silently );\r\n\t\t\t\t} else {\r\n\t\t\t\t\tonTransitionEnd( destIndex, newIndex, prevIndex, silently );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Move the track to the specified index.\r\n\t\t *\r\n\t\t * @param {number} index - A destination index where the track jumps.\r\n\t\t */\r\n\t\tjump( index ) {\r\n\t\t\tthis.translate( getTrimmedPosition( index ) );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Set the list position by CSS translate property.\r\n\t\t *\r\n\t\t * @param {number} position - A new position value.\r\n\t\t */\r\n\t\ttranslate( position ) {\r\n\t\t\tapplyStyle( list, { transform: `translate${ isVertical ? 'Y' : 'X' }(${ position }px)` } );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Cancel the transition and set the list position.\r\n\t\t * Also, loop the slider if necessary.\r\n\t\t */\r\n\t\tcancel() {\r\n\t\t\tif ( Splide.is( LOOP ) ) {\r\n\t\t\t\tthis.shift();\r\n\t\t\t} else {\r\n\t\t\t\t// Ensure the current position.\r\n\t\t\t\tthis.translate( this.position );\r\n\t\t\t}\r\n\r\n\t\t\tapplyStyle( list, { transition: '' } );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Shift the slider if it exceeds borders on the edge.\r\n\t\t */\r\n\t\tshift() {\r\n\t\t\tlet position = abs( this.position );\r\n\r\n\t\t\tconst left = abs( this.toPosition( 0 ) );\r\n\t\t\tconst right = abs( this.toPosition( Splide.length ) );\r\n\t\t\tconst innerSize = right - left;\r\n\r\n\t\t\tif ( position < left ) {\r\n\t\t\t\tposition += innerSize;\r\n\t\t\t} else if ( position > right ) {\r\n\t\t\t\tposition -= innerSize;\r\n\t\t\t}\r\n\r\n\t\t\tthis.translate( sign * position );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Trim redundant spaces on the left or right edge if necessary.\r\n\t\t *\r\n\t\t * @param {number} position - Position value to be trimmed.\r\n\t\t *\r\n\t\t * @return {number} - Trimmed position.\r\n\t\t */\r\n\t\ttrim( position ) {\r\n\t\t\tif ( ! Splide.options.trimSpace || Splide.is( LOOP ) ) {\r\n\t\t\t\treturn position;\r\n\t\t\t}\r\n\r\n\t\t\tconst edge = sign * ( Layout.totalSize() - Layout.size - Layout.gap );\r\n\t\t\treturn between( position, edge, 0 );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Calculate the closest slide index from the given position.\r\n\t\t *\r\n\t\t * @param {number} position - A position converted to an slide index.\r\n\t\t *\r\n\t\t * @return {number} - The closest slide index.\r\n\t\t */\r\n\t\ttoIndex( position ) {\r\n\t\t\tlet index = 0;\r\n\t\t\tlet minDistance = Infinity;\r\n\r\n\t\t\tElements.getSlides( true ).forEach( Slide => {\r\n\t\t\t\tconst slideIndex = Slide.index;\r\n\t\t\t\tconst distance = abs( this.toPosition( slideIndex ) - position );\r\n\r\n\t\t\t\tif ( distance < minDistance ) {\r\n\t\t\t\t\tminDistance = distance;\r\n\t\t\t\t\tindex = slideIndex;\r\n\t\t\t\t}\r\n\t\t\t} );\r\n\r\n\t\t\treturn index;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return coordinates object by the given position.\r\n\t\t *\r\n\t\t * @param {number} position - A position value.\r\n\t\t *\r\n\t\t * @return {Object} - A coordinates object.\r\n\t\t */\r\n\t\ttoCoord( position ) {\r\n\t\t\treturn {\r\n\t\t\t\tx: isVertical ? 0 : position,\r\n\t\t\t\ty: isVertical ? position : 0,\r\n\t\t\t};\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Calculate the track position by a slide index.\r\n\t\t *\r\n\t\t * @param {number} index - Slide index.\r\n\t\t *\r\n\t\t * @return {Object} - Calculated position.\r\n\t\t */\r\n\t\ttoPosition( index ) {\r\n\t\t\tconst position = Layout.totalSize( index ) - Layout.slideSize( index ) - Layout.gap;\r\n\t\t\treturn sign * ( position + this.offset( index ) );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the current offset value, considering direction.\r\n\t\t *\r\n\t\t * @return {number} - Offset amount.\r\n\t\t */\r\n\t\toffset( index ) {\r\n\t\t\tconst { focus } = Splide.options;\r\n\t\t\tconst slideSize = Layout.slideSize( index );\r\n\r\n\t\t\tif ( focus === 'center' ) {\r\n\t\t\t\treturn -( Layout.size - slideSize ) / 2;\r\n\t\t\t}\r\n\r\n\t\t\treturn -( parseInt( focus ) || 0 ) * ( slideSize + Layout.gap );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the current position.\r\n\t\t * This returns the correct position even while transitioning by CSS.\r\n\t\t *\r\n\t\t * @return {number} - Current position.\r\n\t\t */\r\n\t\tget position() {\r\n\t\t\tconst prop = isVertical ? 'top' : isRTL ? 'right' : 'left';\r\n\t\t\treturn getRect( list )[ prop ] - ( getRect( Elements.track )[ prop ] - Layout.padding[ prop ] * sign );\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Called whenever slides arrive at a destination.\r\n\t *\r\n\t * @param {number} destIndex - A destination index.\r\n\t * @param {number} newIndex - A new index.\r\n\t * @param {number} prevIndex - A previous index.\r\n\t * @param {boolean} silently - If true, suppress emitting events.\r\n\t */\r\n\tfunction onTransitionEnd( destIndex, newIndex, prevIndex, silently ) {\r\n\t\tapplyStyle( list, { transition: '' } );\r\n\t\tisLoopPending = false;\r\n\r\n\t\tif ( ! isFade ) {\r\n\t\t\tTrack.jump( newIndex );\r\n\t\t}\r\n\r\n\t\tif ( ! silently ) {\r\n\t\t\tSplide.emit( 'moved', newIndex, prevIndex, destIndex );\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Convert index to the trimmed position.\r\n\t *\r\n\t * @return {number} - Trimmed position.\r\n\t */\r\n\tfunction getTrimmedPosition( index ) {\r\n\t\treturn Track.trim( Track.toPosition( index ) );\r\n\t}\r\n\r\n\treturn Track;\r\n}","/**\r\n * The component for cloning some slides for \"loop\" mode of the track.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { addClass, removeAttribute, append, before, remove } from '../../utils/dom';\r\nimport { LOOP } from '../../constants/types';\r\nimport { TTB } from \"../../constants/directions\";\r\nimport { toPixel } from \"../../utils/utils\";\r\n\r\n\r\n/**\r\n * The component for cloning some slides for \"loop\" mode of the track.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Store information of all clones.\r\n\t *\r\n\t * @type {Array}\r\n\t */\r\n\tlet clones = [];\r\n\r\n\t/**\r\n\t * Store the current clone count on one side.\r\n\t *\r\n\t * @type {number}\r\n\t */\r\n\tlet cloneCount = 0;\r\n\r\n\t/**\r\n\t * Keep Elements component.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Elements = Components.Elements;\r\n\r\n\t/**\r\n\t * Clones component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Clones = {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tif ( Splide.is( LOOP ) ) {\r\n\t\t\t\tinit();\r\n\r\n\t\t\t\tSplide\r\n\t\t\t\t\t.on( 'refresh:before', () => { this.destroy() } )\r\n\t\t\t\t\t.on( 'refresh', init )\r\n\t\t\t\t\t.on( 'resize', () => {\r\n\t\t\t\t\t\tif ( cloneCount !== getCloneCount() ) {\r\n\t\t\t\t\t\t\t// Destroy before refresh not to collect clones by the Elements component.\r\n\t\t\t\t\t\t\tthis.destroy();\r\n\t\t\t\t\t\t\tSplide.refresh();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Destroy.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tremove( clones );\r\n\t\t\tclones = [];\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return all clones.\r\n\t\t *\r\n\t\t * @return {Element[]} - Cloned elements.\r\n\t\t */\r\n\t\tget clones() {\r\n\t\t\treturn clones;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return clone length.\r\n\t\t *\r\n\t\t * @return {number} - A length of clones.\r\n\t\t */\r\n\t\tget length() {\r\n\t\t\treturn clones.length;\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Initialization.\r\n\t */\r\n\tfunction init() {\r\n\t\tClones.destroy();\r\n\t\tcloneCount = getCloneCount();\r\n\t\tgenerateClones( cloneCount );\r\n\t}\r\n\r\n\t/**\r\n\t * Generate and append/prepend clones.\r\n\t *\r\n\t * @param {number} count - The half number of clones.\r\n\t */\r\n\tfunction generateClones( count ) {\r\n\t\tconst { length, register } = Elements;\r\n\r\n\t\tif ( length ) {\r\n\t\t\tlet slides = Elements.slides;\r\n\r\n\t\t\twhile ( slides.length < count ) {\r\n\t\t\t\tslides = slides.concat( slides );\r\n\t\t\t}\r\n\r\n\t\t\t// Clones after the last element.\r\n\t\t\tslides.slice( 0, count ).forEach( ( elm, index ) => {\r\n\t\t\t\tconst clone = cloneDeeply( elm );\r\n\t\t\t\tappend( Elements.list, clone );\r\n\t\t\t\tclones.push( clone );\r\n\r\n\t\t\t\tregister( clone, index + length, index % length );\r\n\t\t\t} );\r\n\r\n\t\t\t// Clones before the first element.\r\n\t\t\tslides.slice( -count ).forEach( ( elm, index ) => {\r\n\t\t\t\tconst clone = cloneDeeply( elm );\r\n\t\t\t\tbefore( clone, slides[0] );\r\n\t\t\t\tclones.push( clone );\r\n\r\n\t\t\t\tregister( clone, index - count, ( length + index - count % length ) % length );\r\n\t\t\t} );\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Return half count of clones to be generated.\r\n\t * Clone count is determined by:\r\n\t * - \"clones\" value in the options.\r\n\t * - Number of slides that can be placed in a view in \"fixed\" mode.\r\n\t * - Max pages a flick action can move.\r\n\t * - Whether the slide length is enough for perPage.\r\n\t *\r\n\t * @return {number} - Count for clones.\r\n\t */\r\n\tfunction getCloneCount() {\r\n\t\tconst options = Splide.options;\r\n\r\n\t\tif ( options.clones ) {\r\n\t\t\treturn options.clones;\r\n\t\t}\r\n\r\n\t\t// Use the slide length in autoWidth mode because the number cannot be calculated.\r\n\t\tlet baseCount = options.autoWidth || options.autoHeight ? Elements.length : options.perPage;\r\n\r\n\t\tconst dimension = options.direction === TTB ? 'Height' : 'Width';\r\n\t\tconst fixedSize = toPixel( Splide.root, options[ `fixed${ dimension }` ] );\r\n\r\n\t\tif ( fixedSize ) {\r\n\t\t\t// Roughly calculate the count. This needs not to be strict.\r\n\t\t\tbaseCount = Math.ceil( Elements.track[ `client${ dimension }` ] / fixedSize );\r\n\t\t}\r\n\r\n\t\treturn baseCount * ( options.drag ? options.flickMaxPages + 1 : 1 );\r\n\t}\r\n\r\n\t/**\r\n\t * Clone deeply the given element.\r\n\t *\r\n\t * @param {Element} elm - An element being duplicated.\r\n\t *\r\n\t * @return {Node} - A cloned node(element).\r\n\t */\r\n\tfunction cloneDeeply( elm ) {\r\n\t\tconst clone = elm.cloneNode( true );\r\n\t\taddClass( clone, Splide.classes.clone );\r\n\r\n\t\t// ID should not be duplicated.\r\n\t\tremoveAttribute( clone, 'id' );\r\n\t\treturn clone;\r\n\t}\r\n\r\n\treturn Clones;\r\n}","/**\r\n * The resolver component for horizontal layout.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle, getRect } from \"../../../utils/dom\";\r\nimport { unit, toPixel } from \"../../../utils/utils\";\r\nimport { RTL } from '../../../constants/directions';\r\n\r\n\r\n/**\r\n * The resolver component for horizontal layout.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The resolver object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Keep the Elements component.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst Elements = Components.Elements;\r\n\r\n\t/**\r\n\t * Keep the root element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tconst root = Splide.root;\r\n\r\n\t/**\r\n\t * Keep the track element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tlet track;\r\n\r\n\t/**\r\n\t * Keep the latest options.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tlet options = Splide.options;\r\n\r\n\treturn {\r\n\t\t/**\r\n\t\t * Margin property name.\r\n\t\t *\r\n\t\t * @type {string}\r\n\t\t */\r\n\t\tmargin: 'margin' + ( options.direction === RTL ? 'Left' : 'Right' ),\r\n\r\n\t\t/**\r\n\t\t * Always 0 because the height will be determined by inner contents.\r\n\t\t *\r\n\t\t * @type {number}\r\n\t\t */\r\n\t\theight: 0,\r\n\r\n\t\t/**\r\n\t\t * Initialization.\r\n\t\t */\r\n\t\tinit() {\r\n\t\t\tthis.resize();\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Resize gap and padding.\r\n\t\t * This must be called on init.\r\n\t\t */\r\n\t\tresize() {\r\n\t\t\toptions = Splide.options;\r\n\t\t\ttrack = Elements.track;\r\n\r\n\t\t\tthis.gap = toPixel( root, options.gap );\r\n\r\n\t\t\tconst padding = options.padding;\r\n\t\t\tconst left = toPixel( root, padding.left || padding );\r\n\t\t\tconst right = toPixel( root, padding.right || padding );\r\n\r\n\t\t\tthis.padding = { left, right };\r\n\t\t\tapplyStyle( track, { paddingLeft : unit( left ), paddingRight: unit( right ) } );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return total width from the left of the list to the right of the slide specified by the provided index.\r\n\t\t *\r\n\t\t * @param {number} index - Optional. A slide index. If undefined, total width of the slider will be returned.\r\n\t\t *\r\n\t\t * @return {number} - Total width to the right side of the specified slide, or 0 for an invalid index.\r\n\t\t */\r\n\t\ttotalWidth( index = Splide.length - 1 ) {\r\n\t\t\tconst Slide = Elements.getSlide( index );\r\n\r\n\t\t\tlet width = 0;\r\n\r\n\t\t\tif ( Slide ) {\r\n\t\t\t\tconst slideRect = getRect( Slide.slide );\r\n\t\t\t\tconst listRect = getRect( Elements.list );\r\n\r\n\t\t\t\tif ( options.direction === RTL ) {\r\n\t\t\t\t\twidth = listRect.right - slideRect.left;\r\n\t\t\t\t} else {\r\n\t\t\t\t\twidth = slideRect.right - listRect.left;\r\n\t\t\t\t}\r\n\r\n\t\t\t\twidth += this.gap;\r\n\t\t\t}\r\n\r\n\t\t\treturn width;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the slide width in px.\r\n\t\t *\r\n\t\t * @param {number} index - Slide index.\r\n\t\t *\r\n\t\t * @return {number} - The slide width.\r\n\t\t */\r\n\t\tslideWidth( index ) {\r\n\t\t\tif ( options.autoWidth ) {\r\n\t\t\t\tconst Slide = Elements.getSlide( index );\r\n\t\t\t\treturn Slide ? Slide.slide.offsetWidth : 0;\r\n\t\t\t}\r\n\r\n\t\t\tconst width = options.fixedWidth || ( ( this.width + this.gap ) / options.perPage ) - this.gap;\r\n\t\t\treturn toPixel( root, width );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the slide height in px.\r\n\t\t *\r\n\t\t * @return {number} - The slide height.\r\n\t\t */\r\n\t\tslideHeight() {\r\n\t\t\tconst height = options.height || options.fixedHeight || this.width * options.heightRatio;\r\n\t\t\treturn toPixel( root, height );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return slider width without padding.\r\n\t\t *\r\n\t\t * @return {number} - Current slider width.\r\n\t\t */\r\n\t\tget width() {\r\n\t\t\treturn track.clientWidth - this.padding.left - this.padding.right;\r\n\t\t},\r\n\t}\r\n}","/**\r\n * The resolver component for vertical layout.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle, getRect } from \"../../../utils/dom\";\r\nimport { toPixel, unit } from \"../../../utils/utils\";\r\nimport { exist } from \"../../../utils/error\";\r\n\r\n\r\n/**\r\n * The resolver component for vertical layout.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The resolver object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Keep the Elements component.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst Elements = Components.Elements;\r\n\r\n\t/**\r\n\t * Keep the root element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tconst root = Splide.root;\r\n\r\n\t/**\r\n\t * Keep the track element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tlet track;\r\n\r\n\t/**\r\n\t * Keep the latest options.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tlet options;\r\n\r\n\treturn {\r\n\t\t/**\r\n\t\t * Margin property name.\r\n\t\t *\r\n\t\t * @type {string}\r\n\t\t */\r\n\t\tmargin: 'marginBottom',\r\n\r\n\t\t/**\r\n\t\t * Initialization.\r\n\t\t */\r\n\t\tinit() {\r\n\t\t\tthis.resize();\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Resize gap and padding.\r\n\t\t * This must be called on init.\r\n\t\t */\r\n\t\tresize() {\r\n\t\t\toptions = Splide.options;\r\n\t\t\ttrack = Elements.track;\r\n\r\n\t\t\tthis.gap = toPixel( root, options.gap );\r\n\r\n\t\t\tconst padding = options.padding;\r\n\t\t\tconst top = toPixel( root, padding.top || padding );\r\n\t\t\tconst bottom = toPixel( root, padding.bottom || padding );\r\n\r\n\t\t\tthis.padding = { top, bottom };\r\n\t\t\tapplyStyle( track, { paddingTop : unit( top ), paddingBottom: unit( bottom ) } );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return total height from the top of the list to the bottom of the slide specified by the provided index.\r\n\t\t *\r\n\t\t * @param {number} index - Optional. A slide index. If undefined, total height of the slider will be returned.\r\n\t\t *\r\n\t\t * @return {number} - Total height to the bottom of the specified slide, or 0 for an invalid index.\r\n\t\t */\r\n\t\ttotalHeight( index = Splide.length - 1 ) {\r\n\t\t\tconst Slide = Elements.getSlide( index );\r\n\r\n\t\t\tif ( Slide ) {\r\n\t\t\t\treturn getRect( Slide.slide ).bottom - getRect( Elements.list ).top + this.gap;\r\n\t\t\t}\r\n\r\n\t\t\treturn 0;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the slide width in px.\r\n\t\t *\r\n\t\t * @return {number} - The slide width.\r\n\t\t */\r\n\t\tslideWidth() {\r\n\t\t\treturn toPixel( root, options.fixedWidth || this.width );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the slide height in px.\r\n\t\t *\r\n\t\t * @param {number} index - Slide index.\r\n\t\t *\r\n\t\t * @return {number} - The slide height.\r\n\t\t */\r\n\t\tslideHeight( index ) {\r\n\t\t\tif ( options.autoHeight ) {\r\n\t\t\t\tconst Slide = Elements.getSlide( index );\r\n\t\t\t\treturn Slide ? Slide.slide.offsetHeight : 0;\r\n\t\t\t}\r\n\r\n\t\t\tconst height = options.fixedHeight || ( this.height + this.gap ) / options.perPage - this.gap;\r\n\t\t\treturn toPixel( root, height );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return slider width without padding.\r\n\t\t *\r\n\t\t * @return {number} - Current slider width.\r\n\t\t */\r\n\t\tget width() {\r\n\t\t\treturn track.clientWidth;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return slide height without padding.\r\n\t\t *\r\n\t\t * @return {number} - Slider height.\r\n\t\t */\r\n\t\tget height() {\r\n\t\t\tconst height = options.height || this.width * options.heightRatio;\r\n\t\t\texist( height, '\"height\" or \"heightRatio\" is missing.' );\r\n\t\t\treturn toPixel( root, height ) - this.padding.top - this.padding.bottom;\r\n\t\t},\r\n\t}\r\n}","/**\r\n * A package of utility functions related with time.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Simple throttle function that controls how often the given function is executed.\r\n *\r\n * @param {function} func - A function to be throttled.\r\n * @param {number} wait - Time in millisecond for interval of execution.\r\n *\r\n * @return {Function} - A debounced function.\r\n */\r\nexport function throttle( func, wait ) {\r\n\tlet timeout;\r\n\r\n\t// Declare function by the \"function\" keyword to prevent \"this\" from being inherited.\r\n\treturn function () {\r\n\t\tif ( ! timeout ) {\r\n\t\t\ttimeout = setTimeout( () => {\r\n\t\t\t\tfunc();\r\n\t\t\t\ttimeout = null;\r\n\t\t\t}, wait );\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Custom setInterval function that provides progress rate as callback.\r\n *\r\n * @param {function} callback - A callback function fired every time the interval time passes.\r\n * @param {number} interval - Interval duration in milliseconds.\r\n * @param {function} progress - A callback function fired whenever the progress goes.\r\n *\r\n * @return {Object} - An object containing play() and pause() functions.\r\n */\r\nexport function createInterval( callback, interval, progress ) {\r\n\tconst { requestAnimationFrame } = window;\r\n\tlet start, elapse, rate, pause = true;\r\n\r\n\tconst step = timestamp => {\r\n\t\tif ( ! pause ) {\r\n\t\t\tif ( ! start ) {\r\n\t\t\t\tstart = timestamp;\r\n\r\n\t\t\t\tif ( rate && rate < 1 ) {\r\n\t\t\t\t\tstart -= rate * interval;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\telapse = timestamp - start;\r\n\t\t\trate = elapse / interval;\r\n\r\n\t\t\tif ( elapse >= interval ) {\r\n\t\t\t\tstart = 0;\r\n\t\t\t\trate = 1;\r\n\t\t\t\tcallback();\r\n\t\t\t}\r\n\r\n\t\t\tif ( progress ) {\r\n\t\t\t\tprogress( rate );\r\n\t\t\t}\r\n\r\n\t\t\trequestAnimationFrame( step );\r\n\t\t}\r\n\t};\r\n\r\n\treturn {\r\n\t\tpause() {\r\n\t\t\tpause = true;\r\n\t\t\tstart = 0;\r\n\t\t},\r\n\r\n\t\tplay( reset ) {\r\n\t\t\tstart = 0;\r\n\r\n\t\t\tif ( reset ) {\r\n\t\t\t\trate = 0;\r\n\t\t\t}\r\n\r\n\t\t\tif ( pause ) {\r\n\t\t\t\tpause = false;\r\n\t\t\t\trequestAnimationFrame( step );\r\n\t\t\t}\r\n\t\t},\r\n\t};\r\n}","/**\r\n * The component for handing slide layouts and their sizes.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport Horizontal from './directions/horizontal';\r\nimport Vertical from './directions/vertical';\r\n\r\nimport { unit } from '../../utils/utils';\r\nimport { throttle } from '../../utils/time';\r\nimport { applyStyle, removeAttribute } from '../../utils/dom';\r\nimport { assign } from \"../../utils/object\";\r\nimport { TTB } from \"../../constants/directions\";\r\n\r\n\r\n/**\r\n * The component for handing slide layouts and their sizes.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Keep the Elements component.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst Elements = Components.Elements;\r\n\r\n\t/**\r\n\t * Whether the slider is vertical or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tconst isVertical = Splide.options.direction === TTB;\r\n\r\n\t/**\r\n\t * Layout component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Layout = assign( {\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tbind();\r\n\t\t\tinit();\r\n\r\n\t\t\t// The word \"size\" means width for a horizontal slider and height for a vertical slider.\r\n\t\t\tthis.totalSize = isVertical ? this.totalHeight : this.totalWidth;\r\n\t\t\tthis.slideSize = isVertical ? this.slideHeight : this.slideWidth;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Destroy the component.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tremoveAttribute( [ Elements.list, Elements.track ], 'style' );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Return the slider height on the vertical mode or width on the horizontal mode.\r\n\t\t *\r\n\t\t * @return {number}\r\n\t\t */\r\n\t\tget size() {\r\n\t\t\treturn isVertical ? this.height : this.width;\r\n\t\t},\r\n\t}, isVertical ?\tVertical( Splide, Components ) : Horizontal( Splide, Components ) );\r\n\r\n\t/**\r\n\t * Init slider styles according to options.\r\n\t */\r\n\tfunction init() {\r\n\t\tLayout.init();\r\n\r\n\t\tapplyStyle( Splide.root, { maxWidth: unit( Splide.options.width ) } );\r\n\t\tElements.each( Slide => { Slide.slide.style[ Layout.margin ] = unit( Layout.gap ) } );\r\n\r\n\t\tresize();\r\n\t}\r\n\r\n\t/**\r\n\t * Listen the resize native event with throttle.\r\n\t * Initialize when the component is mounted or options are updated.\r\n\t */\r\n\tfunction bind() {\r\n\t\tSplide\r\n\t\t\t.on( 'resize load', throttle( () => { Splide.emit( 'resize' ) }, Splide.options.throttle ), window )\r\n\t\t\t.on( 'resize', resize )\r\n\t\t\t.on( 'updated refresh', init );\r\n\t}\r\n\r\n\t/**\r\n\t * Resize the track and slide elements.\r\n\t */\r\n\tfunction resize() {\r\n\t\tconst options = Splide.options;\r\n\r\n\t\tLayout.resize();\r\n\r\n\t\tapplyStyle( Elements.track, { height: unit( Layout.height ) } );\r\n\r\n\t\tconst slideHeight = options.autoHeight ? null : unit( Layout.slideHeight() );\r\n\r\n\t\tElements.each( Slide => {\r\n\t\t\tapplyStyle( Slide.container, { height: slideHeight } );\r\n\r\n\t\t\tapplyStyle( Slide.slide, {\r\n\t\t\t\twidth : options.autoWidth ? null : unit( Layout.slideWidth( Slide.index ) ),\r\n\t\t\t\theight: Slide.container ? null : slideHeight,\r\n\t\t\t} );\r\n\t\t} );\r\n\r\n\t\tSplide.emit( 'resized' );\r\n\t}\r\n\r\n\treturn Layout;\r\n}","/**\r\n * The component for supporting mouse drag and swipe.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { FADE, SLIDE } from '../../constants/types';\r\nimport { TTB } from '../../constants/directions';\r\nimport { MOVING } from '../../constants/states';\r\nimport { between } from '../../utils/utils';\r\nimport { each } from \"../../utils/object\";\r\n\r\nconst { abs } = Math;\r\n\r\n/**\r\n * If the absolute velocity is greater thant this value,\r\n * a slider always goes to a different slide after drag, not allowed to stay on a current slide.\r\n */\r\nconst MIN_VELOCITY = 0.1;\r\n\r\n/**\r\n * Adjust how much the track can be pulled on the first or last page.\r\n * The larger number this is, the farther the track moves.\r\n * This should be around 5 - 9.\r\n *\r\n * @type {number}\r\n */\r\nconst FRICTION_REDUCER = 7;\r\n\r\n\r\n/**\r\n * The component supporting mouse drag and swipe.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Store the Move component.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Track = Components.Track;\r\n\r\n\t/**\r\n\t * Store the Controller component.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Controller = Components.Controller;\r\n\r\n\t/**\r\n\t * Coordinate of the track on starting drag.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tlet startCoord;\r\n\r\n\t/**\r\n\t * Analyzed info on starting drag.\r\n\t *\r\n\t * @type {Object|null}\r\n\t */\r\n\tlet startInfo;\r\n\r\n\t/**\r\n\t * Analyzed info being updated while dragging/swiping.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tlet currentInfo;\r\n\r\n\t/**\r\n\t * Determine whether slides are being dragged or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tlet isDragging;\r\n\r\n\t/**\r\n\t * Whether the slider direction is vertical or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tconst isVertical = Splide.options.direction === TTB;\r\n\r\n\t/**\r\n\t * Axis for the direction.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst axis = isVertical ? 'y' : 'x';\r\n\r\n\t/**\r\n\t * Drag component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Drag = {\r\n\t\t/**\r\n\t\t * Whether dragging is disabled or not.\r\n\t\t *\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\tdisabled: false,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tconst Elements = Components.Elements;\r\n\t\t\tconst track = Elements.track;\r\n\r\n\t\t\tSplide\r\n\t\t\t\t.on( 'touchstart mousedown', start, track )\r\n\t\t\t\t.on( 'touchmove mousemove', move, track, { passive: false } )\r\n\t\t\t\t.on( 'touchend touchcancel mouseleave mouseup dragend', end, track )\r\n\t\t\t\t.on( 'mounted refresh', () => {\r\n\t\t\t\t\t// Prevent dragging an image or anchor itself.\r\n\t\t\t\t\teach( Elements.list.querySelectorAll( 'img, a' ), elm => {\r\n\t\t\t\t\t\tSplide\r\n\t\t\t\t\t\t\t.off( 'dragstart', elm )\r\n\t\t\t\t\t\t\t.on( 'dragstart', e => { e.preventDefault() }, elm, { passive: false } );\r\n\t\t\t\t\t} );\r\n\t\t\t\t} )\r\n\t\t\t\t.on( 'mounted updated', () => {\r\n\t\t\t\t\tthis.disabled = ! Splide.options.drag;\r\n\t\t\t\t} );\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Called when the track starts to be dragged.\r\n\t *\r\n\t * @param {TouchEvent|MouseEvent} e - TouchEvent or MouseEvent object.\r\n\t */\r\n\tfunction start( e ) {\r\n\t\tif ( ! Drag.disabled && ! isDragging ) {\r\n\t\t\t// These prams are used to evaluate whether the slider should start moving.\r\n\t\t\tinit( e );\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Initialize parameters.\r\n\t *\r\n\t * @param {TouchEvent|MouseEvent} e - TouchEvent or MouseEvent object.\r\n\t */\r\n\tfunction init( e ) {\r\n\t\tstartCoord = Track.toCoord( Track.position );\r\n\t\tstartInfo = analyze( e, {} );\r\n\t\tcurrentInfo = startInfo;\r\n\t}\r\n\r\n\t/**\r\n\t * Called while the track being dragged.\r\n\t *\r\n\t * @param {TouchEvent|MouseEvent} e - TouchEvent or MouseEvent object.\r\n\t */\r\n\tfunction move( e ) {\r\n\t\tif ( startInfo ) {\r\n\t\t\tcurrentInfo = analyze( e, startInfo );\r\n\r\n\t\t\tif ( isDragging ) {\r\n\t\t\t\tif ( e.cancelable ) {\r\n\t\t\t\t\te.preventDefault();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ( ! Splide.is( FADE ) ) {\r\n\t\t\t\t\tconst position = startCoord[ axis ] + currentInfo.offset[ axis ];\r\n\t\t\t\t\tTrack.translate( resist( position ) );\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif ( shouldMove( currentInfo ) ) {\r\n\t\t\t\t\tSplide.emit( 'drag', startInfo );\r\n\t\t\t\t\tisDragging = true;\r\n\t\t\t\t\tTrack.cancel();\r\n\r\n\t\t\t\t\t// These params are actual drag data.\r\n\t\t\t\t\tinit( e );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Determine whether to start moving the track or not by drag angle.\r\n\t *\r\n\t * @param {Object} info - An information object.\r\n\t *\r\n\t * @return {boolean} - True if the track should be moved or false if not.\r\n\t */\r\n\tfunction shouldMove( { offset } ) {\r\n\t\tif ( Splide.State.is( MOVING ) && Splide.options.waitForTransition ) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tlet angle = Math.atan( abs( offset.y ) / abs( offset.x ) ) * 180 / Math.PI;\r\n\r\n\t\tif ( isVertical ) {\r\n\t\t\tangle = 90 - angle;\r\n\t\t}\r\n\r\n\t\treturn angle < Splide.options.dragAngleThreshold;\r\n\t}\r\n\r\n\t/**\r\n\t * Resist dragging the track on the first/last page because there is no more.\r\n\t *\r\n\t * @param {number} position - A position being applied to the track.\r\n\t *\r\n\t * @return {Object} - Adjusted position.\r\n\t */\r\n\tfunction resist( position ) {\r\n\t\tif ( Splide.is( SLIDE ) ) {\r\n\t\t\tconst sign = Track.sign;\r\n\t\t\tconst start = sign * Track.trim( Track.toPosition( 0 ) );\r\n\t\t\tconst end = sign * Track.trim( Track.toPosition( Controller.edgeIndex ) );\r\n\r\n\t\t\tposition *= sign;\r\n\r\n\t\t\tif ( position < start ) {\r\n\t\t\t\tposition = start - FRICTION_REDUCER * Math.log( start - position );\r\n\t\t\t}\telse if ( position > end ) {\r\n\t\t\t\tposition = end + FRICTION_REDUCER * Math.log( position - end );\r\n\t\t\t}\r\n\r\n\t\t\tposition *= sign;\r\n\t\t}\r\n\r\n\t\treturn position;\r\n\t}\r\n\r\n\t/**\r\n\t * Called when dragging ends.\r\n\t */\r\n\tfunction end() {\r\n\t\tstartInfo = null;\r\n\r\n\t\tif ( isDragging ) {\r\n\t\t\tSplide.emit( 'dragged', currentInfo );\r\n\t\t\tgo( currentInfo );\r\n\t\t\tisDragging = false;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Go to the slide determined by the analyzed data.\r\n\t *\r\n\t * @param {Object} info - An info object.\r\n\t */\r\n\tfunction go( info ) {\r\n\t\tconst velocity = info.velocity[ axis ];\r\n\t\tconst absV = abs( velocity );\r\n\r\n\t\tif ( absV > 0 ) {\r\n\t\t\tconst options = Splide.options;\r\n\t\t\tconst index = Splide.index;\r\n\t\t\tconst sign = velocity < 0 ? -1 : 1;\r\n\r\n\t\t\tlet destIndex = index;\r\n\r\n\t\t\tif ( ! Splide.is( FADE ) ) {\r\n\t\t\t\tlet destination = Track.position;\r\n\r\n\t\t\t\tif ( absV > options.flickVelocityThreshold && abs( info.offset[ axis ] ) < options.swipeDistanceThreshold ) {\r\n\t\t\t\t\tdestination += sign * Math.min(\r\n\t\t\t\t\t\tabsV * options.flickPower,\r\n\t\t\t\t\t\tComponents.Layout.size * ( options.flickMaxPages || 1 )\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tdestIndex = Track.toIndex( destination );\r\n\t\t\t}\r\n\r\n\t\t\t/*\r\n\t\t\t * Do not allow the track to go to a previous position if there is enough velocity.\r\n\t\t\t * Always use the adjacent index for the fade mode.\r\n\t\t\t */\r\n\t\t\tif ( destIndex === index && absV > MIN_VELOCITY ) {\r\n\t\t\t\tdestIndex = index + sign * Track.sign;\r\n\t\t\t}\r\n\r\n\t\t\tif ( Splide.is( SLIDE ) ) {\r\n\t\t\t\tdestIndex = between( destIndex, 0, Controller.edgeIndex );\r\n\t\t\t}\r\n\r\n\t\t\tController.go( destIndex, options.isNavigation );\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Analyze the given event object and return important information for handling swipe behavior.\r\n\t *\r\n\t * @param {Event} e - Touch or Mouse event object.\r\n\t * @param {Object} startInfo - Information analyzed on start for calculating difference from the current one.\r\n\t *\r\n\t * @return {Object} - An object containing analyzed information, such as offset, velocity, etc.\r\n\t */\r\n\tfunction analyze( e, startInfo ) {\r\n\t\tconst { timeStamp, touches } = e;\r\n\t\tconst { clientX, clientY } = touches ? touches[0] : e;\r\n\t\tconst { x: fromX = clientX, y: fromY = clientY } = startInfo.to || {};\r\n\r\n\t\tconst startTime = startInfo.time || 0;\r\n\t\tconst offset = { x: clientX - fromX, y: clientY - fromY };\r\n\t\tconst duration = timeStamp - startTime;\r\n\t\tconst velocity = { x: offset.x / duration, y: offset.y / duration };\r\n\r\n\t\treturn {\r\n\t\t\tto: { x: clientX, y: clientY },\r\n\t\t\toffset,\r\n\t\t\ttime: timeStamp,\r\n\t\t\tvelocity,\r\n\t\t};\r\n\t}\r\n\r\n\treturn Drag;\r\n}","/**\r\n * The component for handling a click event.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n\r\n/**\r\n * The component for handling a click event.\r\n * Click should be disabled during drag/swipe.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Whether click is disabled or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tlet disabled = false;\r\n\r\n\t/**\r\n\t * Click component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Click = {\r\n\t\t/**\r\n\t\t * Mount only when the drag is activated and the slide type is not \"fade\".\r\n\t\t *\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\trequired: Splide.options.drag,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tSplide\r\n\t\t\t\t.on( 'click', onClick, Components.Elements.track, { capture: true } )\r\n\t\t\t\t.on( 'drag', () => { disabled = true } )\r\n\t\t\t\t.on( 'dragged', () => {\r\n\t\t\t\t\t// Make sure the flag is released after the click event is fired.\r\n\t\t\t\t\tsetTimeout( () => { disabled = false } );\r\n\t\t\t\t} );\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Called when a track element is clicked.\r\n\t *\r\n\t * @param {Event} e - A click event.\r\n\t */\r\n\tfunction onClick( e ) {\r\n\t\tif ( disabled ) {\r\n\t\t\te.preventDefault();\r\n\t\t\te.stopPropagation();\r\n\t\t\te.stopImmediatePropagation();\r\n\t\t}\r\n\t}\r\n\r\n\treturn Click;\r\n}","/**\r\n * The component for playing slides automatically.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle } from '../../utils/dom';\r\nimport { createInterval } from '../../utils/time';\r\n\r\n/**\r\n * Set of pause flags.\r\n */\r\nconst PAUSE_FLAGS = {\r\n\tHOVER : 1,\r\n\tFOCUS : 2,\r\n\tMANUAL: 3,\r\n};\r\n\r\n\r\n/**\r\n * The component for playing slides automatically.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n * @param {string} name - A component name as a lowercase string.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components, name ) => {\r\n\t/**\r\n\t * Store pause flags.\r\n\t *\r\n\t * @type {Array}\r\n\t */\r\n\tlet flags = [];\r\n\r\n\t/**\r\n\t * Store an interval object.\r\n\t *\r\n\t * @type {Object};\r\n\t */\r\n\tlet interval;\r\n\r\n\t/**\r\n\t * Keep the Elements component.\r\n\t *\r\n\t * @type {string}\r\n\t */\r\n\tconst Elements = Components.Elements;\r\n\r\n\t/**\r\n\t * Autoplay component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Autoplay = {\r\n\t\t/**\r\n\t\t * Required only when the autoplay option is true.\r\n\t\t *\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\trequired: Splide.options.autoplay,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t * Note that autoplay starts only if there are slides over perPage number.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tconst options = Splide.options;\r\n\r\n\t\t\tif ( Elements.slides.length > options.perPage ) {\r\n\t\t\t\tinterval = createInterval( () => { Splide.go( '>' ) }, options.interval, rate => {\r\n\t\t\t\t\tSplide.emit( `${ name }:playing`, rate );\r\n\r\n\t\t\t\t\tif ( Elements.bar ) {\r\n\t\t\t\t\t\tapplyStyle( Elements.bar, { width: `${ rate * 100 }%` } );\r\n\t\t\t\t\t}\r\n\t\t\t\t} );\r\n\r\n\t\t\t\tbind();\r\n\t\t\t\tthis.play();\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Start autoplay.\r\n\t\t *\r\n\t\t * @param {number} flag - A pause flag to be removed.\r\n\t\t */\r\n\t\tplay( flag = 0 ) {\r\n\t\t\tflags = flags.filter( f => f !== flag );\r\n\r\n\t\t\tif ( ! flags.length ) {\r\n\t\t\t\tSplide.emit( `${ name }:play` );\r\n\t\t\t\tinterval.play( Splide.options.resetProgress );\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Pause autoplay.\r\n\t\t * Note that Array.includes is not supported by IE.\r\n\t\t *\r\n\t\t * @param {number} flag - A pause flag to be added.\r\n\t\t */\r\n\t\tpause( flag = 0 ) {\r\n\t\t\tinterval.pause();\r\n\r\n\t\t\tif ( flags.indexOf( flag ) === -1 ) {\r\n\t\t\t\tflags.push( flag );\r\n\t\t\t}\r\n\r\n\t\t\tif ( flags.length === 1 ) {\r\n\t\t\t\tSplide.emit( `${ name }:pause` );\r\n\t\t\t}\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Listen some events.\r\n\t */\r\n\tfunction bind() {\r\n\t\tconst options = Splide.options;\r\n\t\tconst sibling = Splide.sibling;\r\n\t\tconst elms = [ Splide.root, sibling ? sibling.root : null ];\r\n\r\n\t\tif ( options.pauseOnHover ) {\r\n\t\t\tswitchOn( elms, 'mouseleave', PAUSE_FLAGS.HOVER, true );\r\n\t\t\tswitchOn( elms, 'mouseenter', PAUSE_FLAGS.HOVER, false );\r\n\t\t}\r\n\r\n\t\tif ( options.pauseOnFocus ) {\r\n\t\t\tswitchOn( elms, 'focusout', PAUSE_FLAGS.FOCUS, true );\r\n\t\t\tswitchOn( elms, 'focusin', PAUSE_FLAGS.FOCUS, false );\r\n\t\t}\r\n\r\n\t\tif ( Elements.play ) {\r\n\t\t\tSplide.on( 'click', () => {\r\n\t\t\t\t// Need to be removed a focus flag at first.\r\n\t\t\t\tAutoplay.play( PAUSE_FLAGS.FOCUS );\r\n\t\t\t\tAutoplay.play( PAUSE_FLAGS.MANUAL );\r\n\t\t\t}, Elements.play );\r\n\t\t}\r\n\r\n\t\tif ( Elements.pause ) {\r\n\t\t\tswitchOn( [ Elements.pause ], 'click', PAUSE_FLAGS.MANUAL, false );\r\n\t\t}\r\n\r\n\t\tSplide\r\n\t\t\t.on( 'move refresh', () => { Autoplay.play() } ) // Rewind the timer.\r\n\t\t\t.on( 'destroy', () => {\tAutoplay.pause() } );\r\n\t}\r\n\r\n\t/**\r\n\t * Play or pause on the given event.\r\n\t *\r\n\t * @param {Element[]} elms - Elements.\r\n\t * @param {string} event - An event name or names.\r\n\t * @param {number} flag - A pause flag defined on the top.\r\n\t * @param {boolean} play - Determine whether to play or pause.\r\n\t */\r\n\tfunction switchOn( elms, event, flag, play ) {\r\n\t\telms.forEach( elm => {\r\n\t\t\tSplide.on( event, () => { Autoplay[ play ? 'play' : 'pause' ]( flag ) }, elm );\r\n\t\t} );\r\n\t}\r\n\r\n\treturn Autoplay;\r\n}","/**\r\n * The component for change an img element to background image of its wrapper.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { applyStyle, child } from '../../utils/dom';\r\n\r\n\r\n/**\r\n * The component for change an img element to background image of its wrapper.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components ) => {\r\n\t/**\r\n\t * Hold options.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst options = Splide.options;\r\n\r\n\t/**\r\n\t * Cover component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Cover = {\r\n\t\t/**\r\n\t\t * Required only when \"cover\" option is true.\r\n\t\t *\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\trequired: options.cover,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\tSplide.on( 'lazyload:loaded', img => { cover( img, false ) } );\r\n\t\t\tSplide.on( 'mounted updated refresh', () => apply( false ) );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Destroy.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tapply( true );\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Apply \"cover\" to all slides.\r\n\t *\r\n\t * @param {boolean} uncover - If true, \"cover\" will be clear.\r\n\t */\r\n\tfunction apply( uncover ) {\r\n\t\tComponents.Elements.each( Slide => {\r\n\t\t\tconst img = child( Slide.slide, 'IMG' ) || child( Slide.container, 'IMG' );\r\n\r\n\t\t\tif ( img && img.src ) {\r\n\t\t\t\tcover( img, uncover );\r\n\t\t\t}\r\n\t\t} );\r\n\t}\r\n\r\n\t/**\r\n\t * Set background image of the parent element, using source of the given image element.\r\n\t *\r\n\t * @param {Element} img - An image element.\r\n\t * @param {boolean} uncover - Reset \"cover\".\r\n\t */\r\n\tfunction cover( img, uncover ) {\r\n\t\tapplyStyle( img.parentElement, { background: uncover ? '' : `center/cover no-repeat url(\"${ img.src }\")` } );\r\n\t\tapplyStyle( img, { display: uncover ? '' : 'none' } );\r\n\t}\r\n\r\n\treturn Cover;\r\n}","/**\r\n * Export vector path for an arrow.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\n/**\r\n * Namespace definition for SVG element.\r\n *\r\n * @type {string}\r\n */\r\nexport const XML_NAME_SPACE = 'http://www.w3.org/2000/svg';\r\n\r\n/**\r\n * The arrow vector path.\r\n *\r\n * @type {number}\r\n */\r\nexport const PATH = 'm15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z';\r\n\r\n/**\r\n * SVG width and height.\r\n *\r\n * @type {number}\r\n */\r\nexport const SIZE = 40;","/**\r\n * The component for appending prev/next arrows.\r\n *\r\n * @author Naotoshi Fujita\r\n * @copyright Naotoshi Fujita. All rights reserved.\r\n */\r\n\r\nimport { create, append, before, domify, remove, removeAttribute } from '../../utils/dom';\r\nimport { XML_NAME_SPACE, PATH, SIZE } from './path';\r\nimport { LOOP } from \"../../constants/types\";\r\n\r\n\r\n/**\r\n * The component for appending prev/next arrows.\r\n *\r\n * @param {Splide} Splide - A Splide instance.\r\n * @param {Object} Components - An object containing components.\r\n * @param {string} name - A component name as a lowercase string.\r\n *\r\n * @return {Object} - The component object.\r\n */\r\nexport default ( Splide, Components, name ) => {\r\n\t/**\r\n\t * Previous arrow element.\r\n\t *\r\n\t * @type {Element|undefined}\r\n\t */\r\n\tlet prev;\r\n\r\n\t/**\r\n\t * Next arrow element.\r\n\t *\r\n\t * @type {Element|undefined}\r\n\t */\r\n\tlet next;\r\n\r\n\t/**\r\n\t * Store the class list.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst classes = Splide.classes;\r\n\r\n\t/**\r\n\t * Hold the root element.\r\n\t *\r\n\t * @type {Element}\r\n\t */\r\n\tconst root = Splide.root;\r\n\r\n\t/**\r\n\t * Whether arrows are created programmatically or not.\r\n\t *\r\n\t * @type {boolean}\r\n\t */\r\n\tlet created;\r\n\r\n\t/**\r\n\t * Hold the Elements component.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Elements = Components.Elements;\r\n\r\n\t/**\r\n\t * Arrows component object.\r\n\t *\r\n\t * @type {Object}\r\n\t */\r\n\tconst Arrows = {\r\n\t\t/**\r\n\t\t * Required when the arrows option is true.\r\n\t\t *\r\n\t\t * @type {boolean}\r\n\t\t */\r\n\t\trequired: Splide.options.arrows,\r\n\r\n\t\t/**\r\n\t\t * Called when the component is mounted.\r\n\t\t */\r\n\t\tmount() {\r\n\t\t\t// Attempt to get arrows from HTML source.\r\n\t\t\tprev = Elements.arrows.prev;\r\n\t\t\tnext = Elements.arrows.next;\r\n\r\n\t\t\t// If arrows were not found in HTML, let's generate them.\r\n\t\t\tif ( ( ! prev || ! next ) && Splide.options.arrows ) {\r\n\t\t\t\tprev = createArrow( true );\r\n\t\t\t\tnext = createArrow( false );\r\n\t\t\t\tcreated = true;\r\n\r\n\t\t\t\tappendArrows();\r\n\t\t\t}\r\n\r\n\t\t\tif ( prev && next ) {\r\n\t\t\t\tbind();\r\n\t\t\t}\r\n\r\n\t\t\tthis.arrows = { prev, next };\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Called after all components are mounted.\r\n\t\t */\r\n\t\tmounted() {\r\n\t\t\tSplide.emit( `${ name }:mounted`, prev, next );\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Destroy.\r\n\t\t */\r\n\t\tdestroy() {\r\n\t\t\tremoveAttribute( [ prev, next ], 'disabled' );\r\n\r\n\t\t\tif ( created ) {\r\n\t\t\t\tremove( prev.parentElement );\r\n\t\t\t}\r\n\t\t},\r\n\t};\r\n\r\n\t/**\r\n\t * Listen to native and custom events.\r\n\t */\r\n\tfunction bind() {\r\n\t\tSplide\r\n\t\t\t.on( 'click', () => { Splide.go( '<' ) }, prev )\r\n\t\t\t.on( 'click', () => { Splide.go( '>' ) }, next )\r\n\t\t\t.on( 'mounted move updated refresh', updateDisabled );\r\n\t}\r\n\r\n\t/**\r\n\t * Update a disabled attribute.\r\n\t */\r\n\tfunction updateDisabled() {\r\n\t\tconst { prevIndex, nextIndex } = Components.Controller;\r\n\t\tconst isEnough = Splide.length > Splide.options.perPage || Splide.is( LOOP );\r\n\r\n\t\tprev.disabled = prevIndex < 0 || ! isEnough;\r\n\t\tnext.disabled = nextIndex < 0 || ! isEnough;\r\n\r\n\t\tSplide.emit( `${ name }:updated`, prev, next, prevIndex, nextIndex );\r\n\t}\r\n\r\n\t/**\r\n\t * Create a wrapper element and append arrows.\r\n\t */\r\n\tfunction appendArrows() {\r\n\t\tconst wrapper = create( 'div', { class: classes.arrows } );\r\n\r\n\t\tappend( wrapper, prev );\r\n\t\tappend( wrapper, next );\r\n\r\n\t\tconst slider = Elements.slider;\r\n\t\tconst parent = Splide.options.arrows === 'slider' && slider ? slider : root;\r\n\r\n\t\tbefore( wrapper, parent.firstElementChild );\r\n\t}\r\n\r\n\t/**\r\n\t * Create an arrow element.\r\n\t *\r\n\t * @param {boolean} prev - Determine to create a prev arrow or next arrow.\r\n\t *\r\n\t * @return {Element} - A created arrow element.\r\n\t */\r\n\tfunction createArrow( prev ) {\r\n\t\tconst arrow = `