(function ($) {
    'use strict';

    function magicScrollHandler($scope) {
        var magic_scroll = document.querySelectorAll('.tp-magic-scroll');
        if (!magic_scroll.length) return;

        magic_scroll.forEach(function (self) {

            if (self.dataset.magicScrollProcessing === 'true') {
                return;
            }
            self.dataset.magicScrollProcessing = 'true';

            var getDevice = 'md';
            var deviceMode = window.innerWidth;

            if (deviceMode >= 1024) {
                getDevice = 'md';
            } else if (deviceMode >= 768 && deviceMode < 1024) {
                getDevice = 'sm';
            } else {
                getDevice = 'xs';
            }

            function safeParseJSON(jsonString, fallback) {
                if (!jsonString || typeof jsonString !== 'string') return fallback;
                if (jsonString.trim() === '' || jsonString.trim() === 'undefined') return fallback;
                try {
                    return JSON.parse(jsonString);
                } catch (e) {
                    return fallback;
                }
            }

            var deviceVisibility = [];
            if (self && self.dataset && self.dataset.tpmsMsview) {
                deviceVisibility = safeParseJSON(self.dataset.tpmsMsview, []);
            }

            if (deviceVisibility.length > 0 && !deviceVisibility.includes(getDevice)) {
                return;
            }

            var attr_scroll = [];
            if (self && self.dataset) {
                if (self.dataset.tpmsMs && self.dataset.tpmsMs.trim() !== '' && self.dataset.tpmsMs.trim() !== 'undefined') {
                    attr_scroll = safeParseJSON(self.dataset.tpmsMs, []);
                } else if (self.dataset.tpms && self.dataset.tpms.trim() !== '' && self.dataset.tpms.trim() !== 'undefined') {
                    attr_scroll = safeParseJSON(self.dataset.tpms, []);
                }
            }

            function safePadding(val, def = '0') {
                return (val !== undefined && val !== null && val !== '' ? val : def);
            }

            function checkHorizontalScrollAbove(currentEl) {
                if (!currentEl) return 0;

                const wrappers = document.querySelectorAll('.tp-horizontal-scroll-wrapper');
                if (!wrappers.length) return 0;

                const getPageTop = (el) =>
                    el.getBoundingClientRect().top + (window.pageYOffset || document.documentElement.scrollTop || 0);

                const currentTop = getPageTop(currentEl);
                let totalExtra = 0;

                wrappers.forEach((hsSection) => {
                    if (hsSection.contains(currentEl)) return;
                    if (getPageTop(hsSection) >= currentTop) return;

                    let tempID = '';
                    try {
                        const data = hsSection.dataset.result ? JSON.parse(hsSection.dataset.result) : null;
                        tempID = data && data.tempID ? String(data.tempID) : '';
                    } catch (e) {
                        tempID = '';
                    }

                    const selector = tempID ? `.elementor.elementor-${tempID} > .elementor-element` : '.elementor > .elementor-element';
                    const items = hsSection.querySelectorAll(selector);

                    const firstItem = items[0];
                    const wrapperWidth = hsSection.clientWidth || hsSection.offsetWidth || 0;

                    if (firstItem && wrapperWidth) {
                        const itemWidth = (firstItem.clientWidth || firstItem.offsetWidth || 0) + 15;
                        const trackCount = items.length + 1;
                        const totalTrackWidth = Math.max(0, trackCount * itemWidth);
                        const extra = Math.max(0, totalTrackWidth);
                        totalExtra += extra;
                    }
                });

                return totalExtra;
            }


            attr_scroll.forEach(function (item, itemIndex) {
                var attr_properties = {},
                    attr_propertiesEnd = {};

                let animationTargets = [self];

                var dev_options = false,
                    attr_sticky = false,
                    dev_name = '';

                function getNumericValueWithFallback(valueObj, defaultValue = 0) {
                    if (!valueObj) return defaultValue;

                    function isValidValue(value) {
                        return value !== '' && value !== null && value !== undefined;
                    }

                    function getValueFromDevice(device) {
                        if (!valueObj[device]) return null;
                        let value = valueObj[device];
                        return isValidValue(value) ? value : null;
                    }

                    let value = getValueFromDevice(getDevice);
                    if (value !== null) return value;

                    if (getDevice === 'xs') {
                        value = getValueFromDevice('sm');
                        if (value !== null) return value;
                        value = getValueFromDevice('md');
                        if (value !== null) return value;
                    } else if (getDevice === 'sm') {
                        value = getValueFromDevice('md');
                        if (value !== null) return value;
                    }

                    return defaultValue;
                }

                if (item.develop) {
                    dev_options = true;
                    dev_name = item.develop_name;
                }

                let textElements = [];

                function hasTextPropertiesForDevice() {
                    if (item.colorms?.colorValuems?.[getDevice] ||
                        item.fontsizems?.fontSizeValuems?.[getDevice] ||
                        item.letterspacingms?.letterSpacingValuems?.[getDevice] ||
                        item.textshadowms?.textShadowHms?.[getDevice] ||
                        item.paddingms?.paddingValuems?.[getDevice] ||
                        item.blurms?.blurValuems?.[getDevice] ||
                        item.grayscalems?.grayscaleValuems?.[getDevice] ||
                        item.brightnessms?.brightnessValuems?.[getDevice]) {
                        return true;
                    }

                    if (item.letterspacingms?.letterSpacingValuems) {
                        if (getDevice === 'xs') {
                            if (item.letterspacingms.letterSpacingValuems.sm || item.letterspacingms.letterSpacingValuems.md) {
                                return true;
                            }
                        } else if (getDevice === 'sm') {
                            if (item.letterspacingms.letterSpacingValuems.md || item.letterspacingms.letterSpacingValuems.xs) {
                                return true;
                            }
                        } else if (getDevice === 'md') {
                            if (item.letterspacingms.letterSpacingValuems.sm || item.letterspacingms.letterSpacingValuems.xs) {
                                return true;
                            }
                        }
                    }

                    return false;
                }

                const hasTextProperties = hasTextPropertiesForDevice();
                const hasCustomSelector = item.selector && item.selector.trim() !== '';

                if (hasTextProperties || hasCustomSelector) {
                    const customSelector = item.selector;

                    if (customSelector && customSelector.trim() !== '') {
                        let selectors = customSelector.split('|').map(sel => sel.trim()).filter(Boolean);
                        let allTextElements = [];
                        selectors.forEach(sel => {
                            let found = Array.from(self.querySelectorAll(sel));
                            allTextElements = allTextElements.concat(found);
                        });
                        textElements = Array.from(new Set(allTextElements));
                    } else {
                        textElements = Array.from(self.querySelectorAll('p, h1, h2, h3, h4, h5, h6, span, div, a, li, td, th, label, strong, em, b, i'));
                    }
                }

                let hasTextAnimation = false;

                // Rotation
                if (item.rotate) {
                    function getRotationValuesWithFallback(rotationObj, defaultValue = 0) {
                        if (!rotationObj) return { start: defaultValue, end: defaultValue };

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function hasValidValues(device) {
                            if (!rotationObj[device] || !Array.isArray(rotationObj[device]) || rotationObj[device].length < 2) {
                                return false;
                            }
                            return isValidValue(rotationObj[device][0]) || isValidValue(rotationObj[device][1]);
                        }

                        function getValuesFromDevice(device) {
                            if (!hasValidValues(device)) return null;

                            let start = isValidValue(rotationObj[device][0]) ? rotationObj[device][0] : 0;
                            let end = isValidValue(rotationObj[device][1]) ? rotationObj[device][1] : start;

                            return {
                                start: start,
                                end: end
                            };
                        }

                        let values = getValuesFromDevice(getDevice);
                        if (values !== null) return values;

                        if (getDevice === 'xs') {
                            values = getValuesFromDevice('sm');
                            if (values !== null) return values;
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        } else if (getDevice === 'sm') {
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        }

                        return { start: defaultValue, end: defaultValue };
                    }

                    var rotateXValues = getRotationValuesWithFallback(item.rotate.rotateX, 0);
                    var rotateYValues = getRotationValuesWithFallback(item.rotate.rotateY, 0);
                    var rotateZValues = getRotationValuesWithFallback(item.rotate.rotateZ, 0);

                    var rotateXstart = rotateXValues.start,
                        rotateXend = rotateXValues.end,
                        rotateYstart = rotateYValues.start,
                        rotateYend = rotateYValues.end,
                        rotateZstart = rotateZValues.start,
                        rotateZend = rotateZValues.end,
                        rotatePosi = item.rotate.position ? item.rotate.position : 'center center';

                    if (rotateXstart !== 0 || rotateXend !== 0) {
                        attr_properties.rotationX = rotateXstart;
                        attr_propertiesEnd.rotationX = rotateXend;
                    }

                    if (rotateYstart !== 0 || rotateYend !== 0) {
                        attr_properties.rotationY = rotateYstart;
                        attr_propertiesEnd.rotationY = rotateYend;
                    }

                    if (rotateZstart !== 0 || rotateZend !== 0) {
                        attr_properties.rotationZ = rotateZstart;
                        attr_propertiesEnd.rotationZ = rotateZend;
                    }

                    if (item.rotate.position) {
                        attr_propertiesEnd.transformOrigin = rotatePosi;
                    }
                }

                // Opacity
                var trigger = '50%';
                var offset = '0px';
                var end = 300;
                var trigger_ofst = '0px 50%';

                if (item.trigger || item.offset || item.duration) {
                    trigger = item.trigger && item.trigger[getDevice] ? item.trigger[getDevice] * 100 + '%' : '0%';
                    offset = item.offset && item.offset[getDevice] ? item.offset[getDevice] + 'px' : '0px';
                    end = item.duration && item.duration[getDevice] ? item.duration[getDevice] : 300;

                    if (item.dynamicHeight) {
                        const referenceHeight = item.dynamicHeight.referenceHeight || 1080;
                        const deviceHeight = window.innerHeight;
                        const originalOffset = parseFloat(offset) || 0;
                        const heightRatio = deviceHeight / referenceHeight;
                        var scaledOffset = originalOffset * heightRatio;
                        offset = scaledOffset + 'px';
                    }
                }
                const baseOffsetPx = parseFloat(offset) || 0;
                const extraPx = checkHorizontalScrollAbove(self);
                const newOffsetPx = baseOffsetPx + (extraPx > 0 ? extraPx : 0);
                trigger_ofst = newOffsetPx + 'px ' + trigger;
                // trigger_ofst = offset + ' ' + trigger;

                if (item.opacity) {
                    function getOpacityValuesWithFallback(opacityObj, defaultValue = '') {
                        if (!opacityObj) return { start: defaultValue, end: defaultValue };

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function hasValidValues(device) {
                            if (!opacityObj.speed || !opacityObj.speed[device] || !Array.isArray(opacityObj.speed[device]) || opacityObj.speed[device].length < 2) {
                                return false;
                            }
                            return isValidValue(opacityObj.speed[device][0]) && isValidValue(opacityObj.speed[device][1]);
                        }

                        function getValuesFromDevice(device) {
                            if (!hasValidValues(device)) return null;
                            return {
                                start: opacityObj.speed[device][0],
                                end: opacityObj.speed[device][1]
                            };
                        }

                        let values = getValuesFromDevice(getDevice);
                        if (values !== null) return values;

                        if (getDevice === 'xs') {
                            values = getValuesFromDevice('sm');
                            if (values !== null) return values;
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        } else if (getDevice === 'sm') {
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        }

                        return { start: defaultValue, end: defaultValue };
                    }

                    var opacityValues = getOpacityValuesWithFallback(item.opacity, '');
                    var opacity_start = opacityValues.start;
                    var opacity_end = opacityValues.end;

                    attr_properties.opacity = opacity_start;
                    attr_propertiesEnd.opacity = opacity_end;
                }

                // Horizontal
                if (item.horizontal) {
                    function getHorizontalValuesWithFallback(horizontalObj, defaultValue = 0) {
                        if (!horizontalObj) return { start: defaultValue, end: defaultValue };

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function hasValidValues(device) {
                            if (!horizontalObj.speed || !horizontalObj.speed[device] || !Array.isArray(horizontalObj.speed[device]) || horizontalObj.speed[device].length < 2) {
                                return false;
                            }
                            return isValidValue(horizontalObj.speed[device][0]) && isValidValue(horizontalObj.speed[device][1]);
                        }

                        function getValuesFromDevice(device) {
                            if (!hasValidValues(device)) return null;
                            return {
                                start: horizontalObj.speed[device][0],
                                end: horizontalObj.speed[device][1]
                            };
                        }

                        let values = getValuesFromDevice(getDevice);
                        if (values !== null) return values;

                        if (getDevice === 'xs') {
                            values = getValuesFromDevice('sm');
                            if (values !== null) return values;
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        } else if (getDevice === 'sm') {
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        }

                        return { start: defaultValue, end: defaultValue };
                    }

                    var horizontalValues = getHorizontalValuesWithFallback(item.horizontal, 0);
                    var horizontal_start = horizontalValues.start;
                    var horizontal_end = horizontalValues.end;

                    if (horizontal_start !== 0 || horizontal_end !== 0) {
                        attr_properties.x = horizontal_start;
                        attr_propertiesEnd.x = horizontal_end;
                    }
                }

                // Vertical
                if (item.vertical) {
                    function getVerticalValuesWithFallback(verticalObj, defaultValue = 0) {
                        if (!verticalObj) return { start: defaultValue, end: defaultValue };

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function hasValidValues(device) {
                            if (!verticalObj.speed || !verticalObj.speed[device] || !Array.isArray(verticalObj.speed[device]) || verticalObj.speed[device].length < 2) {
                                return false;
                            }
                            return isValidValue(verticalObj.speed[device][0]) && isValidValue(verticalObj.speed[device][1]);
                        }

                        function getValuesFromDevice(device) {
                            if (!hasValidValues(device)) return null;
                            return {
                                start: verticalObj.speed[device][0],
                                end: verticalObj.speed[device][1]
                            };
                        }

                        let values = getValuesFromDevice(getDevice);
                        if (values !== null) return values;

                        if (getDevice === 'xs') {
                            values = getValuesFromDevice('sm');
                            if (values !== null) return values;
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        } else if (getDevice === 'sm') {
                            values = getValuesFromDevice('md');
                            if (values !== null) return values;
                        }

                        return { start: defaultValue, end: defaultValue };
                    }

                    var verticalValues = getVerticalValuesWithFallback(item.vertical, 0);
                    var vertical_start = verticalValues.start;
                    var vertical_end = verticalValues.end;

                    if (vertical_start !== 0 || vertical_end !== 0) {
                        attr_properties.y = vertical_start;
                        attr_propertiesEnd.y = vertical_end;
                    }
                }

                // Scale
                if (item.scale) {
                    function getScaleValueWithFallback(scaleObj, scaleType, index, defaultValue = 1) {
                        if (!scaleObj || !scaleObj[scaleType]) return defaultValue;

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function getValueFromDevice(device) {
                            if (!scaleObj[scaleType][device] || !Array.isArray(scaleObj[scaleType][device]) || scaleObj[scaleType][device].length <= index) {
                                return null;
                            }
                            let value = scaleObj[scaleType][device][index];
                            return isValidValue(value) ? value : null;
                        }

                        let value = getValueFromDevice(getDevice);
                        if (value !== null) return value;

                        if (getDevice === 'xs') {
                            value = getValueFromDevice('sm');
                            if (value !== null) return value;
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        } else if (getDevice === 'sm') {
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        }

                        return defaultValue;
                    }

                    var scalex_start = getScaleValueWithFallback(item.scale, 'scaleX', 0, 1);
                    var scalex_end = getScaleValueWithFallback(item.scale, 'scaleX', 1, 1);
                    var scaley_start = getScaleValueWithFallback(item.scale, 'scaleY', 0, 1);
                    var scaley_end = getScaleValueWithFallback(item.scale, 'scaleY', 1, 1);
                    var scalez_start = getScaleValueWithFallback(item.scale, 'scaleZ', 0, 1);
                    var scalez_end = getScaleValueWithFallback(item.scale, 'scaleZ', 1, 1);

                    if (scalex_start !== 1 || scalex_end !== 1) {
                        attr_properties.scaleX = scalex_start;
                        attr_propertiesEnd.scaleX = scalex_end;
                    }

                    if (scaley_start !== 1 || scaley_end !== 1) {
                        attr_properties.scaleY = scaley_start;
                        attr_propertiesEnd.scaleY = scaley_end;
                    }

                    if (scalez_start !== 1 || scalez_end !== 1) {
                        attr_properties.scaleZ = scalez_start;
                        attr_propertiesEnd.scaleZ = scalez_end;
                    }

                    // if (scalez_start !== 0 || scalez_end !== 0) {
                    //     attr_properties.z = scalez_start * 100;
                    //     attr_propertiesEnd.z = scalez_end * 100;
                    // }
                }

                // Skew
                if (item.skew) {
                    function getSkewValueWithFallback(skewObj, skewType, index, defaultValue = '0') {
                        if (!skewObj || !skewObj[skewType]) return defaultValue;

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function getValueFromDevice(device) {
                            if (!skewObj[skewType][device] || !Array.isArray(skewObj[skewType][device]) || skewObj[skewType][device].length <= index) {
                                return null;
                            }
                            let value = skewObj[skewType][device][index];
                            return isValidValue(value) ? value : null;
                        }
                        let value = getValueFromDevice(getDevice);
                        if (value !== null) return value;

                        if (getDevice === 'xs') {
                            value = getValueFromDevice('sm');
                            if (value !== null) return value;
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        } else if (getDevice === 'sm') {
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        }

                        return defaultValue;
                    }

                    var skewx_start = getSkewValueWithFallback(item.skew, 'skewX', 0, '0');
                    var skewx_end = getSkewValueWithFallback(item.skew, 'skewX', 1, '0');
                    var skewy_start = getSkewValueWithFallback(item.skew, 'skewY', 0, '0');
                    var skewy_end = getSkewValueWithFallback(item.skew, 'skewY', 1, '0');

                    if (skewx_start !== '0' || skewx_end !== '0') {
                        attr_properties.skewX = skewx_start;
                        attr_propertiesEnd.skewX = skewx_end;
                    }

                    if (skewy_start !== '0' || skewy_end !== '0') {
                        attr_properties.skewY = skewy_start;
                        attr_propertiesEnd.skewY = skewy_end;
                    }
                }

                // FONT SIZE
                if (item.fontsizems?.fontSizeValuems) {
                    function getFontSizeValueWithFallback(fontSizeObj, index, defaultValue = '') {
                        if (!fontSizeObj || !fontSizeObj.fontSizeValuems) return defaultValue;

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function getValueFromDevice(device) {
                            if (!fontSizeObj.fontSizeValuems[device] || !Array.isArray(fontSizeObj.fontSizeValuems[device]) || fontSizeObj.fontSizeValuems[device].length <= index) {
                                return null;
                            }
                            let value = fontSizeObj.fontSizeValuems[device][index];
                            return isValidValue(value) ? value : null;
                        }

                        let value = getValueFromDevice(getDevice);
                        if (value !== null) return value;

                        if (getDevice === 'xs') {
                            value = getValueFromDevice('sm');
                            if (value !== null) return value;
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        } else if (getDevice === 'sm') {
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        }

                        return defaultValue;
                    }

                    let start = getFontSizeValueWithFallback(item.fontsizems, 0, '');
                    let end = getFontSizeValueWithFallback(item.fontsizems, 1, start);

                    if (start !== '' || end !== '') {
                        attr_properties.fontSize = start;
                        attr_propertiesEnd.fontSize = end;
                        hasTextAnimation = true;
                    }
                }

                // LETTER SPACING
                if (item.letterspacingms?.letterSpacingValuems) {
                    function getLetterSpacingValueWithFallback(letterSpacingObj, index, defaultValue = '') {
                        if (!letterSpacingObj || !letterSpacingObj.letterSpacingValuems) return defaultValue;

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function getValueFromDevice(device) {
                            if (!letterSpacingObj.letterSpacingValuems[device] || !Array.isArray(letterSpacingObj.letterSpacingValuems[device]) || letterSpacingObj.letterSpacingValuems[device].length <= index) {
                                return null;
                            }
                            let value = letterSpacingObj.letterSpacingValuems[device][index];
                            if (!isValidValue(value)) return null;

                            if (typeof value === 'string') {
                                if (value.match(/^-?\d*\.?\d+(px|em|rem|%|pt|pc|mm|cm|in)$/)) {
                                    return value;
                                }
                                if (value.match(/^-?\d*\.?\d+$/)) {
                                    return value + 'px';
                                }
                            } else if (typeof value === 'number') {
                                return value + 'px';
                            }

                            return value;
                        }

                        let value = getValueFromDevice(getDevice);
                        if (value !== null) return value;

                        if (getDevice === 'xs') {
                            value = getValueFromDevice('sm');
                            if (value !== null) return value;
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        } else if (getDevice === 'sm') {
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        }

                        return defaultValue;
                    }

                    let start = getLetterSpacingValueWithFallback(item.letterspacingms, 0, '');
                    let end = getLetterSpacingValueWithFallback(item.letterspacingms, 1, start);

                    if (start !== '' || end !== '') {
                        attr_properties['letter-spacing'] = start;
                        attr_propertiesEnd['letter-spacing'] = end;
                        hasTextAnimation = true;
                    }
                }

                // TEXT SHADOW
                if (item.textshadowms?.textShadowHms?.[getDevice]) {
                    let arr = item.textshadowms.textShadowHms[getDevice];

                    let start = '';
                    let end = '';

                    if (arr.length >= 4) {
                        start = `${arr[0] || '0px'} ${arr[1] || '0px'} ${arr[2] || '0px'} ${arr[3] || '#000000'}`;
                    }

                    if (arr.length >= 8) {
                        end = `${arr[4] || '0px'} ${arr[5] || '0px'} ${arr[6] || '0px'} ${arr[7] || '#000000'}`;
                    } else {
                        end = start;
                    }

                    attr_properties.textShadow = start;
                    attr_propertiesEnd.textShadow = end;
                    hasTextAnimation = true;
                }

                // BOX SHADOW (array-based)
                if (item.boxshadowms?.boxShadowHms?.[getDevice]) {
                    let arr = item.boxshadowms.boxShadowHms[getDevice];
                    function buildBoxShadowFromArray(arr, startIndex = 0) {
                        if (!arr || arr.length < startIndex + 5) return '';
                        let h = arr[startIndex] || '0px';
                        let v = arr[startIndex + 1] || '0px';
                        let blur = arr[startIndex + 2] || '0px';
                        let spread = arr[startIndex + 3] || '0px';
                        let color = arr[startIndex + 4] || 'rgba(0,0,0,0)';
                        let pos = arr[startIndex + 5] || '';
                        return `${h} ${v} ${blur} ${spread} ${color}${pos ? ' ' + pos : ''}`;
                    }
                    let boxShadowStart = buildBoxShadowFromArray(arr, 0);
                    let boxShadowEnd = buildBoxShadowFromArray(arr, 6);
                    attr_properties.boxShadow = boxShadowStart;
                    attr_propertiesEnd.boxShadow = boxShadowEnd;
                }

                if (item.colorms?.colorValuems) {
                    function getColorValueWithFallback(colorObj, index, defaultValue = '') {
                        if (!colorObj || !colorObj.colorValuems) return defaultValue;

                        function isValidValue(value) {
                            return value !== '' && value !== null && value !== undefined;
                        }

                        function getValueFromDevice(device) {
                            if (!colorObj.colorValuems[device] || !Array.isArray(colorObj.colorValuems[device]) || colorObj.colorValuems[device].length <= index) {
                                return null;
                            }
                            let value = colorObj.colorValuems[device][index];
                            return isValidValue(value) ? value : null;
                        }

                        let value = getValueFromDevice(getDevice);
                        if (value !== null) return value;

                        if (getDevice === 'xs') {
                            value = getValueFromDevice('sm');
                            if (value !== null) return value;
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        } else if (getDevice === 'sm') {
                            value = getValueFromDevice('md');
                            if (value !== null) return value;
                        }

                        return defaultValue;
                    }

                    let start = getColorValueWithFallback(item.colorms, 0, '');
                    let end = getColorValueWithFallback(item.colorms, 1, start);

                    if (start !== '' || end !== '') {
                        if (textElements.length > 0) {
                            attr_properties.color = start;
                            attr_propertiesEnd.color = end;
                            hasTextAnimation = true;
                        } else {
                            attr_properties.color = start;
                            attr_propertiesEnd.color = end;
                        }
                    }
                }

                // PADDING (individual sides)
                if (item.paddingms && item.paddingms.paddingValuems) {
                    let padStart = item.paddingms.paddingValuems[getDevice]?.[0] || {};
                    let padEnd = item.paddingms.paddingValuems[getDevice]?.[1] || {};

                    attr_properties.paddingTop = safePadding(padStart.top) + (padStart.unit || 'px');
                    attr_properties.paddingRight = safePadding(padStart.right) + (padStart.unit || 'px');
                    attr_properties.paddingBottom = safePadding(padStart.bottom) + (padStart.unit || 'px');
                    attr_properties.paddingLeft = safePadding(padStart.left) + (padStart.unit || 'px');

                    attr_propertiesEnd.paddingTop = safePadding(padEnd.top) + (padEnd.unit || 'px');
                    attr_propertiesEnd.paddingRight = safePadding(padEnd.right) + (padEnd.unit || 'px');
                    attr_propertiesEnd.paddingBottom = safePadding(padEnd.bottom) + (padEnd.unit || 'px');
                    attr_propertiesEnd.paddingLeft = safePadding(padEnd.left) + (padEnd.unit || 'px');
                }

                // FILTERS: BLUR, GRAYSCALE, BRIGHTNESS
                let filters_start = [];
                let filters_end = [];

                function getFilterValueWithFallback(filterObj, filterType, index, defaultValue = 0) {
                    if (!filterObj || !filterObj[filterType]) return defaultValue;

                    function isValidValue(value) {
                        return value !== '' && value !== null && value !== undefined;
                    }

                    function getValueFromDevice(device) {
                        if (!filterObj[filterType][device] || !Array.isArray(filterObj[filterType][device]) || filterObj[filterType][device].length <= index) {
                            return null;
                        }
                        let value = filterObj[filterType][device][index];
                        return isValidValue(value) ? value : null;
                    }

                    let value = getValueFromDevice(getDevice);
                    if (value !== null) return value;

                    if (getDevice === 'xs') {
                        value = getValueFromDevice('sm');
                        if (value !== null) return value;
                        value = getValueFromDevice('md');
                        if (value !== null) return value;
                    } else if (getDevice === 'sm') {
                        value = getValueFromDevice('md');
                        if (value !== null) return value;
                    }

                    return defaultValue;
                }

                // BLUR
                if (item.blurms?.blurValuems) {
                    let blurStart = getFilterValueWithFallback(item.blurms, 'blurValuems', 0, 0);
                    let blurEnd = getFilterValueWithFallback(item.blurms, 'blurValuems', 1, blurStart);

                    if (blurStart !== 0 || blurEnd !== 0) {
                        filters_start.push(`blur(${blurStart}px)`);
                        filters_end.push(`blur(${blurEnd}px)`);
                    }
                }

                // GRAYSCALE
                if (item.grayscalems?.grayscaleValuems) {
                    let start = getFilterValueWithFallback(item.grayscalems, 'grayscaleValuems', 0, 0);
                    let end = getFilterValueWithFallback(item.grayscalems, 'grayscaleValuems', 1, start);

                    if (start !== 0 || end !== 0) {
                        filters_start.push(`grayscale(${start}%)`);
                        filters_end.push(`grayscale(${end}%)`);
                    }
                }

                // BRIGHTNESS
                if (item.brightnessms?.brightnessValuems) {
                    let start = 1 + getFilterValueWithFallback(item.brightnessms, 'brightnessValuems', 0, 0) / 100;
                    let end = 1 + getFilterValueWithFallback(item.brightnessms, 'brightnessValuems', 1, 0) / 100;

                    if (start !== 1 || end !== 1) {
                        filters_start.push(`brightness(${start})`);
                        filters_end.push(`brightness(${end})`);
                    }
                }

                if (filters_start.length > 0 || filters_end.length > 0) {
                    if (textElements.length > 0) {
                        attr_propertiesEnd.filter = filters_end.join(' ');
                        hasTextAnimation = true;
                    } else {
                        attr_properties.filter = filters_start.join(' ');
                        attr_propertiesEnd.filter = filters_end.join(' ');
                    }
                }

                // Border Radius
                if (item.borderR) {
                    if (item.borderR[0]) {
                        var Sborder_attr = item.borderR[0].fromBR[getDevice];
                        var unit = Sborder_attr && Sborder_attr.unit ? Sborder_attr.unit : 'px';
                        var borderT_start = Sborder_attr && Sborder_attr.top ? Sborder_attr.top + unit : '0px',
                            borderR_start = Sborder_attr && Sborder_attr.right ? Sborder_attr.right + unit : '0px',
                            borderB_start = Sborder_attr && Sborder_attr.bottom ? Sborder_attr.bottom + unit : '0px',
                            borderL_start = Sborder_attr && Sborder_attr.left ? Sborder_attr.left + unit : '0px';

                        var Border_start = `${borderT_start} ${borderR_start} ${borderB_start} ${borderL_start}`;
                        attr_properties.borderRadius = Border_start;
                    }

                    if (item.borderR[1]) {
                        var Eborder_attr = item.borderR[1].toBR[getDevice];
                        var unit = Eborder_attr && Eborder_attr.unit ? Eborder_attr.unit : 'px';
                        var borderT_end = Eborder_attr && Eborder_attr.top ? Eborder_attr.top + unit : '0px',
                            borderR_end = Eborder_attr && Eborder_attr.right ? Eborder_attr.right + unit : '0px',
                            borderB_end = Eborder_attr && Eborder_attr.bottom ? Eborder_attr.bottom + unit : '0px',
                            borderL_end = Eborder_attr && Eborder_attr.left ? Eborder_attr.left + unit : '0px';

                        var Border_end = `${borderT_end} ${borderR_end} ${borderB_end} ${borderL_end}`;
                        attr_propertiesEnd.borderRadius = Border_end;
                    }
                }

                // Parallax
                var xMove = 0,
                    yMove = 0;

                if (item.parallax) {
                    if (item.parallax[getDevice]) {
                        xMove = item.parallax[getDevice].x || 0;
                        yMove = item.parallax[getDevice].y || 0;
                    } else {
                        xMove = item.parallax.x || 0;
                        yMove = item.parallax.y || 0;
                    }

                    var maxX = parseFloat(xMove) || 0;
                    var maxY = parseFloat(yMove) || 0;

                    if (maxX !== 0 || maxY !== 0) {
                        window.addEventListener("mousemove", (e) => {
                            var xPos = e.clientX - window.innerWidth / 2;
                            var yPos = e.clientY - window.innerHeight / 2;

                            var speedX = maxX / (window.innerWidth / 2);
                            var speedY = maxY / (window.innerHeight / 2);

                            gsap.to(animationTargets, {
                                x: xPos * speedX,
                                y: yPos * speedY,
                                duration: item.tp_duration ? item.tp_duration : 3,
                                ease: easing,
                                overwrite: "auto"
                            });
                        });
                    }
                }

                // Background Color
                if (item.bgColor) {

                    var bgcolor_start = item.bgColor[0].fromColor ? item.bgColor[0].fromColor : '',
                        bgcolor_end = item.bgColor[1].toColor ? item.bgColor[1].toColor : '';

                    const customSelector = item.selector;

                    if (customSelector && customSelector.trim() !== '') {
                        if (item.bgColor[0]) {
                            attr_properties.backgroundColor = bgcolor_start
                        }
                        if (item.bgColor[1]) {
                            attr_propertiesEnd.backgroundColor = bgcolor_end
                        }
                    } else {
                        if (item.bgColor[0]) {
                            attr_properties.backgroundColor = bgcolor_start
                        }
                        if (item.bgColor[1]) {
                            attr_propertiesEnd.backgroundColor = bgcolor_end
                        }
                    }
                }

                // Repeat
                var attr_repeter = 0;
                if (item.repeat) {
                    attr_repeter = getNumericValueWithFallback(item.repeat, 0);
                }

                // Easing
                if (item.easing) {
                    var easing = item.easing ? item.easing : '';
                }

                // Sticky
                if (item.sticky) {
                    attr_sticky = true;

                    if (item.zindex) {
                        self.style.position = 'relative';
                        self.style.zIndex = item.zindex;
                    }
                }

                // Delay
                if (item.delay) {
                    var delay = getNumericValueWithFallback(item.delay, 0);
                }

                // Timing
                let scrub_value = getNumericValueWithFallback(item.timing, 1);

                if (item.playvideo) {
                    scrub_value = true;
                }

                let pinTarget = self;

                if (attr_sticky && item.selector && item.selector.trim() !== '' && textElements.length > 0) {
                    pinTarget = textElements[0];
                }

                if (hasTextAnimation && textElements.length > 0 && !(item.selector && item.selector.trim() !== '')) {
                    animationTargets = textElements;
                }
                let triggerTarget = self;

                if (item.selector && item.selector.trim() !== '') {
                    let selectors = item.selector.split('|').map(sel => sel.trim()).filter(Boolean);
                    let allTargets = [];
                    selectors.forEach(sel => {
                        let found = Array.from(self.querySelectorAll(sel));
                        allTargets = allTargets.concat(found);
                    });
                    if (allTargets.length > 0) {
                        animationTargets = Array.from(new Set(allTargets));
                    }
                }

                let triggerId = dev_name ? dev_name.trim().replace(/\s+/g, '-') : 'magic-scroll-' + Math.random().toString(36).substr(2, 9);

                if (!self._tpMagicScrollTriggers) {
                    self._tpMagicScrollTriggers = new Set();
                }

                let originalTriggerId = triggerId;
                let counter = 1;
                while (self._tpMagicScrollTriggers.has(triggerId)) {
                    triggerId = originalTriggerId + '-' + counter;
                    counter++;
                }
                self._tpMagicScrollTriggers.add(triggerId);

                ScrollTrigger.getAll().forEach(trigger => {
                    if (trigger.vars && trigger.vars.trigger === self && trigger.vars.id === triggerId) {
                        trigger.kill();
                    }
                });

                gsap.getTweensOf(animationTargets).forEach(tween => {
                    if (tween.vars && tween.vars.id === triggerId) {
                        tween.kill();
                    }
                });

                gsap.getTweensOf(self).forEach(tween => {
                    if (tween.vars && tween.vars.id === triggerId) {
                        tween.kill();
                    }
                });

                gsap.set([self, ...animationTargets], { clearProps: "transform" });

                if ('filter' in attr_properties) delete attr_properties.filter;
                if ('filter' in attr_propertiesEnd) delete attr_propertiesEnd.filter;

                if ((attr_properties.color || attr_propertiesEnd.color ||
                    attr_properties.fontSize || attr_propertiesEnd.fontSize ||
                    attr_properties['letter-spacing'] || attr_propertiesEnd['letter-spacing'] ||
                    attr_properties.textShadow || attr_propertiesEnd.textShadow) &&
                    !(item.selector && item.selector.trim() !== '')) {
                    let textEls = Array.from(self.querySelectorAll('p, h1, h2, h3, h4, h5, h6, span, a, li, td, th, label, strong, em, b, i'));
                    if (textEls.length > 0) {
                        animationTargets = textEls;
                    }
                }

                let videoControlCallback = null;
                let videoElements = [];
                if (item.playvideo) {
                    const videoSelector = item.selector || 'video';

                    let videos = self.querySelectorAll(videoSelector);

                    if (videos.length === 0) {
                        videos = self.querySelectorAll('video');
                    }

                    videos.forEach(video => videoElements.push(video));
                    if (videoElements.length > 0) {
                        let videoReadyCount = 0;
                        let fallbackDuration = 20;
                        videoElements.forEach(video => {
                            const checkVideoReady = () => {
                                if (video.duration && isFinite(video.duration) && video.duration > 0) {
                                    videoReadyCount++;
                                    return true;
                                }
                                return false;
                            };
                            const setFallbackDuration = () => {
                                if (video.duration === Infinity || video.duration === 0 || !isFinite(video.duration)) {
                                    video._fallbackDuration = fallbackDuration;
                                    videoReadyCount++;
                                    return true;
                                }
                                return false;
                            };
                            video.controls = false;
                            video.muted = true;
                            video.playsInline = true;
                            if (video.readyState < 2) {
                                video.addEventListener('loadedmetadata', () => {
                                    if (!checkVideoReady()) {
                                        setFallbackDuration();
                                    }
                                });
                                video.addEventListener('canplay', () => {
                                    if (!checkVideoReady()) {
                                        setFallbackDuration();
                                    }
                                });
                                video.addEventListener('loadeddata', () => {
                                    if (!checkVideoReady()) {
                                        setFallbackDuration();
                                    }
                                });
                                video.load();
                            } else {
                                if (!checkVideoReady()) {
                                    setFallbackDuration();
                                }
                            }
                        });
                        setTimeout(() => {
                            if (videoReadyCount === 0) {
                                videoElements.forEach(video => {
                                    if (video.duration === Infinity || video.duration === 0 || !isFinite(video.duration)) {
                                        video._fallbackDuration = fallbackDuration;
                                        videoReadyCount++;
                                    }
                                });
                            }
                        }, 3000);
                        videoControlCallback = (self) => {
                            const progress = self.progress;
                            if (isNaN(progress) || !isFinite(progress)) {
                                return;
                            }
                            if (videoReadyCount === 0) {
                                return;
                            }
                            videoElements.forEach(video => {
                                try {
                                    if (video.readyState < 2) {
                                        return;
                                    }
                                    video.controls = false;
                                    video.muted = true;
                                    video.playsInline = true;
                                    let effectiveDuration = video.duration;
                                    if (video._fallbackDuration) {
                                        effectiveDuration = video._fallbackDuration;
                                    }
                                    if (effectiveDuration && isFinite(effectiveDuration) && effectiveDuration > 0 && !isNaN(progress) && isFinite(progress)) {
                                        const newTime = progress * effectiveDuration;
                                        if (!isNaN(newTime) && isFinite(newTime) && newTime >= 0 && newTime <= effectiveDuration) {
                                            if (video.duration && isFinite(video.duration) && video.duration > 0) {
                                                video.currentTime = newTime;
                                            }
                                        }
                                    }
                                } catch (error) { }
                            });
                        };
                    }
                }

                const scrollTriggerConfig = {
                    trigger: self,
                    scrub: attr_sticky ? true : scrub_value,
                    start: trigger_ofst,
                    end: end && end !== undefined ? `+=${end}` : undefined,
                    markers: dev_options,
                    id: triggerId,
                    pin: attr_sticky ? pinTarget : false,
                    pinSpacing: attr_sticky ? false : true,
                    // pinReparent: true
                };

                if (videoControlCallback) {
                    scrollTriggerConfig.onUpdate = videoControlCallback;
                }

                const hasAnimationProperties = Object.keys(attr_properties).length > 0 || Object.keys(attr_propertiesEnd).length > 0 || filters_start.length > 0 || filters_end.length > 0;
                const hasVideoControl = videoControlCallback !== null;
                const hasSticky = attr_sticky;
                const hasTriggers = trigger_ofst !== undefined || end !== undefined;

                if (hasAnimationProperties || hasVideoControl) {
                    if (filters_start.length > 0 || filters_end.length > 0) {
                        gsap.fromTo(
                            animationTargets,
                            { ...attr_properties, filter: filters_start.join(' ') },
                            {
                                ...attr_propertiesEnd,
                                filter: filters_end.join(' '),
                                id: triggerId,
                                scrollTrigger: scrollTriggerConfig,
                                ease: easing,
                                repeat: attr_repeter,
                                overwrite: "auto",
                                immediateRender: false,
                            }
                        );
                    } else {
                        if ('tp_on_scroll' === item.gsap_animetion_trigger) {
                            gsap.fromTo(
                                animationTargets,
                                attr_properties,
                                {
                                    ...attr_propertiesEnd,
                                    id: triggerId,
                                    scrollTrigger: scrollTriggerConfig,
                                    ease: easing,
                                    repeat: attr_repeter,
                                    overwrite: "auto",
                                    immediateRender: false,
                                }
                            );
                        } else if ('tp_on_load' === item.gsap_animetion_trigger) {
                            gsap.fromTo(
                                animationTargets,
                                {
                                    ...attr_properties
                                },
                                {
                                    ...attr_propertiesEnd,
                                    ease: easing,
                                    repeat: attr_repeter,
                                    overwrite: "auto",
                                    immediateRender: true,
                                    duration: item.tp_duration ? item.tp_duration : 3
                                }
                            );
                        } else if ('tp_on_hover' === item.gsap_animetion_trigger) {
                            var hoverTween = gsap.fromTo(
                                animationTargets,
                                attr_properties,
                                {
                                    ...attr_propertiesEnd,
                                    ease: easing,
                                    paused: true,
                                    overwrite: "auto",
                                    duration: item.tp_duration ? item.tp_duration : 3
                                }
                            );
                            self.addEventListener('mouseenter', () => {
                                hoverTween.play();
                            });
                            self.addEventListener('mouseleave', () => {
                                hoverTween.reverse();
                            });
                        }
                    }
                } else if (hasVideoControl) {
                    gsap.fromTo(
                        [self],
                        {},
                        {
                            id: triggerId,
                            scrollTrigger: scrollTriggerConfig,
                            ease: easing,
                            repeat: attr_repeter,
                            overwrite: "auto",
                            immediateRender: false,
                        }
                    );
                } else if (hasSticky || hasTriggers) {
                    gsap.fromTo(
                        [self],
                        {},
                        {
                            id: triggerId,
                            scrollTrigger: scrollTriggerConfig,
                            ease: easing,
                            repeat: attr_repeter,
                            overwrite: "auto",
                            immediateRender: false,
                        }
                    );
                }

                //draw SVG
                if (item.drawsvg) {
                    gsap.registerPlugin(DrawSVGPlugin);
                    var savgTragets = self.querySelectorAll(item.drawsvg);

                    savgTragets.forEach(function (wrapper, index) {
                        var paths = wrapper.querySelectorAll(
                            'path, line, polyline, polygon, circle, rect'
                        );
                        if (!paths.length) return;

                        attr_properties.drawSVG = "0%";
                        attr_propertiesEnd.drawSVG = "100%";

                        gsap.fromTo(
                            paths,
                            attr_properties,
                            {
                                ...attr_propertiesEnd,
                                id: triggerId,
                                scrollTrigger: scrollTriggerConfig,
                                ease: easing,
                                repeat: attr_repeter,
                                overwrite: "auto",
                                immediateRender: false,
                            }
                        );
                    });
                }

                setTimeout(() => {
                    if (self.dataset.magicScrollProcessing === 'true') {
                        self.dataset.magicScrollProcessing = 'false';
                    }
                }, 100);
            })
        })
    }

    $(window).on('elementor/frontend/init', function () {
        function runMagicScrollHandler($scope) {
            magicScrollHandler($scope);
        }

        if (elementorFrontend.isEditMode()) {
            elementorFrontend.hooks.addAction('frontend/element_ready/global', runMagicScrollHandler);
        } else {
            elementorFrontend.hooks.addAction('frontend/element_ready/section', runMagicScrollHandler);
            elementorFrontend.hooks.addAction('frontend/element_ready/container', runMagicScrollHandler);
        }
    });


}(jQuery));