Current File : /home/natitnen/elitepathways.com.ng/wp-content/plugins/smoother/js/smoother.js
/**
 * Smoother
 * Smoother - Smooth scrolling experience for WordPress Websites.
 * Exclusively on https://1.envato.market/smoother
 *
 * @encoding        UTF-8
 * @version         2.0.3
 * @copyright       (C) 2018 - 2021 Merkulove ( https://merkulov.design/ ). All rights reserved.
 * @license         Envato License https://1.envato.market/KYbje
 * @contributors    Nemirovskiy Vitaliy (nemirovskiyvitaliy@gmail.com), Dmitry Merkulov (dmitry@merkulov.design)
 * @support         help@merkulov.design
 **/

//
// SmoothScroll for websites v1.4.9 (Balazs Galambosi)
// http://www.smoothscroll.net/
//
// Licensed under the terms of the MIT license.
//
// You may use it in your theme if you credit me. 
// It is also free to use on any individual website.
//
// Exception:
// The only restriction is to not publish any  
// extension for browsers or native application
// without getting a written permission first.
//

(function () {

"use strict";
  
const defaultOptions = {

    // Scrolling Core
    frameRate: 150, // [Hz]
    animationTime: 400, // [ms]
    stepSize: 100, // [px]

    // Pulse (less tweakable)
    // ratio of "tail" to "acceleration"
    pulseAlgorithm: true,
    pulseScale: 4,
    pulseNormalize: 1,

    // Acceleration
    accelerationDelta: 50,  // 50
    accelerationMax: 3,   // 3

    // Keyboard Settings
    keyboardSupport: true,  // option
    arrowScroll: 50,    // [px]

    // Other
    fixedBackground: true,
    excluded: ''
};

let options = defaultOptions;


// Other Variables
    const isExcluded = false;
    let isFrame = false;
    const direction = {x: 0, y: 0};
    let initDone = false;
    let root = document.documentElement;
    let activeElement;
    let observer;
    let refreshSize;
    let deltaBuffer = [];
    let deltaBufferTimer;
    const isMac = /^Mac/.test( navigator.platform );
    const isItSafari = (navigator.userAgent.toLowerCase().includes( 'safari' ) && ! navigator.userAgent.toLowerCase().includes( 'chrome' ));
    const isFireFox = navigator.userAgent.toLowerCase().includes( 'firefox' );

    const key = {
        left: 37, up: 38, right: 39, down: 40, spacebar: 32,
        pageup: 33, pagedown: 34, end: 35, home: 36
    };
    const arrowKeys = {37: 1, 38: 1, 39: 1, 40: 1};

    /***********************************************
 * INITIALIZE
 ***********************************************/

/**
 * Tests if smooth scrolling is allowed. Shuts down everything if not.
 */
function initTest() {
    if (options.keyboardSupport) {
        addEvent('keydown', keydown);
    }
}

/**
 * Sets up scrolls array, determines if frames are involved.
 */
function init() {

    if (initDone || !document.body) return;

    initDone = true;

    const body = document.body;
    const html = document.documentElement;
    const windowHeight = window.innerHeight;
    const scrollHeight = body.scrollHeight;

    // check compat mode for root element
    root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
    activeElement = body;
    
    initTest();

    // Checks if this script is running in a frame
    if (top != self) {
        isFrame = true;
    }

    /**
     * Safari 10 fixed it, Chrome fixed it in v45:
     * This fixes a bug where the areas left and right to 
     * the content does not trigger the onmousewheel event
     * on some pages. e.g.: html, body { height: 100% }
     */
    else if (isOldSafari &&
             scrollHeight > windowHeight &&
            (body.offsetHeight <= windowHeight || 
             html.offsetHeight <= windowHeight)) {

        const fullPageElem = document.createElement( 'div' );
        fullPageElem.style.cssText = 'position:absolute; z-index:-10000; ' +
                                     'top:0; left:0; right:0; height:' + 
                                      root.scrollHeight + 'px';
        document.body.appendChild(fullPageElem);
        
        // DOM changed (throttled) to fix height
        let pendingRefresh;
        refreshSize = function () {
            if (pendingRefresh) return; // could also be: clearTimeout(pendingRefresh);
            pendingRefresh = setTimeout(function () {
                if (isExcluded) return; // could be running after cleanup
                fullPageElem.style.height = '0';
                fullPageElem.style.height = root.scrollHeight + 'px';
                pendingRefresh = null;
            }, 500); // act rarely to stay fast
        };
  
        setTimeout(refreshSize, 10);

        addEvent('resize', refreshSize);

        // TODO: attributeFilter?
        const config = {
            attributes: true,
            childList: true,
            characterData: false
            // subtree: true
        };

        observer = new MutationObserver(refreshSize);
        observer.observe(body, config);

        if (root.offsetHeight <= windowHeight) {
            const clearfix = document.createElement( 'div' );
            clearfix.style.clear = 'both';
            body.appendChild(clearfix);
        }
    }

    // disable fixed background
    if (!options.fixedBackground && !isExcluded) {
        body.style.backgroundAttachment = 'scroll';
        html.style.backgroundAttachment = 'scroll';
    }
}

/**
 * Removes event listeners and other traces left on the page.
 */
function cleanup() {
    observer && observer.disconnect();
    removeEvent(wheelEvent, wheel);
    removeEvent('mousedown', mousedown);
    removeEvent('keydown', keydown);
    removeEvent('resize', refreshSize);
    removeEvent('load', init);
}

/**
 * Add event listeners and other traces left on the page.
 */
function restart() {
    observer && observer.observe();
    addEvent(wheelEvent, wheel, { passive: false } );
    addEvent('mousedown', mousedown);
    addEvent('keydown', keydown);
    addEvent('resize', refreshSize);
    addEvent('load', init);
}

    /************************************************
     * SCROLLING
     ************************************************/
    let que = [];
    let pending = false;
    let lastScroll = Date.now();

    /**
 * Pushes scroll actions to the scrolling queue.
 */
function scrollArray( elem, left, top ) {
    
    directionCheck( left, top );

    if (options.accelerationMax !== 1) {
        const now = Date.now();
        const elapsed = now - lastScroll;
        if (elapsed < options.accelerationDelta) {
            let factor = (1 + (50 / elapsed)) / 2;
            if (factor > 1) {
                factor = Math.min(factor, options.accelerationMax);
                left *= factor;
                top  *= factor;
            }
        }
        lastScroll = Date.now();
    }          
    
    // push a scroll command
    que.push({
        x: left, 
        y: top, 
        lastX: (left < 0) ? 0.99 : -0.99,
        lastY: (top  < 0) ? 0.99 : -0.99, 
        start: Date.now()
    });
        
    // don't act if there's a pending queue
    if (pending) {
        return;
    }

    const scrollRoot = getScrollRoot();
    const isWindowScroll = (elem === scrollRoot || elem === document.body);

    // if we haven't already fixed the behavior, 
    // and it needs fixing for this sesh
    if (elem.$scrollBehavior == null && isScrollBehaviorSmooth(elem)) {
        elem.$scrollBehavior = elem.style.scrollBehavior;
        elem.style.scrollBehavior = 'auto';
    }

    const step = function ( time ) {

        const now = Date.now();
        let scrollX = 0;
        let scrollY = 0;

        for ( let i = 0; i < que.length; i++ ) {

            const item = que[i];
            const elapsed = now - item.start;
            const finished = (elapsed >= options.animationTime);

            // scroll position: [0, 1]
            let position = (finished) ? 1 : elapsed / options.animationTime;

            // easing [optional]
            if ( options.pulseAlgorithm ) {
                position = pulse( position );
            }

            // only need the difference
            const x = (item.x * position - item.lastX) >> 0;
            const y = (item.y * position - item.lastY) >> 0;

            // add this to the total scrolling
            scrollX += x;
            scrollY += y;

            // update last values
            item.lastX += x;
            item.lastY += y;

            // delete and step back if it's over
            if ( finished ) {
                que.splice( i, 1 );
                i--;
            }
        }

        // scroll left and top
        if ( isWindowScroll ) {
            window.scrollBy( scrollX, scrollY );
        } else {
            if ( scrollX ) elem.scrollLeft += scrollX;
            if ( scrollY ) elem.scrollTop += scrollY;
        }

        // clean up if there's nothing left to do
        if ( ! left && ! top ) {
            que = [];
        }

        if ( que.length ) {
            requestFrame( step, elem, (1000 / options.frameRate + 1) );
        } else {
            pending = false;
            // restore default behavior at the end of scrolling sesh
            if ( elem.$scrollBehavior != null ) {
                elem.style.scrollBehavior = elem.$scrollBehavior;
                elem.$scrollBehavior = null;
            }
        }
    };

    // start a new queue of actions
    requestFrame(step, elem, 0);
    pending = true;
}


/***********************************************
 * EVENTS
 ***********************************************/

/**
 * Mouse wheel handler.
 * @param {Object} event
 */
function wheel(event) {

    // Disable TouchPad Smooth scrolling
    const isTouchPad = event.wheelDeltaY ? event.wheelDeltaY === -3 * event.deltaY : event.deltaMode === 0;
    if ( isTouchPad ) return;

    if (!initDone) {
        init();
    }

    const target = event.target;

    // leave early if default action is prevented   
    // or it's a zooming event with CTRL 
    if (event.defaultPrevented || event.ctrlKey) {
        return true;
    }
    
    // leave embedded content alone (flash & pdf)
    if (isNodeName(activeElement, 'embed') || 
       (isNodeName(target, 'embed') && /\.pdf/i.test(target.src)) ||
        isNodeName(activeElement, 'object') ||
        target.shadowRoot) {
        return true;
    }

    let deltaX = -event.wheelDeltaX || event.deltaX || 0;
    let deltaY = -event.wheelDeltaY || event.deltaY || 0;

    // Disable macOS wheel acceleration for Safari
    if (isItSafari) {
        deltaY = 10*deltaY;
        if ( Math.abs(deltaY) > 120 ) {
            if ( deltaY > 0 ) {
                deltaY = 120;
            } else {
                deltaY = -120;
            }
        }
    }

    if ( isMac ) {

        if (event.wheelDeltaX && isDivisible(event.wheelDeltaX, 120)) {
            deltaX = -120 * (event.wheelDeltaX / Math.abs(event.wheelDeltaX));
        }
        if (event.wheelDeltaY && isDivisible(event.wheelDeltaY, 120)) {
            deltaY = -120 * (event.wheelDeltaY / Math.abs(event.wheelDeltaY));
        }

    }
    
    // use wheelDelta if deltaX/Y is not available
    if (!deltaX && !deltaY) {
        deltaY = -event.wheelDelta || 0;
    }

    // line based scrolling (Firefox mostly)
    if (event.deltaMode === 1) {
        deltaX *= 40;
        deltaY *= 40;
    }

    const overflowing = overflowingAncestor( target );

    // nothing to do if there's no element that's scrollable
    if (!overflowing) {
        // except Chrome iframes seem to eat wheel events, which we need to 
        // propagate up, if the iframe has nothing overflowing to scroll
        if (isFrame && isChrome)  {
            // change target to iframe element itself for the parent frame
            Object.defineProperty(event, "target", {value: window.frameElement});
            return parent.wheel(event);
        }
        return true;
    }
    
    // check if it's a touchpad scroll that should be ignored
    if ( isTouchpad(deltaY) ) {
        return true;
    }

    // scale by step size
    // delta is 120 most of the time
    // synaptics seems to send 1 sometimes
    if (Math.abs(deltaX) > 1.2) {
        deltaX *= options.stepSize / 120;
    }
    if (Math.abs(deltaY) > 1.2) {
        deltaY *= options.stepSize / 120;
    }
    
    scrollArray(overflowing, deltaX, deltaY);
    event.preventDefault();
    scheduleClearCache();
}

/**
 * Keydown event handler.
 * @param {Object} event
 */
function keydown(event) {

    const target = event.target;
    const modifier = event.ctrlKey || event.altKey || event.metaKey ||
        (event.shiftKey && event.keyCode !== key.spacebar);

    // our own tracked active element could've been removed from the DOM
    if (!document.body.contains(activeElement)) {
        activeElement = document.activeElement;
    }

    // do nothing if user is editing text
    // or using a modifier key (except shift)
    // or in a dropdown
    // or inside interactive elements
    const inputNodeNames = /^(textarea|select|embed|object)$/i;
    const buttonTypes = /^(button|submit|radio|checkbox|file|color|image)$/i;
    if ( event.defaultPrevented ||
         inputNodeNames.test(target.nodeName) ||
         isNodeName(target, 'input') && !buttonTypes.test(target.type) ||
         isNodeName(activeElement, 'video') ||
         isInsideYoutubeVideo(event) ||
         target.isContentEditable || 
         modifier ) {
      return true;
    }

    // [spacebar] should trigger button press, leave it alone
    if ((isNodeName(target, 'button') ||
         isNodeName(target, 'input') && buttonTypes.test(target.type)) &&
        event.keyCode === key.spacebar) {
      return true;
    }

    // [arrwow keys] on radio buttons should be left alone
    if (isNodeName(target, 'input') && target.type == 'radio' &&
        arrowKeys[event.keyCode])  {
      return true;
    }

    let shift, x = 0, y = 0;
    let overflowing = overflowingAncestor( activeElement );

    if (!overflowing) {
        // Chrome iframes seem to eat key events, which we need to 
        // propagate up, if the iframe has nothing overflowing to scroll
        return (isFrame && isChrome) ? parent.keydown(event) : true;
    }

    let clientHeight = overflowing.clientHeight;

    if (overflowing == document.body) {
        clientHeight = window.innerHeight;
    }

    switch (event.keyCode) {
        case key.up:
            y = -options.arrowScroll;
            break;
        case key.down:
            y = options.arrowScroll;
            break;         
        case key.spacebar: // (+ shift)
            shift = event.shiftKey ? 1 : -1;
            y = -shift * clientHeight * 0.9;
            break;
        case key.pageup:
            y = -clientHeight * 0.9;
            break;
        case key.pagedown:
            y = clientHeight * 0.9;
            break;
        case key.home:
            if (overflowing == document.body && document.scrollingElement)
                overflowing = document.scrollingElement;
            y = -overflowing.scrollTop;
            break;
        case key.end:
            const scroll = overflowing.scrollHeight - overflowing.scrollTop;
            const scrollRemaining = scroll - clientHeight;
            y = (scrollRemaining > 0) ? scrollRemaining + 10 : 0;
            break;
        case key.left:
            x = -options.arrowScroll;
            break;
        case key.right:
            x = options.arrowScroll;
            break;            
        default:
            return true; // a key we don't care about
    }

    scrollArray(overflowing, x, y);
    event.preventDefault();
    scheduleClearCache();
}

/**
 * Mousedown event only for updating activeElement
 */
function mousedown(event) {
    activeElement = event.target;
}


    /***********************************************
     * OVERFLOW
     ***********************************************/
    const uniqueID = (function () {
        let i = 0;
        return function ( el ) {
            return el.uniqueID || (el.uniqueID = i++);
        };
    })();

    let cacheX = {}; // cleared out after a scrolling session
    let cacheY = {}; // cleared out after a scrolling session
    let clearCacheTimer;
    let smoothBehaviorForElement = {};

//setInterval(function () { cache = {}; }, 10 * 1000);

function scheduleClearCache() {
    clearTimeout(clearCacheTimer);

    /** Never clean cache for the Scroller */
    if ( typeof document.getElementById( 'scroller-body' ) === "undefined" ) {

        clearCacheTimer = setInterval(function () {
            cacheX = cacheY = smoothBehaviorForElement = {};
        }, 1000);

    }

}

function setCache(elems, overflowing, x) {
    const cache = x ? cacheX : cacheY;
    for ( let i = elems.length; i--;)
        cache[uniqueID(elems[i])] = overflowing;
    return overflowing;
}

function getCache(el, x) {
    return (x ? cacheX : cacheY)[uniqueID(el)];
}

//  (body)                (root)
//         | hidden | visible | scroll |  auto  |
// hidden  |   no   |    no   |   YES  |   YES  |
// visible |   no   |   YES   |   YES  |   YES  |
// scroll  |   no   |   YES   |   YES  |   YES  |
// auto    |   no   |   YES   |   YES  |   YES  |

function overflowingAncestor(el) {
    const elems = [];
    const body = document.body;
    const rootScrollHeight = root.scrollHeight;
    do {
        const cached = getCache( el, false );
        if (cached) {
            return setCache(elems, cached);
        }
        elems.push(el);
        if (rootScrollHeight === el.scrollHeight) {
            const topOverflowsNotHidden = overflowNotHidden( root ) && overflowNotHidden( body );
            const isOverflowCSS = topOverflowsNotHidden || overflowAutoOrScroll( root );
            if (isFrame && isContentOverflowing(root) || 
               !isFrame && isOverflowCSS) {
                return setCache(elems, getScrollRoot()); 
            }
        } else if (isContentOverflowing(el) && overflowAutoOrScroll(el)) {
            return setCache(elems, el);
        }
    } while ((el = el.parentElement));
}

function isContentOverflowing(el) {
    return (el.clientHeight + 10 < el.scrollHeight);
}

// typically for <body> and <html>
function overflowNotHidden(el) {
    const overflow = getComputedStyle( el, '' ).getPropertyValue( 'overflow-y' );
    return (overflow !== 'hidden');
}

// for all other elements
function overflowAutoOrScroll(el) {
    const overflow = getComputedStyle( el, '' ).getPropertyValue( 'overflow-y' );
    return (overflow === 'scroll' || overflow === 'auto');
}

// for all other elements
function isScrollBehaviorSmooth(el) {
    const id = uniqueID( el );
    if (smoothBehaviorForElement[id] == null) {
        const scrollBehavior = getComputedStyle( el, '' )['scroll-behavior'];
        smoothBehaviorForElement[id] = ('smooth' == scrollBehavior);
    }
    return smoothBehaviorForElement[id];
}


/***********************************************
 * HELPERS
 ***********************************************/

function addEvent(type, fn, arg) {

    if ( document.getElementById( 'scroller-body' ) !== null ) {

        /** Add eventListeners for Scroller plugin */
        document.getElementById( 'scroller-body' ).addEventListener(type, fn, arg || false);

    } else {

        /** Add eventListeners */
        window.addEventListener(type, fn, arg || false);

    }

}

function removeEvent(type, fn, arg) {

    if ( document.getElementById( 'scroller-body' ) !== null ) {

        /** Remove eventListeners for Scroller plugin */
        document.getElementById( 'scroller-body' ).addEventListener(type, fn, arg || false);

    } else {

        /** Remove eventListeners */
        window.removeEventListener(type, fn, arg || false);

    }

}

function isNodeName(el, tag) {
    return el && (el.nodeName||'').toLowerCase() === tag.toLowerCase();
}

function directionCheck(x, y) {
    x = (x > 0) ? 1 : -1;
    y = (y > 0) ? 1 : -1;
    if (direction.x !== x || direction.y !== y) {
        direction.x = x;
        direction.y = y;
        que = [];
        lastScroll = 0;
    }
}

if (window.localStorage && localStorage.SS_deltaBuffer) {
    try { // #46 Safari throws in private browsing for localStorage 
        deltaBuffer = localStorage.SS_deltaBuffer.split(',');
    } catch (e) { } 
}

/**
 * Detect touchpad screen
 * @param deltaY
 * @return {boolean}
 */
function isTouchpad( deltaY ) {

    if ( !deltaY ) return;

    if ( !deltaBuffer.length ) {
        deltaBuffer = [deltaY, deltaY, deltaY];
    }

    deltaY = Math.abs(deltaY);
    deltaBuffer.push(deltaY);
    deltaBuffer.shift();
    clearTimeout(deltaBufferTimer);

    deltaBufferTimer = setTimeout( function () {
        try { // #46 Safari throws in private browsing for localStorage
            localStorage.SS_deltaBuffer = deltaBuffer.join( ',' );
        } catch (e) { }  
    }, 1000 );

    const dpiScaledWheelDelta = deltaY > 120 && allDeltasDivisableBy(deltaY); // win64
    let allDeltasDivisableBy100 = allDeltasDivisableBy(100);
    let allDeltasDivisableBy120 = allDeltasDivisableBy(120);
    if ( isFireFox && isMac ) { allDeltasDivisableBy120 = true; } // Firefox MacOS Scrolling Fix.\\

    return !allDeltasDivisableBy120 && !allDeltasDivisableBy100 && !dpiScaledWheelDelta;

} 

function isDivisible(n, divisor) {
    return (Math.floor(n / divisor) == n / divisor);
}

function allDeltasDivisableBy(divisor) {
    return (isDivisible(deltaBuffer[0], divisor) &&
            isDivisible(deltaBuffer[1], divisor) &&
            isDivisible(deltaBuffer[2], divisor));
}

function isInsideYoutubeVideo(event) {
    let elem = event.target;
    let isControl = false;
    if (document.URL.indexOf ('www.youtube.com/watch') != -1) {
        do {
            isControl = (elem.classList && 
                         elem.classList.contains('html5-video-controls'));
            if (isControl) break;
        } while ((elem = elem.parentNode));
    }
    return isControl;
}

var requestFrame = (function () {
      return (window.requestAnimationFrame       || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame    ||
              function (callback, element, delay) {
                 window.setTimeout(callback, delay || (1000/60));
             });
})();

var MutationObserver = (window.MutationObserver || 
                        window.WebKitMutationObserver ||
                        window.MozMutationObserver);  

var getScrollRoot = (function() {
    let SCROLL_ROOT = document.scrollingElement;
    return function() {
    if (!SCROLL_ROOT) {
        const dummy = document.createElement( 'div' );
        dummy.style.cssText = 'height:10000px;width:1px;';
      document.body.appendChild(dummy);
        const bodyScrollTop = document.body.scrollTop;
        const docElScrollTop = document.documentElement.scrollTop;
        window.scrollBy(0, 3);
      if (document.body.scrollTop != bodyScrollTop)
        (SCROLL_ROOT = document.body);
      else 
        (SCROLL_ROOT = document.documentElement);
      window.scrollBy(0, -3);
      document.body.removeChild(dummy);
    }
    return SCROLL_ROOT;
  };
})();


/***********************************************
 * PULSE (by Michael Herf)
 ***********************************************/
 
/**
 * Viscous fluid with a pulse for part and decay for the rest.
 * - Applies a fixed force over an interval (a damped acceleration), and
 * - Lets the exponential bleed away the velocity over a longer interval
 * - Michael Herf, http://stereopsis.com/stopping/
 */
function pulse_(x) {
    let val, start, expx;
    // test
    x = x * options.pulseScale;
    if (x < 1) { // acceleartion
        val = x - (1 - Math.exp(-x));
    } else {     // tail
        // the previous animation ended here:
        start = Math.exp(-1);
        // simple viscous drag
        x -= 1;
        expx = 1 - Math.exp(-x);
        val = start + (expx * (1 - start));
    }
    return val * options.pulseNormalize;
}

function pulse(x) {
    if (x >= 1) return 1;
    if (x <= 0) return 0;

    if (options.pulseNormalize == 1) {
        options.pulseNormalize /= pulse_(1);
    }
    return pulse_(x);
}


/***********************************************
 * FIRST RUN
 ***********************************************/

const userAgent = window.navigator.userAgent;
const isEdge    = /Edge/.test(userAgent); // thank you MS
const isChrome  = /chrome/i.test(userAgent) && !isEdge;
const isSafari  = /safari/i.test(userAgent) && !isEdge;
const isMobile  = /mobile/i.test(userAgent);
const isIEWin7  = /Windows NT 6.1/i.test(userAgent) && /rv:11/i.test(userAgent);
const isOldSafari = isSafari && (/Version\/8/i.test(userAgent) || /Version\/9/i.test(userAgent));
const isEnabledForBrowser = ( isChrome || isSafari || isIEWin7 || window.mdSmootherAllBrowsers ) && !isMobile;

    let supportsPassive = false;
    try {
  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () {
            supportsPassive = true;
        } 
    }));
} catch(e) {}

    const wheelOpt = supportsPassive ? {passive: false} : false;
    var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';

if (wheelEvent && isEnabledForBrowser) {
    addEvent(wheelEvent, wheel, wheelOpt);
    addEvent('mousedown', mousedown);
    addEvent('load', init);
}


/***********************************************
 * PUBLIC INTERFACE
 ***********************************************/

function SmoothScroll(optionsToSet) {

    const { anchor } = optionsToSet;

    /** Smooth scrolling to anchor */
    if ( anchor ) {

        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });

    }

    for ( let key in optionsToSet)
        if (defaultOptions.hasOwnProperty(key))
            options[key] = optionsToSet[key];

}
SmoothScroll.destroy = cleanup;
SmoothScroll.restart = restart;

if (window.SmoothScrollOptions) // async API
    SmoothScroll(window.SmoothScrollOptions);

if (typeof define === 'function' && define.amd)
    define(function() {
        return SmoothScroll;
    });
else if ('object' == typeof exports)
    module.exports = SmoothScroll;
else
    window.SmoothScroll = SmoothScroll;

})();