/**
 * Wp Alpha Core FrameWork
 * Alpha Animated Text Library
 * 
 * @package Wp Alpha Core FrameWork
 * @version 1.0
 */
'use strict';

/**
 * http://animejs.com
 * JavaScript animation engine
 * @version v2.2.0
 * @author Julian Garnier
 * @copyright ©2017 Julian Garnier
 * Released under the MIT license
**/

( function ( root, factory ) {
    if ( typeof define === 'function' && define.amd ) {
        // AMD. Register as an anonymous module.
        define( [], factory );
    } else if ( typeof module === 'object' && module.exports ) {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.anime = factory();
    }
}( this, () => {

    // Defaults

    const defaultInstanceSettings = {
        update: undefined,
        begin: undefined,
        run: undefined,
        complete: undefined,
        loop: 1,
        direction: 'normal',
        autoplay: true,
        offset: 0
    }

    const defaultTweenSettings = {
        duration: 1000,
        delay: 0,
        easing: 'easeOutElastic',
        elasticity: 500,
        round: 0
    }

    const validTransforms = [ 'translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skewX', 'skewY', 'perspective' ];
    let transformString;

    // Utils

    function stringContains( str, text ) {
        return str.indexOf( text ) > -1;
    }

    const is = {
        arr: a => Array.isArray( a ),
        obj: a => stringContains( Object.prototype.toString.call( a ), 'Object' ),
        pth: a => is.obj( a ) && a.hasOwnProperty( 'totalLength' ),
        svg: a => a instanceof SVGElement,
        dom: a => a.nodeType || is.svg( a ),
        str: a => typeof a === 'string',
        fnc: a => typeof a === 'function',
        und: a => typeof a === 'undefined',
        hex: a => /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test( a ),
        rgb: a => /^rgb/.test( a ),
        hsl: a => /^hsl/.test( a ),
        col: a => ( is.hex( a ) || is.rgb( a ) || is.hsl( a ) )
    }

    // BezierEasing https://github.com/gre/bezier-easing

    const bezier = ( () => {

        const kSplineTableSize = 11;
        const kSampleStepSize = 1.0 / ( kSplineTableSize - 1.0 );

        function A( aA1, aA2 ) { return 1.0 - 3.0 * aA2 + 3.0 * aA1 };
        function B( aA1, aA2 ) { return 3.0 * aA2 - 6.0 * aA1 };
        function C( aA1 ) { return 3.0 * aA1 };

        function calcBezier( aT, aA1, aA2 ) { return ( ( A( aA1, aA2 ) * aT + B( aA1, aA2 ) ) * aT + C( aA1 ) ) * aT };
        function getSlope( aT, aA1, aA2 ) { return 3.0 * A( aA1, aA2 ) * aT * aT + 2.0 * B( aA1, aA2 ) * aT + C( aA1 ) };

        function binarySubdivide( aX, aA, aB, mX1, mX2 ) {
            let currentX, currentT, i = 0;
            do {
                currentT = aA + ( aB - aA ) / 2.0;
                currentX = calcBezier( currentT, mX1, mX2 ) - aX;
                if ( currentX > 0.0 ) { aB = currentT } else { aA = currentT };
            } while ( Math.abs( currentX ) > 0.0000001 && ++i < 10 );
            return currentT;
        }

        function newtonRaphsonIterate( aX, aGuessT, mX1, mX2 ) {
            for ( let i = 0; i < 4; ++i ) {
                const currentSlope = getSlope( aGuessT, mX1, mX2 );
                if ( currentSlope === 0.0 ) return aGuessT;
                const currentX = calcBezier( aGuessT, mX1, mX2 ) - aX;
                aGuessT -= currentX / currentSlope;
            }
            return aGuessT;
        }

        function bezier( mX1, mY1, mX2, mY2 ) {

            if ( !( 0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1 ) ) return;
            let sampleValues = new Float32Array( kSplineTableSize );

            if ( mX1 !== mY1 || mX2 !== mY2 ) {
                for ( let i = 0; i < kSplineTableSize; ++i ) {
                    sampleValues[ i ] = calcBezier( i * kSampleStepSize, mX1, mX2 );
                }
            }

            function getTForX( aX ) {

                let intervalStart = 0.0;
                let currentSample = 1;
                const lastSample = kSplineTableSize - 1;

                for ( ; currentSample !== lastSample && sampleValues[ currentSample ] <= aX; ++currentSample ) {
                    intervalStart += kSampleStepSize;
                }

                --currentSample;

                const dist = ( aX - sampleValues[ currentSample ] ) / ( sampleValues[ currentSample + 1 ] - sampleValues[ currentSample ] );
                const guessForT = intervalStart + dist * kSampleStepSize;
                const initialSlope = getSlope( guessForT, mX1, mX2 );

                if ( initialSlope >= 0.001 ) {
                    return newtonRaphsonIterate( aX, guessForT, mX1, mX2 );
                } else if ( initialSlope === 0.0 ) {
                    return guessForT;
                } else {
                    return binarySubdivide( aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2 );
                }

            }

            return x => {
                if ( mX1 === mY1 && mX2 === mY2 ) return x;
                if ( x === 0 ) return 0;
                if ( x === 1 ) return 1;
                return calcBezier( getTForX( x ), mY1, mY2 );
            }

        }

        return bezier;

    } )();

    const easings = ( () => {

        const names = [ 'Quad', 'Cubic', 'Quart', 'Quint', 'Sine', 'Expo', 'Circ', 'Back', 'Elastic' ];

        // Elastic easing adapted from jQueryUI http://api.jqueryui.com/easings/

        function elastic( t, p ) {
            return t === 0 || t === 1 ? t :
                -Math.pow( 2, 10 * ( t - 1 ) ) * Math.sin( ( ( ( t - 1 ) - ( p / ( Math.PI * 2.0 ) * Math.asin( 1 ) ) ) * ( Math.PI * 2 ) ) / p );
        }

        // Approximated Penner equations http://matthewlein.com/ceaser/

        const equations = {
            In: [
                [ 0.550, 0.085, 0.680, 0.530 ], /* InQuad */
                [ 0.550, 0.055, 0.675, 0.190 ], /* InCubic */
                [ 0.895, 0.030, 0.685, 0.220 ], /* InQuart */
                [ 0.755, 0.050, 0.855, 0.060 ], /* InQuint */
                [ 0.470, 0.000, 0.745, 0.715 ], /* InSine */
                [ 0.950, 0.050, 0.795, 0.035 ], /* InExpo */
                [ 0.600, 0.040, 0.980, 0.335 ], /* InCirc */
                [ 0.600, -0.280, 0.735, 0.045 ], /* InBack */
                elastic /* InElastic */
            ], Out: [
                [ 0.250, 0.460, 0.450, 0.940 ], /* OutQuad */
                [ 0.215, 0.610, 0.355, 1.000 ], /* OutCubic */
                [ 0.165, 0.840, 0.440, 1.000 ], /* OutQuart */
                [ 0.230, 1.000, 0.320, 1.000 ], /* OutQuint */
                [ 0.390, 0.575, 0.565, 1.000 ], /* OutSine */
                [ 0.190, 1.000, 0.220, 1.000 ], /* OutExpo */
                [ 0.075, 0.820, 0.165, 1.000 ], /* OutCirc */
                [ 0.175, 0.885, 0.320, 1.275 ], /* OutBack */
                ( t, f ) => 1 - elastic( 1 - t, f ) /* OutElastic */
            ], InOut: [
                [ 0.455, 0.030, 0.515, 0.955 ], /* InOutQuad */
                [ 0.645, 0.045, 0.355, 1.000 ], /* InOutCubic */
                [ 0.770, 0.000, 0.175, 1.000 ], /* InOutQuart */
                [ 0.860, 0.000, 0.070, 1.000 ], /* InOutQuint */
                [ 0.445, 0.050, 0.550, 0.950 ], /* InOutSine */
                [ 1.000, 0.000, 0.000, 1.000 ], /* InOutExpo */
                [ 0.785, 0.135, 0.150, 0.860 ], /* InOutCirc */
                [ 0.680, -0.550, 0.265, 1.550 ], /* InOutBack */
                ( t, f ) => t < .5 ? elastic( t * 2, f ) / 2 : 1 - elastic( t * -2 + 2, f ) / 2 /* InOutElastic */
            ]
        }

        let functions = {
            linear: bezier( 0.250, 0.250, 0.750, 0.750 )
        }

        for ( let type in equations ) {
            equations[ type ].forEach( ( f, i ) => {
                functions[ 'ease' + type + names[ i ] ] = is.fnc( f ) ? f : bezier.apply( this, f );
            } );
        }

        return functions;

    } )();

    // Strings

    function stringToHyphens( str ) {
        return str.replace( /([a-z])([A-Z])/g, '$1-$2' ).toLowerCase();
    }

    function selectString( str ) {
        if ( is.col( str ) ) return;
        try {
            let nodes = document.querySelectorAll( str );
            return nodes;
        } catch ( e ) {
            return;
        }
    }

    // Arrays

    function filterArray( arr, callback ) {
        const len = arr.length;
        const thisArg = arguments.length >= 2 ? arguments[ 1 ] : void 0;
        let result = [];
        for ( let i = 0; i < len; i++ ) {
            if ( i in arr ) {
                const val = arr[ i ];
                if ( callback.call( thisArg, val, i, arr ) ) {
                    result.push( val );
                }
            }
        }
        return result;
    }

    function flattenArray( arr ) {
        return arr.reduce( ( a, b ) => a.concat( is.arr( b ) ? flattenArray( b ) : b ), [] );
    }

    function toArray( o ) {
        if ( is.arr( o ) ) return o;
        if ( is.str( o ) ) o = selectString( o ) || o;
        if ( o instanceof NodeList || o instanceof HTMLCollection ) return [].slice.call( o );
        return [ o ];
    }

    function arrayContains( arr, val ) {
        return arr.some( a => a === val );
    }

    // Objects

    function cloneObject( o ) {
        let clone = {};
        for ( let p in o ) clone[ p ] = o[ p ];
        return clone;
    }

    function replaceObjectProps( o1, o2 ) {
        let o = cloneObject( o1 );
        for ( let p in o1 ) o[ p ] = o2.hasOwnProperty( p ) ? o2[ p ] : o1[ p ];
        return o;
    }

    function mergeObjects( o1, o2 ) {
        let o = cloneObject( o1 );
        for ( let p in o2 ) o[ p ] = is.und( o1[ p ] ) ? o2[ p ] : o1[ p ];
        return o;
    }

    // Colors

    function rgbToRgba( rgbValue ) {
        const rgb = /rgb\((\d+,\s*[\d]+,\s*[\d]+)\)/g.exec( rgbValue );
        return rgb ? `rgba(${ rgb[ 1 ] },1)` : rgbValue;
    }

    function hexToRgba( hexValue ) {
        const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
        const hex = hexValue.replace( rgx, ( m, r, g, b ) => r + r + g + g + b + b );
        const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( hex );
        const r = parseInt( rgb[ 1 ], 16 );
        const g = parseInt( rgb[ 2 ], 16 );
        const b = parseInt( rgb[ 3 ], 16 );
        return `rgba(${ r },${ g },${ b },1)`;
    }

    function hslToRgba( hslValue ) {
        const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec( hslValue ) || /hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec( hslValue );
        const h = parseInt( hsl[ 1 ] ) / 360;
        const s = parseInt( hsl[ 2 ] ) / 100;
        const l = parseInt( hsl[ 3 ] ) / 100;
        const a = hsl[ 4 ] || 1;
        function hue2rgb( p, q, t ) {
            if ( t < 0 ) t += 1;
            if ( t > 1 ) t -= 1;
            if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
            if ( t < 1 / 2 ) return q;
            if ( t < 2 / 3 ) return p + ( q - p ) * ( 2 / 3 - t ) * 6;
            return p;
        }
        let r, g, b;
        if ( s == 0 ) {
            r = g = b = l;
        } else {
            const q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s;
            const p = 2 * l - q;
            r = hue2rgb( p, q, h + 1 / 3 );
            g = hue2rgb( p, q, h );
            b = hue2rgb( p, q, h - 1 / 3 );
        }
        return `rgba(${ r * 255 },${ g * 255 },${ b * 255 },${ a })`;
    }

    function colorToRgb( val ) {
        if ( is.rgb( val ) ) return rgbToRgba( val );
        if ( is.hex( val ) ) return hexToRgba( val );
        if ( is.hsl( val ) ) return hslToRgba( val );
    }

    // Units

    function getUnit( val ) {
        const split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec( val );
        if ( split ) return split[ 2 ];
    }

    function getTransformUnit( propName ) {
        if ( stringContains( propName, 'translate' ) || propName === 'perspective' ) return 'px';
        if ( stringContains( propName, 'rotate' ) || stringContains( propName, 'skew' ) ) return 'deg';
    }

    // Values

    function minMaxValue( val, min, max ) {
        return Math.min( Math.max( val, min ), max );
    }

    function getFunctionValue( val, animatable ) {
        if ( !is.fnc( val ) ) return val;
        return val( animatable.target, animatable.id, animatable.total );
    }

    function getCSSValue( el, prop ) {
        if ( prop in el.style ) {
            return getComputedStyle( el ).getPropertyValue( stringToHyphens( prop ) ) || '0';
        }
    }

    function getAnimationType( el, prop ) {
        if ( is.dom( el ) && arrayContains( validTransforms, prop ) ) return 'transform';
        if ( is.dom( el ) && ( el.getAttribute( prop ) || ( is.svg( el ) && el[ prop ] ) ) ) return 'attribute';
        if ( is.dom( el ) && ( prop !== 'transform' && getCSSValue( el, prop ) ) ) return 'css';
        if ( el[ prop ] != null ) return 'object';
    }

    function getTransformValue( el, propName ) {
        const defaultUnit = getTransformUnit( propName );
        const defaultVal = stringContains( propName, 'scale' ) ? 1 : 0 + defaultUnit;
        const str = el.style.transform;
        if ( !str ) return defaultVal;
        let match = [];
        let props = [];
        let values = [];
        const rgx = /(\w+)\((.+?)\)/g;
        while ( match = rgx.exec( str ) ) {
            props.push( match[ 1 ] );
            values.push( match[ 2 ] );
        }
        const value = filterArray( values, ( val, i ) => props[ i ] === propName );
        return value.length ? value[ 0 ] : defaultVal;
    }

    function getOriginalTargetValue( target, propName ) {
        switch ( getAnimationType( target, propName ) ) {
            case 'transform': return getTransformValue( target, propName );
            case 'css': return getCSSValue( target, propName );
            case 'attribute': return target.getAttribute( propName );
        }
        return target[ propName ] || 0;
    }

    function getRelativeValue( to, from ) {
        const operator = /^(\*=|\+=|-=)/.exec( to );
        if ( !operator ) return to;
        const u = getUnit( to ) || 0;
        const x = parseFloat( from );
        const y = parseFloat( to.replace( operator[ 0 ], '' ) );
        switch ( operator[ 0 ][ 0 ] ) {
            case '+': return x + y + u;
            case '-': return x - y + u;
            case '*': return x * y + u;
        }
    }

    function validateValue( val, unit ) {
        if ( is.col( val ) ) return colorToRgb( val );
        const originalUnit = getUnit( val );
        const unitLess = originalUnit ? val.substr( 0, val.length - originalUnit.length ) : val;
        return unit && !/\s/g.test( val ) ? unitLess + unit : unitLess;
    }

    // getTotalLength() equivalent for circle, rect, polyline, polygon and line shapes. 
    // adapted from https://gist.github.com/SebLambla/3e0550c496c236709744

    function getDistance( p1, p2 ) {
        return Math.sqrt( Math.pow( p2.x - p1.x, 2 ) + Math.pow( p2.y - p1.y, 2 ) );
    }

    function getCircleLength( el ) {
        return 2 * Math.PI * el.getAttribute( 'r' );
    }

    function getRectLength( el ) {
        return ( el.getAttribute( 'width' ) * 2 ) + ( el.getAttribute( 'height' ) * 2 );
    }

    function getLineLength( el ) {
        return getDistance(
            { x: el.getAttribute( 'x1' ), y: el.getAttribute( 'y1' ) },
            { x: el.getAttribute( 'x2' ), y: el.getAttribute( 'y2' ) }
        );
    }

    function getPolylineLength( el ) {
        const points = el.points;
        let totalLength = 0;
        let previousPos;
        for ( let i = 0; i < points.numberOfItems; i++ ) {
            const currentPos = points.getItem( i );
            if ( i > 0 ) totalLength += getDistance( previousPos, currentPos );
            previousPos = currentPos;
        }
        return totalLength;
    }

    function getPolygonLength( el ) {
        const points = el.points;
        return getPolylineLength( el ) + getDistance( points.getItem( points.numberOfItems - 1 ), points.getItem( 0 ) );
    }

    // Path animation

    function getTotalLength( el ) {
        if ( el.getTotalLength ) return el.getTotalLength();
        switch ( el.tagName.toLowerCase() ) {
            case 'circle': return getCircleLength( el );
            case 'rect': return getRectLength( el );
            case 'line': return getLineLength( el );
            case 'polyline': return getPolylineLength( el );
            case 'polygon': return getPolygonLength( el );
        }
    }

    function setDashoffset( el ) {
        const pathLength = getTotalLength( el );
        el.setAttribute( 'stroke-dasharray', pathLength );
        return pathLength;
    }

    // Motion path

    function getPath( path, percent ) {
        const el = is.str( path ) ? selectString( path )[ 0 ] : path;
        const p = percent || 100;
        return function ( prop ) {
            return {
                el: el,
                property: prop,
                totalLength: getTotalLength( el ) * ( p / 100 )
            }
        }
    }

    function getPathProgress( path, progress ) {
        function point( offset = 0 ) {
            const l = progress + offset >= 1 ? progress + offset : 0;
            return path.el.getPointAtLength( l );
        }
        const p = point();
        const p0 = point( -1 );
        const p1 = point( +1 );
        switch ( path.property ) {
            case 'x': return p.x;
            case 'y': return p.y;
            case 'angle': return Math.atan2( p1.y - p0.y, p1.x - p0.x ) * 180 / Math.PI;
        }
    }

    // Decompose value

    function decomposeValue( val, unit ) {
        const rgx = /-?\d*\.?\d+/g;
        const value = validateValue( ( is.pth( val ) ? val.totalLength : val ), unit ) + '';
        return {
            original: value,
            numbers: value.match( rgx ) ? value.match( rgx ).map( Number ) : [ 0 ],
            strings: ( is.str( val ) || unit ) ? value.split( rgx ) : []
        }
    }

    // Animatables

    function parseTargets( targets ) {
        const targetsArray = targets ? ( flattenArray( is.arr( targets ) ? targets.map( toArray ) : toArray( targets ) ) ) : [];
        return filterArray( targetsArray, ( item, pos, self ) => self.indexOf( item ) === pos );
    }

    function getAnimatables( targets ) {
        const parsed = parseTargets( targets );
        return parsed.map( ( t, i ) => {
            return { target: t, id: i, total: parsed.length };
        } );
    }

    // Properties

    function normalizePropertyTweens( prop, tweenSettings ) {
        let settings = cloneObject( tweenSettings );
        if ( is.arr( prop ) ) {
            const l = prop.length;
            const isFromTo = ( l === 2 && !is.obj( prop[ 0 ] ) );
            if ( !isFromTo ) {
                // Duration divided by the number of tweens
                if ( !is.fnc( tweenSettings.duration ) ) settings.duration = tweenSettings.duration / l;
            } else {
                // Transform [from, to] values shorthand to a valid tween value
                prop = { value: prop };
            }
        }
        return toArray( prop ).map( ( v, i ) => {
            // Default delay value should be applied only on the first tween
            const delay = !i ? tweenSettings.delay : 0;
            // Use path object as a tween value
            let obj = is.obj( v ) && !is.pth( v ) ? v : { value: v };
            // Set default delay value
            if ( is.und( obj.delay ) ) obj.delay = delay;
            return obj;
        } ).map( k => mergeObjects( k, settings ) );
    }

    function getProperties( instanceSettings, tweenSettings, params ) {
        let properties = [];
        const settings = mergeObjects( instanceSettings, tweenSettings );
        for ( let p in params ) {
            if ( !settings.hasOwnProperty( p ) && p !== 'targets' ) {
                properties.push( {
                    name: p,
                    offset: settings[ 'offset' ],
                    tweens: normalizePropertyTweens( params[ p ], tweenSettings )
                } );
            }
        }
        return properties;
    }

    // Tweens

    function normalizeTweenValues( tween, animatable ) {
        let t = {};
        for ( let p in tween ) {
            let value = getFunctionValue( tween[ p ], animatable );
            if ( is.arr( value ) ) {
                value = value.map( v => getFunctionValue( v, animatable ) );
                if ( value.length === 1 ) value = value[ 0 ];
            }
            t[ p ] = value;
        }
        t.duration = parseFloat( t.duration );
        t.delay = parseFloat( t.delay );
        return t;
    }

    function normalizeEasing( val ) {
        return is.arr( val ) ? bezier.apply( this, val ) : easings[ val ];
    }

    function normalizeTweens( prop, animatable ) {
        let previousTween;
        return prop.tweens.map( t => {
            let tween = normalizeTweenValues( t, animatable );
            const tweenValue = tween.value;
            const originalValue = getOriginalTargetValue( animatable.target, prop.name );
            const previousValue = previousTween ? previousTween.to.original : originalValue;
            const from = is.arr( tweenValue ) ? tweenValue[ 0 ] : previousValue;
            const to = getRelativeValue( is.arr( tweenValue ) ? tweenValue[ 1 ] : tweenValue, from );
            const unit = getUnit( to ) || getUnit( from ) || getUnit( originalValue );
            tween.from = decomposeValue( from, unit );
            tween.to = decomposeValue( to, unit );
            tween.start = previousTween ? previousTween.end : prop.offset;
            tween.end = tween.start + tween.delay + tween.duration;
            tween.easing = normalizeEasing( tween.easing );
            tween.elasticity = ( 1000 - minMaxValue( tween.elasticity, 1, 999 ) ) / 1000;
            tween.isPath = is.pth( tweenValue );
            tween.isColor = is.col( tween.from.original );
            if ( tween.isColor ) tween.round = 1;
            previousTween = tween;
            return tween;
        } );
    }

    // Tween progress

    const setTweenProgress = {
        css: ( t, p, v ) => t.style[ p ] = v,
        attribute: ( t, p, v ) => t.setAttribute( p, v ),
        object: ( t, p, v ) => t[ p ] = v,
        transform: ( t, p, v, transforms, id ) => {
            if ( !transforms[ id ] ) transforms[ id ] = [];
            transforms[ id ].push( `${ p }(${ v })` );
        }
    }

    // Animations

    function createAnimation( animatable, prop ) {
        const animType = getAnimationType( animatable.target, prop.name );
        if ( animType ) {
            const tweens = normalizeTweens( prop, animatable );
            return {
                type: animType,
                property: prop.name,
                animatable: animatable,
                tweens: tweens,
                duration: tweens[ tweens.length - 1 ].end,
                delay: tweens[ 0 ].delay
            }
        }
    }

    function getAnimations( animatables, properties ) {
        return filterArray( flattenArray( animatables.map( animatable => {
            return properties.map( prop => {
                return createAnimation( animatable, prop );
            } );
        } ) ), a => !is.und( a ) );
    }

    // Create Instance

    function getInstanceTimings( type, animations, instanceSettings, tweenSettings ) {
        const isDelay = ( type === 'delay' );
        if ( animations.length ) {
            return ( isDelay ? Math.min : Math.max ).apply( Math, animations.map( anim => anim[ type ] ) );
        } else {
            return isDelay ? tweenSettings.delay : instanceSettings.offset + tweenSettings.delay + tweenSettings.duration;
        }
    }

    function createNewInstance( params ) {
        const instanceSettings = replaceObjectProps( defaultInstanceSettings, params );
        const tweenSettings = replaceObjectProps( defaultTweenSettings, params );
        const animatables = getAnimatables( params.targets );
        const properties = getProperties( instanceSettings, tweenSettings, params );
        const animations = getAnimations( animatables, properties );
        return mergeObjects( instanceSettings, {
            children: [],
            animatables: animatables,
            animations: animations,
            duration: getInstanceTimings( 'duration', animations, instanceSettings, tweenSettings ),
            delay: getInstanceTimings( 'delay', animations, instanceSettings, tweenSettings )
        } );
    }

    // Core

    let activeInstances = [];
    let raf = 0;

    const engine = ( () => {
        function play() { raf = requestAnimationFrame( step ); };
        function step( t ) {
            const activeLength = activeInstances.length;
            if ( activeLength ) {
                let i = 0;
                while ( i < activeLength ) {
                    if ( activeInstances[ i ] ) activeInstances[ i ].tick( t );
                    i++;
                }
                play();
            } else {
                cancelAnimationFrame( raf );
                raf = 0;
            }
        }
        return play;
    } )();


    // Public Instance

    function anime( params = {} ) {

        let now, startTime, lastTime = 0;

        let resolve = null;

        function makePromise() {
            return window.Promise && new Promise( _resolve => resolve = _resolve );
        }

        let promise = makePromise();

        let instance = createNewInstance( params );

        function toggleInstanceDirection() {
            instance.reversed = !instance.reversed;
        }

        function adjustTime( time ) {
            return instance.reversed ? instance.duration - time : time;
        }

        function syncInstanceChildren( time ) {
            const children = instance.children;
            const childrenLength = children.length;
            if ( time >= instance.currentTime ) {
                for ( let i = 0; i < childrenLength; i++ ) children[ i ].seek( time );
            } else {
                for ( let i = childrenLength; i--; ) children[ i ].seek( time );
            }
        }

        function setAnimationsProgress( insTime ) {
            let i = 0;
            let transforms = {};
            const animations = instance.animations;
            const animationsLength = animations.length;
            while ( i < animationsLength ) {
                const anim = animations[ i ];
                const animatable = anim.animatable;
                const tweens = anim.tweens;
                const tweenLength = tweens.length - 1;
                let tween = tweens[ tweenLength ];
                // Only check for keyframes if there is more than one tween
                if ( tweenLength ) tween = filterArray( tweens, t => ( insTime < t.end ) )[ 0 ] || tween;
                const elapsed = minMaxValue( insTime - tween.start - tween.delay, 0, tween.duration ) / tween.duration;
                const eased = isNaN( elapsed ) ? 1 : tween.easing( elapsed, tween.elasticity );
                const strings = tween.to.strings;
                const round = tween.round;
                let numbers = [];
                let progress;
                const toNumbersLength = tween.to.numbers.length;
                for ( let n = 0; n < toNumbersLength; n++ ) {
                    let value;
                    const toNumber = tween.to.numbers[ n ];
                    const fromNumber = tween.from.numbers[ n ];
                    if ( !tween.isPath ) {
                        value = fromNumber + ( eased * ( toNumber - fromNumber ) );
                    } else {
                        value = getPathProgress( tween.value, eased * toNumber );
                    }
                    if ( round ) {
                        if ( !( tween.isColor && n > 2 ) ) {
                            value = Math.round( value * round ) / round;
                        }
                    }
                    numbers.push( value );
                }
                // Manual Array.reduce for better performances
                const stringsLength = strings.length;
                if ( !stringsLength ) {
                    progress = numbers[ 0 ];
                } else {
                    progress = strings[ 0 ];
                    for ( let s = 0; s < stringsLength; s++ ) {
                        const a = strings[ s ];
                        const b = strings[ s + 1 ];
                        const n = numbers[ s ];
                        if ( !isNaN( n ) ) {
                            if ( !b ) {
                                progress += n + ' ';
                            } else {
                                progress += n + b;
                            }
                        }
                    }
                }
                setTweenProgress[ anim.type ]( animatable.target, anim.property, progress, transforms, animatable.id );
                anim.currentValue = progress;
                i++;
            }
            const transformsLength = Object.keys( transforms ).length;
            if ( transformsLength ) {
                for ( let id = 0; id < transformsLength; id++ ) {
                    if ( !transformString ) {
                        const t = 'transform';
                        transformString = ( getCSSValue( document.body, t ) ? t : `-webkit-${ t }` );
                    }
                    instance.animatables[ id ].target.style[ transformString ] = transforms[ id ].join( ' ' );
                }
            }
            instance.currentTime = insTime;
            instance.progress = ( insTime / instance.duration ) * 100;
        }

        function setCallback( cb ) {
            if ( instance[ cb ] ) instance[ cb ]( instance );
        }

        function countIteration() {
            if ( instance.remaining && instance.remaining !== true ) {
                instance.remaining--;
            }
        }

        function setInstanceProgress( engineTime ) {
            const insDuration = instance.duration;
            const insOffset = instance.offset;
            const insStart = insOffset + instance.delay;
            const insCurrentTime = instance.currentTime;
            const insReversed = instance.reversed;
            const insTime = adjustTime( engineTime );
            if ( instance.children.length ) syncInstanceChildren( insTime );
            if ( insTime >= insStart || !insDuration ) {
                if ( !instance.began ) {
                    instance.began = true;
                    setCallback( 'begin' );
                }
                setCallback( 'run' );
            }
            if ( insTime > insOffset && insTime < insDuration ) {
                setAnimationsProgress( insTime );
            } else {
                if ( insTime <= insOffset && insCurrentTime !== 0 ) {
                    setAnimationsProgress( 0 );
                    if ( insReversed ) countIteration();
                }
                if ( ( insTime >= insDuration && insCurrentTime !== insDuration ) || !insDuration ) {
                    setAnimationsProgress( insDuration );
                    if ( !insReversed ) countIteration();
                }
            }
            setCallback( 'update' );
            if ( engineTime >= insDuration ) {
                if ( instance.remaining ) {
                    startTime = now;
                    if ( instance.direction === 'alternate' ) toggleInstanceDirection();
                } else {
                    instance.pause();
                    if ( !instance.completed ) {
                        instance.completed = true;
                        setCallback( 'complete' );
                        if ( 'Promise' in window ) {
                            resolve();
                            promise = makePromise();
                        }
                    }
                }
                lastTime = 0;
            }
        }

        instance.reset = function () {
            const direction = instance.direction;
            const loops = instance.loop;
            instance.currentTime = 0;
            instance.progress = 0;
            instance.paused = true;
            instance.began = false;
            instance.completed = false;
            instance.reversed = direction === 'reverse';
            instance.remaining = direction === 'alternate' && loops === 1 ? 2 : loops;
            setAnimationsProgress( 0 );
            for ( let i = instance.children.length; i--; ) {
                instance.children[ i ].reset();
            }
        }

        instance.tick = function ( t ) {
            now = t;
            if ( !startTime ) startTime = now;
            const engineTime = ( lastTime + now - startTime ) * anime.speed;
            setInstanceProgress( engineTime );
        }

        instance.seek = function ( time ) {
            setInstanceProgress( adjustTime( time ) );
        }

        instance.pause = function () {
            const i = activeInstances.indexOf( instance );
            if ( i > -1 ) activeInstances.splice( i, 1 );
            instance.paused = true;
        }

        instance.play = function () {
            if ( !instance.paused ) return;
            instance.paused = false;
            startTime = 0;
            lastTime = adjustTime( instance.currentTime );
            activeInstances.push( instance );
            if ( !raf ) engine();
        }

        instance.reverse = function () {
            toggleInstanceDirection();
            startTime = 0;
            lastTime = adjustTime( instance.currentTime );
        }

        instance.restart = function () {
            instance.pause();
            instance.reset();
            instance.play();
        }

        instance.finished = promise;

        instance.reset();

        if ( instance.autoplay ) instance.play();

        return instance;

    }

    // Remove targets from animation

    function removeTargets( targets ) {
        const targetsArray = parseTargets( targets );
        for ( let i = activeInstances.length; i--; ) {
            const instance = activeInstances[ i ];
            const animations = instance.animations;
            for ( let a = animations.length; a--; ) {
                if ( arrayContains( targetsArray, animations[ a ].animatable.target ) ) {
                    animations.splice( a, 1 );
                    if ( !animations.length ) instance.pause();
                }
            }
        }
    }

    // Timeline

    function timeline( params ) {
        let tl = anime( params );
        tl.pause();
        tl.duration = 0;
        tl.add = function ( instancesParams ) {
            tl.children.forEach( i => { i.began = true; i.completed = true; } );
            toArray( instancesParams ).forEach( instanceParams => {
                let insParams = mergeObjects( instanceParams, replaceObjectProps( defaultTweenSettings, params || {} ) );
                insParams.targets = insParams.targets || params.targets;
                const tlDuration = tl.duration;
                const insOffset = insParams.offset;
                insParams.autoplay = false;
                insParams.direction = tl.direction;
                insParams.offset = is.und( insOffset ) ? tlDuration : getRelativeValue( insOffset, tlDuration );
                tl.began = true;
                tl.completed = true;
                tl.seek( insParams.offset );
                const ins = anime( insParams );
                ins.began = true;
                ins.completed = true;
                if ( ins.duration > tlDuration ) tl.duration = ins.duration;
                tl.children.push( ins );
            } );
            tl.seek( 0 );
            tl.reset();
            if ( tl.autoplay ) tl.restart();
            return tl;
        }
        return tl;
    }

    anime.version = '2.2.0';
    anime.speed = 1;
    anime.running = activeInstances;
    anime.remove = removeTargets;
    anime.getValue = getOriginalTargetValue;
    anime.path = getPath;
    anime.setDashoffset = setDashoffset;
    anime.bezier = bezier;
    anime.easings = easings;
    anime.timeline = timeline;
    anime.random = ( min, max ) => Math.floor( Math.random() * ( max - min + 1 ) ) + min;

    return anime;

} ) );


/**
 * Alpha Animated Text Library
 * 
 * @package Alpha FrameWork
 * @version 1.0
 */
window.theme = window.theme || {};

( function ( $ ) {

    if ( typeof anime != 'function' ) {
        return;
    }

    /**
     * Run text animation
     * 
     * @param {string} selector 
     */
    theme.animatedText = ( function () {

        function AnimatedText( $el, options ) {
            return this.init( $el, options );
        }

        /**
         * Effects
         */
        AnimatedText.effects = {
            'joke': {
                in: {
                    duration: 1000,
                    delay: function ( el, index ) { return 75 + index * 100; },
                    easing: 'easeOutElastic',
                    elasticity: 650,
                    opacity: {
                        value: [ 0, 1 ],
                        easing: 'easeOutExpo',
                    },
                    translateY: [ '100%', '0%' ]
                },
                out: {
                    duration: 300,
                    delay: function ( el, index ) { return index * 40; },
                    easing: 'easeInOutExpo',
                    opacity: 0,
                    translateY: '-100%'
                }
            },
            'fall': {
                in: {
                    duration: 250,
                    delay: function ( el, index ) { return 200 + index * 25; },
                    easing: 'easeOutCubic',
                    opacity: {
                        value: [ 0, 1 ],
                        easing: 'easeOutExpo',
                    },
                    translateY: [ '-50%', '0%' ]
                },
                out: {
                    duration: 250,
                    delay: function ( el, index ) { return index * 25; },
                    easing: 'easeOutCubic',
                    opacity: 0,
                    translateY: '50%'
                }
            },
            'rotation': {
                in: {
                    duration: 400,
                    delay: function ( el, index ) { return index * 50; },
                    easing: 'easeOutSine',
                    opacity: {
                        value: [ 0, 1 ],
                        easing: 'easeOutExpo',
                    },
                    rotateY: [ -90, 0 ]
                },
                out: {
                    duration: 200,
                    delay: function ( el, index ) { return index * 50; },
                    easing: 'easeOutSine',
                    opacity: 0,
                    rotateY: 45
                }
            },
            'croco': {
                in: {
                    duration: 400,
                    delay: function ( el, index ) { return 200 + index * 30; },
                    easing: 'easeOutExpo',
                    opacity: 1,
                    rotateX: [ 90, 0 ]
                },
                out: {
                    duration: 250,
                    delay: function ( el, index ) { return index * 30; },
                    easing: 'easeOutExpo',
                    opacity: 0,
                    rotateX: -90
                }
            },
            'scaling': {
                in: {
                    duration: 400,
                    delay: function ( el, index ) { return 100 + index * 50; },
                    easing: 'easeOutExpo',
                    opacity: {
                        value: [ 0, 1 ],
                        easing: 'easeOutExpo',
                    },
                    rotateX: [ 110, 0 ]
                },
                out: {
                    duration: 250,
                    delay: function ( el, index ) { return index * 50; },
                    easing: 'easeOutExpo',
                    opacity: 0,
                    rotateX: -110
                }
            },
            'typing': {
                in: {
                    elasticity: false,
                    duration: 1,
                    delay: function ( el, index ) {
                        var delay = index * 100 + anime.random( 50, 100 );

                        return delay;
                    },
                    width: [ 0, function ( el, i ) { return $( el ).width(); } ]
                },
                out: {
                    duration: 1,
                    delay: function ( el, index ) { return ( el.parentNode.children.length - index - 1 ) * 20; },
                    easing: 'linear',
                    width: {
                        value: 0
                    }
                }
            }
        };

        AnimatedText.prototype.init = function ( $el, options ) {

            var self = this;
            self.$el = $el;
            self.$items = $el.children( '.animating-item' );
            self.currentIndex = 0;
            self.settings = $.extend( {
                effect: 'joke',
                delay: 3000
            }, $el.data( 'settings' ) || {}, options || {} );

            self.showText(
                self.$items.eq( self.currentIndex ),
                self.settings.effect,
                null,
                function () {
                    var currentDelay = self.settings.delay;

                    if ( self.timeOut ) {
                        clearTimeout( self.timeOut );
                    }

                    self.timeOut = setTimeout( function () {
                        self.textChange();
                    }, currentDelay );
                }
            );
        }

        AnimatedText.prototype.textChange = function () {
            var self = this,
                $prevText = self.$items.eq( self.currentIndex ),
                $nextText;

            if ( self.currentIndex < self.$items.length - 1 ) {
                ++self.currentIndex;
            } else {
                self.currentIndex = 0;
            }

            $nextText = self.$items.eq( self.currentIndex );

            self.hideText( $prevText, self.settings.effect, null, function ( anime ) {
                $prevText.toggleClass( 'visible' );

                var currentDelay = self.settings.delay;

                if ( self.timeOut ) {
                    clearTimeout( self.timeOut );
                }

                self.showText(
                    $nextText,
                    self.settings.effect,
                    function () {
                        $nextText.toggleClass( 'active' );
                        $prevText.toggleClass( 'active' );

                        $nextText.toggleClass( 'visible' );
                    },
                    function () {
                        self.timeOut = setTimeout( function () {
                            self.textChange();
                        }, currentDelay );
                    }
                );

            } );
        };

        AnimatedText.prototype.showText = function ( $item, effect, beginCallback, completeCallback ) {
            var targets = [];

            $( 'span', $item ).each( function () {
                $( this ).css( {
                    'width': 'auto',
                    'opacity': 1,
                    'WebkitTransform': '',
                    'transform': ''
                } );
                targets.push( this );
            } );

            this.animateText( targets, 'in', effect, beginCallback, completeCallback );
        };

        AnimatedText.prototype.hideText = function ( $item, effect, beginCallback, completeCallback ) {
            var targets = [];

            $( 'span', $item ).each( function () {
                targets.push( this );
            } );

            this.animateText( targets, 'out', effect, beginCallback, completeCallback );
        };

        AnimatedText.prototype.animateText = function ( targets, direction, effect, beginCallback, completeCallback ) {
            var effectSettings = AnimatedText.effects[ effect ] || {};
            anime( $.extend( {
                targets: targets,
                begin: beginCallback,
                complete: completeCallback,
            }, effectSettings[ direction ] ) );
        }

        return function ( selector ) {
            theme.$( selector ).each( function () {
                var $this = $( this );
                $this.data( 'theme-animated-text', new AnimatedText( $this ) );
            } )
        }
    } )();

    $( window ).on( 'alpha_complete', function () {
        theme.animatedText( '.animating-text' );
    } );
} )( jQuery );