/*************************************************************
Lagom Orderform Scripts
1. Product domain search box
2. Product domain search results
3. Add Domain To Cart
4. Domain Register Search
5. Update Config Options
6. Serialize Config Form
7. Domain Renewals
8. Empty Cart
9. Use Credit on Checkout
10. Payment Methods
11. Domain Contacts
12. Change Domain Register Period on Configure Domains Page
13. Submit Login From on Checkout Page by Enter Key
*************************************************************
*/
/*******************************************
Lagom Orderform Functions
1. Product Domain Lookup Ended
2. Domain Lookup Ended
2. Recalc Totals
3. Recalc Renew Totals
4. Remove Item
5. Select Domain Period
6. Validate Captcha
7. More Suggestions
8. Checkout Form
9. Select Product Billing Cycle
10. Remove Addon
11. Check Tos
12. Update Stripe
13. Update Domain Period
14. Add Promo Code
*******************************************
*/


function scrollToGatewayInputError() {
    var displayError = jQuery('.gateway-errors,.assisted-cc-input-feedback').first(),
        frm = displayError.closest('form');
    if (!frm) {
        frm = jQuery('form').first();
    }
    frm.find('button[type="submit"],input[type="submit"]')
        .prop('disabled', false)
        .removeClass('disabled')
        .find('i.fas,i.far,i.fal,i.fab')
        .removeAttr('class')
        .addClass('fas fa-arrow-circle-right')
        .find('span').toggleClass('hidden');

    if (displayError.length) {
        if (elementOutOfViewPort(displayError[0])) {
            jQuery('html, body').animate(
                {
                    scrollTop: displayError.offset().top - 50
                },
                500
            );
        }
    }
}

function elementOutOfViewPort(element) {
    // Get element's bounding
    var bounding = element.getBoundingClientRect();
    // Check if it's out of the viewport on each side
    var out = {};
    out.top = bounding.top < 0;
    out.left = bounding.left < 0;
    out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
    out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
    out.any = out.top || out.left || out.bottom || out.right;

    return out.any;
}

function showCheckoutError(errorMessage, container = null) {
    jQuery('.alert-danger').hide();

    const selectors = [
        '.checkout-error-feedback',
        '#existingLoginMessage',
        '.gateway-errors',
        '.assisted-cc-input-feedback'
    ];

    if (!container) {
        container = jQuery(selectors.join(', ')).first();
    }

    if (container.length) {
        container.html(errorMessage).slideDown('fast');
    }
}

/**
 * WHMCS authentication module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2017
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */

(function(module) {
    if (!WHMCS.hasModule('authn')) {
        WHMCS.loadModule('authn', module);
    }
})({
provider: function () {
    var callbackFired = false;

    /**
     * @return {jQuery}
     */
    this.feedbackContainer = function () {
        return jQuery(".providerLinkingFeedback");
    };

    /**
     * @returns {jQuery}
     */
    this.btnContainer = function () {
        return jQuery(".providerPreLinking");
    };

    this.feedbackMessage = function (context) {
        if (typeof context === 'undefined') {
            context = 'complete_sign_in';
        }
        var msgContainer = jQuery('p.providerLinkingMsg-preLink-' + context);
        if (msgContainer.length) {
            return msgContainer.first().html();
        }

        return '';
    };

    this.showProgressMessage = function(callback) {
        this.feedbackContainer().fadeIn('fast', function () {
            if (typeof callback === 'function' && !callbackFired) {
                callbackFired = true;
                callback();
            }
        });
    };

    this.preLinkInit = function (callback) {
        var icon = '<i class="fas fa-fw fa-spinner fa-spin"></i> ';

        this.feedbackContainer()
            .removeClass('alert-danger alert-success')
            .addClass('alert alert-info')
            .html(icon + this.feedbackMessage())
            .hide();

        var btnContainer = this.btnContainer();
        if (btnContainer.length) {
            if (btnContainer.data('hideOnPrelink')) {
                var self = this;
                btnContainer.fadeOut('false', function ()
                {
                    self.showProgressMessage(callback)
                });
            } else if (btnContainer.data('disableOnPrelink')) {
                btnContainer.find('.btn').addClass('disabled');
                this.showProgressMessage(callback);
            } else {
                this.showProgressMessage(callback);
            }
        } else {
            this.showProgressMessage(callback);
        }
    };

    this.displayError = function (provider, errorCondition, providerErrorText){
        jQuery('#providerLinkingMessages .provider-name').html(provider);

        var feedbackMsg = this.feedbackMessage('connect_error');
        if (errorCondition) {
            var errorMsg = this.feedbackMessage(errorCondition);
            if (errorMsg) {
                feedbackMsg = errorMsg
            }
        }

        if (providerErrorText && $('.btn-logged-in-admin').length > 0) {
            feedbackMsg += ' Error: ' + providerErrorText;
        }

        this.feedbackContainer().removeClass('alert-info alert-success')
            .addClass('alert alert-danger')
            .html(feedbackMsg).slideDown();
    };

    this.displaySuccess = function (data, context, provider) {
        var icon = provider.icon;
        var htmlTarget = context.htmlTarget;
        var targetLogin = context.targetLogin;
        var targetRegister = context.targetRegister;
        var displayName = provider.name;
        var feedbackMsg = '';

        switch (data.result) {
            case "logged_in":
            case "2fa_needed":
                feedbackMsg = this.feedbackMessage('2fa_needed');
                this.feedbackContainer().removeClass('alert-danger alert-warning alert-success')
                    .addClass('alert alert-info')
                    .html(feedbackMsg);
                    window.location = data.redirect_url
                        ? decodeURIComponent(data.redirect_url)
                        : decodeURIComponent(context.redirectUrl);
                break;

            case "linking_complete":
                var accountInfo = '';
                if (data.remote_account.email) {
                    accountInfo = data.remote_account.email;
                } else {
                    accountInfo = data.remote_account.firstname + " " + data.remote_account.lastname;
                }

                accountInfo = accountInfo.trim();

                feedbackMsg = this.feedbackMessage('linking_complete').trim().replace(':displayName', displayName);
                if (accountInfo) {
                    feedbackMsg = feedbackMsg.replace(/\.$/, ' (' + accountInfo + ').');
                }

                this.feedbackContainer().removeClass('alert-danger alert-warning alert-info')
                    .addClass('alert alert-success')
                    .html(icon + feedbackMsg);
                break;

            case "login_to_link":
                if (htmlTarget === targetLogin) {
                    feedbackMsg = this.feedbackMessage('login_to_link-signin-required');
                    this.feedbackContainer().removeClass('alert-danger alert-success alert-info')
                        .addClass('alert alert-warning')
                        .html(icon + feedbackMsg);
                } else {
                    var emailField = jQuery("input[name=email]");
                    var firstNameField = jQuery("input[name=firstname]");
                    var lastNameField = jQuery("input[name=lastname]");

                    if (emailField.val() === "") {
                        emailField.val(data.remote_account.email);
                    }

                    if (firstNameField.val() === "") {
                        firstNameField.val(data.remote_account.firstname);
                    }

                    if (lastNameField.val() === "") {
                        lastNameField.val(data.remote_account.lastname);
                    }

                    if (htmlTarget === targetRegister) {
                        if (typeof WHMCS.client.registration === 'object') {
                            WHMCS.client.registration.prefillPassword();
                        }
                        feedbackMsg = this.feedbackMessage('login_to_link-registration-required');
                        this.feedbackContainer().fadeOut('slow', function () {
                            $(this).removeClass('alert-danger alert-success alert-info')
                                .addClass('alert alert-warning')
                                .html(icon + feedbackMsg).fadeIn('fast');
                        });

                    } else {
                        // this is checkout
                        if (typeof WHMCS.client.registration === 'object') {
                            WHMCS.client.registration.prefillPassword();
                        }

                        var self = this;
                        this.feedbackContainer().each(function (i, el) {
                            var container = $(el);
                            var linkContext = container.siblings('div .providerPreLinking').data('linkContext');

                            container.fadeOut('slow', function () {
                                if (linkContext === 'checkout-new') {
                                    feedbackMsg = self.feedbackMessage('checkout-new');
                                } else {
                                    feedbackMsg = self.feedbackMessage('login_to_link-signin-required');
                                }
                                container.removeClass('alert-danger alert-success alert-info')
                                    .addClass('alert alert-warning')
                                    .html(icon + feedbackMsg).fadeIn('fast');
                            });
                        });
                    }
                }

                break;

            case "other_user_exists":
                feedbackMsg = this.feedbackMessage('other_user_exists');
                this.feedbackContainer().removeClass('alert-info alert-success')
                    .addClass('alert alert-danger')
                    .html(icon + feedbackMsg).slideDown();
                break;

            case "already_linked":
                feedbackMsg = this.feedbackMessage('already_linked');
                this.feedbackContainer().removeClass('alert-info alert-success')
                    .addClass('alert alert-danger')
                    .html(icon + feedbackMsg).slideDown();
                break;

            default:
                feedbackMsg = this.feedbackMessage('default');
                this.feedbackContainer().removeClass('alert-info alert-success')
                    .addClass('alert alert-danger')
                    .html(icon + feedbackMsg).slideDown();
                break;
        }
    };

    this.signIn = function (config, context, provider, providerDone, providerError) {
        jQuery.ajax(config).done(function(data) {
            providerDone();
            WHMCS.authn.provider.displaySuccess(data, context, provider);
            var table = jQuery('#tableLinkedAccounts');
            if (table.length) {
                WHMCS.ui.dataTable.getTableById('tableLinkedAccounts').ajax.reload();
            }
        }).error(function() {
            providerError();
            WHMCS.authn.provider.displayError();
        });
    };

    var sdkSourcePatterns = [];
    var sdkErrorHandlerRegistered = false;

    /**
     * Register a targeted error handler for sign-in SDK scripts.
     * Only displays sign-in errors when errors originate from the specified sources.
     *
     * @param {string[]} sourcePatterns - Array of URL patterns to match against error source
     */
    this.registerSdkErrorHandler = function (sourcePatterns) {
        var self = this;

        for (var i = 0; i < sourcePatterns.length; i++) {
            if (sdkSourcePatterns.indexOf(sourcePatterns[i]) === -1) {
                sdkSourcePatterns.push(sourcePatterns[i]);
            }
        }

        if (sdkErrorHandlerRegistered) {
            return;
        }
        sdkErrorHandlerRegistered = true;

        window.addEventListener('error', function (event) {
            var source = event.filename || '';
            for (var j = 0; j < sdkSourcePatterns.length; j++) {
                if (source.indexOf(sdkSourcePatterns[j]) !== -1) {
                    self.displayError();
                    return true;
                }
            }
            return false;
        });
    };

    return this;
}});

/**
 * WHMCS client module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2017
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */
(function(module) {
    if (!WHMCS.hasModule('client')) {
        WHMCS.loadModule('client', module);
    }
})({
registration: function () {
    this.prefillPassword = function (params) {
        params = params || {};
        if (typeof params.hideContainer === 'undefined') {
            var id = (jQuery('#inputSecurityQId').attr('id')) ? '#containerPassword' : '#containerNewUserSecurity';
            params.hideContainer = jQuery(id);
            params.hideInputs = true;
        } else if (typeof params.hideContainer === 'string' && params.hideContainer.length) {
            params.hideContainer = jQuery(params.hideContainer);
        }

        if (typeof params.form === 'undefined') {
            params.form = {
                password: [
                    {id: 'inputNewPassword1'},
                    {id: 'inputNewPassword2'}
                ]
            };
        }

        var prefillFunc = function () {
            var $randomPasswd = WHMCS.utils.simpleRNG();
            for (var i = 0, len = params.form.password.length; i < len; i++) {
                jQuery('#' + params.form.password[i].id)
                    .val($randomPasswd).trigger('keyup');
            }
        };

        if (params.hideInputs) {
            params.hideContainer.slideUp('fast', prefillFunc);
        } else {
            prefillFunc();
        }
    };

    return this;
},

tokenProcessor: function () {
    this.hostOrigin = window.location.origin;
    this.postForm = null;

    /**
     * @return Object A jQuery instance of auto-POST form
     */
    this.getAutoPostForm = function () {
        if (!this.postForm) {
            this.postForm = jQuery('<form>')
                .attr('id', 'whmcsAutoPostForm')
                .attr('target', '_self')
                .attr('method', 'POST')
                .append(
                    jQuery('<input>')
                        .attr('type', 'hidden')
                        .attr('name', 'token')
                        .attr('value', csrfToken)
                );

            jQuery('body').append(this.postForm);
        }

        return this.postForm;
    },

    /**
     * @param {URL} url
     * @return boolean
     */
    this.isSameOrigin = function (url) {
        return url.origin && (url.origin === this.hostOrigin);
    },

    /**
     * @param {URL} url
     * @return boolean
     */
    this.isClientModopCustom = function (url) {
        if (!url.pathname || !url.pathname.match(/\/clientarea.php$/)) {
            return false;
        }

        if (!url.searchParams || (url.searchParams.get('modop') !== 'custom')) {
            return false;
        }

        return true;
    },

    /**
     * Normalizes a string URL by converting it to a URL object and appending origin as necessary
     *
     * @param {string} urlString
     * @return URL
     */
    this.getFqUrl = function(urlString) {
        try {
            if (!urlString.match(/[a-z]+:\/\//i)) {
                // URLs without origin will not parse

                if (urlString.indexOf('/') !== 0) {
                    const whmcsPath = window.location.pathname.split('/').slice(0, -1).join('/');

                    urlString = `${whmcsPath}/${urlString}`;
                }

                urlString = `${this.hostOrigin}${urlString}`;
            }

            return url = new URL(urlString);
        } catch (e) {
            return null;
        }
    }

    /**
     * @param {URL|string} url
     * @return boolean
     */
    this.isUrlEligibleForToken = function (url) {
        if (typeof url === 'string') {
            url = this.getFqUrl(url);

            if (!url) {
                return false;
            }
        }

        if ((typeof url !== 'object')) {
            return false;
        }

        if (!this.isSameOrigin(url)) {
            return false;
        }

        return this.isClientModopCustom(url);
    },

    /**
     * @param {string} urlString
     * @param {string|null} target
     * @return void
     */
    this.submitUrlViaPost = function (urlString, target) {
        jQuery(this.getAutoPostForm())
            .attr('target', target || '_self')
            .attr('action', urlString)
            .submit();
    };

    /**
     * @return void
     */
    this.processTokenSubmitters = function () {
        jQuery('a').each((index, link) => {
            const urlString = jQuery(link).attr('href');

            if (!urlString) {
                return;
            }

            if (!this.isUrlEligibleForToken(urlString)) {
                return;
            }

            if (!jQuery(link).data('whmcs-tokenized')) {
                jQuery(link).data('whmcs-tokenized', true);

                jQuery(link).attr('href', '#');

                jQuery(link).on('click', (e) => {
                    let target = jQuery(link).attr('target');

                    if (e.metaKey || e.ctrlKey) {
                        target = '_blank';
                    }

                    e.preventDefault();
                    this.submitUrlViaPost(urlString, target);
                });

                jQuery(link).on('contextmenu', (e) => {
                    e.preventDefault();
                    return false;
                });
            }
        });
    }
}
});

/**
 * WHMCS HTTP module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2018
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */
(function(module) {
    if (!WHMCS.hasModule('http')) {
        WHMCS.loadModule('http', module);
    }
})({
jqClient: function () {
    _getSettings = function (url, data, success, dataType)
    {
        if (typeof url === 'object') {
            /*
                Settings may be the only argument
             */
            return url;
        }

        if (typeof data === 'function') {
            /*
                If 'data' is omitted, 'success' will come in its place
             */
            success = data;
            data = null;
        }

        return {
            url: url,
            data: data,
            success: success,
            dataType: dataType
        };
    };

    /**
     * @param url
     * @param data
     * @param success
     * @param dataType
     * @returns {*}
     */
    this.get = function (url, data, success, dataType)
    {
        return WHMCS.http.client.request(
            jQuery.extend(
                _getSettings(url, data, success, dataType),
                {
                    type: 'GET'
                }
            )
        );
    };

    /**
     * @param url
     * @param data
     * @param success
     * @param dataType
     * @returns {*}
     */
    this.post = function (url, data, success, dataType)
    {
        return WHMCS.http.client.request(
            jQuery.extend(
                _getSettings(url, data, success, dataType),
                {
                    type: 'POST'
                }
            )
        );
    };
    this.jsonGet = function (options) {
        options = options || {};
        this.get(options.url, options.data, function(response) {
            if (response.warning) {
                console.log('[WHMCS] Warning: ' + response.warning);
                if (typeof options.warning === 'function') {
                    options.warning(jsonResponse.warning, jsonResponse, jqXHR);
                }
            } else if (jsonResponse.error) {
                console.log('[WHMCS] Error: ' + jsonResponse.error);
                if (typeof options.error === 'function') {
                    options.error(jsonResponse.error, jsonResponse, jqXHR);
                }
                } else if (typeof options.success === 'function') {
                    options.success(jsonResponse, jqXHR);
            }
        }, 'json')
        .fail(function(jqXHR, jqResponseType, httpStatusText){
            console.log('[WHMCS] Fail: ' + jqResponseType);
            if (typeof options.fail === 'function') {
                options.fail(jqResponseType, jqXHR.responseJSON, jqXHR);
            }
        })
        .always(function(jqXHR, jqResponseType, httpStatusText) {
            if (typeof options.always === 'function') {
                options.always(jqXHR);
            }
        });
    };

    /**
     * @param options
     * @returns {*}
     */
    this.jsonPost = function (options) {
        options = options || {};
        this.post(options.url, options.data, function(jsonResponse, httpStatusText, jqXHR) {
            if (jsonResponse.warning) {
                console.log('[WHMCS] Warning: ' + jsonResponse.warning);
                if (typeof options.warning === 'function') {
                    options.warning(response.warning);
                }
            } else if (response.error) {
                console.log('[WHMCS] Error: ' + response.error);
                if (typeof options.error === 'function') {
                    options.error(response.error);
                }
            } else {
                if (typeof options.success === 'function') {
                    options.success(response);
                }
            }
        }, 'json').error(function(xhr, errorMsg){
            console.log('[WHMCS] Error: ' + errorMsg);
            if (typeof options.fail === 'function') {
                options.fail(errorMsg);
            }
        }).always(function() {
            if (typeof options.always === 'function') {
                options.always();
            }
        });
    };

    return this;
},

client: function () {
    var methods = ['get', 'post', 'put', 'delete'];
    var client = this;

    _beforeRequest = function (settings)
    {
        /*
            Enforcing dataType was found to break many invocations expecting HTML back.
            If/when those are refactored, this may be uncommented to enforce a safer
            data transit.
         */
        /*if (typeof settings.dataType === 'undefined') {
            settings.dataType = 'json';
        }*/

        if (typeof settings.type === 'undefined') {
            // default request type is GET
            settings.type = 'GET';
        }

        /*
            Add other preprocessing here if required
         */

        return settings;
    };

    this.request = function (settings)
    {
        settings = _beforeRequest(settings || {});
        return jQuery.ajax(settings);
    };

    /*
        Create shortcut methods for methods[] array above
     */
    jQuery.each(methods, function(index, method) {
        client[method] = (function(method, client) {
            return function (settings)
            {
                settings = settings || {};

                settings.type = method.toUpperCase();

                return client.request(settings);
            }
        })(method, client);
    });

    return this;
}

});

/**
 * WHMCS UI module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2017
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */
(function(module) {
    if (!WHMCS.hasModule('ui')) {
        WHMCS.loadModule('ui', module);
    }
})({
/**
 * Confirmation PopUp
 */
confirmation: function () {

    /**
     * @type {Array} Registered confirmation root selectors
     */
    var toggles = [];

    /**
     * Register/Re-Register all confirmation elements with jQuery
     * By default all elements of data toggle "confirmation" will be registered
     *
     * @param {(string|undefined)} rootSelector
     * @return {Array} array of registered toggles
     */
    this.register = function (rootSelector) {
        if (typeof rootSelector === 'undefined') {
            rootSelector = '[data-toggle=confirmation]';
        }
        if (toggles.indexOf(rootSelector) < 0) {
            toggles.push(rootSelector);
        }

        jQuery(rootSelector).confirmation({
            rootSelector: rootSelector
        });

        return toggles;
    };

    return this;
},

/**
 * Data Driven Table
 */
dataTable: function () {

    /**
     * @type {{}}
     */
    this.tables = {};

    /**
     * Register all tables on page with the class "data-driven"
     */
    this.register = function () {
        var self = this;
        jQuery('table.data-driven').each(function (i, table) {
            self.getTableById(table.id, undefined);
        });
    };

    /**
     * Get a table by id; create table object on fly as necessary
     *
     * @param {string} id
     * @param {({}|undefined)} options
     * @returns {DataTable}
     */
    this.getTableById = function (id, options) {
        var self = this;
        var el = jQuery('#' + id);
        if (typeof self.tables[id] === 'undefined') {
            if (typeof options === 'undefined') {
                options = {
                    dom: '<"listtable"ift>pl',
                    paging: false,
                    lengthChange: false,
                    searching: false,
                    ordering: true,
                    info: false,
                    autoWidth: true,
                    columns: [],
                    lengthMenu: [10, 25, 50, 100, 500, 1000],
                    language: {
                        emptyTable: (el.data('langEmptyTable')) ? el.data('langEmptyTable') : "No records found"
                    }
                };
            }
            jQuery.each(el.data(), function (key, value) {
                if (typeof value === 'undefined') {
                    return;
                }
                if (key === 'ajaxUrl') {
                    options.ajax = {
                        url: value
                    };
                    return;
                }
                if (key === 'lengthChange') {
                    options.lengthChange = value;
                    return;
                }
                if (key === 'pageLength') {
                    options.pageLength = value;
                    return;
                }
                if (key === 'langEmptyTable') {
                    if (typeof options.language === "undefined") {
                        options.language = {};
                    }
                    options.language.emptyTable = value;
                    return
                }
                if (key === 'langZeroRecords') {
                    if (typeof options.language === "undefined") {
                        options.language = {};
                    }
                    options.language.zeroRecords = value;
                    return
                }
                options.key = value;
            });
            jQuery.each(el.find('th'), function() {
                if (typeof options.columns === "undefined") {
                    options.columns = [];
                }
                options.columns.push({data:jQuery(this).data('name')});
            });


            self.tables[id] = self.initTable(el, options);
        } else if (typeof options !== 'undefined') {
            var oldTable = self.tables[id];
            var initOpts = oldTable.init();
            var newOpts = jQuery.extend( initOpts, options);
            oldTable.destroy();
            self.tables[id] = self.initTable(el, newOpts);
        }

        return self.tables[id];
    };

    this.initTable = function (el, options) {
        var table = el.DataTable(options);
        var self = this;
        if (el.data('on-draw')) {
            table.on('draw.dt', function (e, settings) {
                var namedCallback = el.data('on-draw');
                if (typeof window[namedCallback] === 'function') {
                    window[namedCallback](e, settings);
                }
            });
        } else if (el.data('on-draw-rebind-confirmation')) {
            table.on('draw.dt', function (e) {
                self.rebindConfirmation(e);
            });
        }

        return table;
    };

    this.rebindConfirmation = function (e) {
        var self = this;
        var tableId = e.target.id;
        var toggles = WHMCS.ui.confirmation.register();
        for(var i = 0, len = toggles.length; i < len; i++ ) {
            jQuery(toggles[i]).on(
                'confirmed.bs.confirmation',
                function (e)
                {
                    e.preventDefault();
                    WHMCS.http.jqClient.post(
                        jQuery(e.target).data('target-url'),
                        {
                            'token': csrfToken
                        }
                    ).done(function (data)
                    {
                        if (data.status === 'success' || data.status === 'okay') {
                            self.getTableById(tableId, undefined).ajax.reload();
                        }
                    });

                }
            );
        }
    };

    return this;
},

clipboard: function() {
    this.copy = function(e) {
        e.preventDefault();

        var trigger = $(e.currentTarget);
        var contentElement = $(trigger).data('clipboard-target');
        var container = $(contentElement).parent();

        try {
            var tempElement = $('<textarea>')
                .css('position', 'fixed')
                .css('opacity', '0')
                .css('width', '1px')
                .css('height', '1px')
                .val($(contentElement).val());

            container.append(tempElement);
            tempElement.focus().select();
            document.execCommand('copy');
        } finally {
            tempElement.remove();
        }

        trigger.tooltip({
            trigger: 'click',
            placement: 'bottom'
        });

        WHMCS.ui.toolTip.setTip(trigger, 'Copied!');
        WHMCS.ui.toolTip.hideTip(trigger);
    };
    return this;
},

/**
 * ToolTip and Clipboard behaviors
 */
toolTip: function () {
    this.setTip = function (btn, message) {
        var tip = btn.data('bs.tooltip');
        if (tip.hoverState !== 'in') {
            tip.hoverState = 'in';
        }
        btn.attr('data-original-title', message);
        tip.show();

        return tip;
    };

    this.hideTip = function (btn, timeout) {
        if (!timeout) {
            timeout = 2000;
        }
        return setTimeout(function() {
            btn.data('bs.tooltip').hide()
        }, timeout);
    }
},

jsonForm: function() {
    this.managedElements = 'input,textarea,select';

    this.initFields = function (form) {
        var self = this;
        $(form).find(self.managedElements).each(function () {
            var field = this;

            $(field).on('keypress change', function () {
                if (self.fieldHasError(field)) {
                    self.clearFieldError(field);
                }
            });
        });
    };

    this.init = function (form) {
        var self = this;

        self.initFields(form);

        $(form).on('submit', function(e) {
            e.preventDefault();
            e.stopPropagation();

            self.clearErrors(form);

            var formModal = $(form).parents('.modal[role="dialog"]').first();

            if ($(formModal).length) {
                $(formModal).on('show.bs.modal hidden.bs.modal', function() {
                    self.clearErrors(form);
                });

                /*
                 * Make this optional if the form is used for editing
                 */
                $(formModal).on('show.bs.modal', function() {
                    $(form)[0].reset();
                });
            }

            WHMCS.http.client.post({
                url: $(form).attr('action'),
                data: $(form).serializeArray(),
            })
                .done(function (response) {
                    self.onSuccess(form, response);
                })
                .fail(function (jqXHR) {
                    self.onError(form, jqXHR);
                })
                .always(function (data) {
                    self.onRequestComplete(form, data);
                });
        });
    };

    this.initAll = function () {
        var self = this;

        $('form[data-role="json-form"]').each(function() {
            var formElement = this;
            self.init(formElement);
        });
    };

    this.markFieldErrors = function (form, fields)
    {
        var self = this;
        var errorMessage = null;
        var field, fieldLookup;

        for (var fieldName in fields) {
            if (fields.hasOwnProperty(fieldName)) {
                errorMessage = fields[fieldName];
            }

            fieldLookup = self.managedElements.split(',').map(function(element) {
                return element + '[name="' + fieldName + '"]';
            }).join(',');

            field = $(form).find(fieldLookup);

            if (errorMessage) {
                $(field).parents('.form-group').addClass('has-error');
                $(field).attr('title', errorMessage);
                $(field).tooltip();
            }
        }

        $(form).find('.form-group.has-error input[title]').first().tooltip('show');
    };

    this.fieldHasError = function (field) {
        return $(field).parents('.form-group').hasClass('has-error');
    };

    this.clearFieldError = function (field) {
        /**
         * Try dispose first for BS 4, which will raise error
         * on BS 3 or older, then we use destroy instead
         */
        try {
            $(field).tooltip('dispose');
        } catch (err) {
            $(field).tooltip('destroy');
        }
        $(field).parents('.form-group').removeClass('has-error');
    };

    this.onSuccess = function (form, response) {
        var formOnSuccess = $(form).data('on-success');

        if (typeof formOnSuccess === 'function') {
            formOnSuccess(response.data);
        }
    };

    this.onError = function (form, jqXHR) {
        if (jqXHR.responseJSON && jqXHR.responseJSON.fields && typeof jqXHR.responseJSON.fields === 'object') {
            this.markFieldErrors(form, jqXHR.responseJSON.fields);
        } else {
            // TODO: replace with client-accessible generic error messaging
            console.log('Unknown error - please try again later.');
        }

        var formOnError = $(form).data('on-error');

        if (typeof formOnError === 'function') {
            formOnError(jqXHR);
        }
    };

    this.clearErrors = function (form) {
        var self = this;

        $(form).find(self.managedElements).each(function () {
            self.clearFieldError(this);
        })
    };

    this.onRequestComplete = function (form, data) {
        // implement as needed
    };

    return this;
},

effects: function () {
    this.errorShake = function (element) {
        /**
         * Shake effect without jQuery UI inspired by Hiren Patel | ninty9notout:
         * @see https://github.com/ninty9notout/jquery-shake/blob/51f3dcf625970c78505bcac831fd9e28fc85d374/jquery.ui.shake.js
         */
        options = options || {};
        var options = $.extend({
            direction: "left",
            distance: 8,
            times: 3,
            speed: 90
        }, options);

        return element.each(function () {
            var el = $(this), props = {
                position: el.css("position"),
                top: el.css("top"),
                bottom: el.css("bottom"),
                left: el.css("left"),
                right: el.css("right")
            };

            el.css("position", "relative");

            var ref = (options.direction === "up" || options.direction === "down") ? "top" : "left";
            var motion = (options.direction === "up" || options.direction === "left") ? "pos" : "neg";

            var animation = {}, animation1 = {}, animation2 = {};
            animation[ref] = (motion === "pos" ? "-=" : "+=") + options.distance;
            animation1[ref] = (motion === "pos" ? "+=" : "-=") + options.distance * 2;
            animation2[ref] = (motion === "pos" ? "-=" : "+=") + options.distance * 2;

            el.animate(animation, options.speed);
            for (var i = 1; i < options.times; i++) {
                el.animate(animation1, options.speed).animate(animation2, options.speed);
            }

            el.animate(animation1, options.speed).animate(animation, options.speed / 2, function () {
                el.css(props);
            });
        });
    };
},
/*
<script>WHMCS.ui.markdownEditor.register()</script>
<someTag id="someTag-node"
    class="container-markdown-editor editor-tagging local-storage"
    data-locale="de"
    data-local-storage-id="someTag-node-session-1234"
    data-fetch-preview-url="https://x.local/mde/preview"
    data-fetch-help-url="https://x.local/mde/help"
    data-tagging-url="url-to-handle-tagging"
    />
NOTE: elements without IDs will not be initialized via `register` or `getEditorById`
to ensure no target node is reinitialized within a previously initialized node.
 */
markdownEditor: function () {
    this.editors = {};
    this.counters = {};
    this.register = function () {
        let self = this;
        jQuery('.container-markdown-editor')
            .each(function (i, el) {
                el = jQuery(el);
                if (typeof el.attr('id') === "undefined") {
                    console.debug('Element has no id', el);
                    return;
                }
                self.getEditorById(el.attr('id'));
                self.withTagging(el);
            });
    };
    this.withTagging = function(el) {
        if (!el.is('.editor-tagging')) {
            return;
        }
        el.atwho({
            at: "@",
            displayTpl: "<li class=\"mention-list\">${gravatar} ${username} - ${name} (${email})</li>",
            insertTpl: mentionsFormat,
            data: el.data('tagging-url'),
            limit: 5
        });
    }
    this.getEditorById = function(id) {
        let self = this;
        let el = jQuery('#' + id);
        if (typeof self.editors[id] === 'undefined') {
            self.editors[id] = self.init(el);
        }

        return self.editors[id];
    };
    this.init = function (element) {
        let self = this;
        let elementId = element.attr('id');
        let footerId = elementId + '-footer';
        let footerIdRef = '#' + footerId;
        let footerNode ='<div id="'
            + footerId
            + '" class="markdown-editor-status"></div>';
        let locale = (typeof element.data('locale') === 'undefined')
            ? 'en'
            : element.data('locale');
        let localStorageId = element.data('localStorageId');
        let csrf_token = csrfToken;
        let fetchPreviewUrl = element.data('fetchPreviewUrl');
        self.counters[elementId] = 0;

        element.markdown(
            {
                footer: footerNode,
                autofocus: false,
                savable: false,
                resize: 'vertical',
                iconlibrary: 'glyph',
                language: locale,
                onShow: function(e){
                    let content = '',
                        save_enabled = false;
                    if(typeof(Storage) !== "undefined") {
                        // Code for localStorage/sessionStorage.
                        content = localStorage.getItem(localStorageId);
                        save_enabled = true;
                        if (content && typeof(content) !== "undefined") {
                            e.setContent(content);
                        }
                    }
                    jQuery(footerIdRef).html(
                        self.parseMdeFooter(content, save_enabled, 'saved')
                    );
                },
                onChange: function(e){
                    let content = e.getContent(),
                        save_enabled = false;
                        elementId = e.$element.attr('id');
                    if(typeof(Storage) !== "undefined") {
                        self.counters[elementId] = 3;
                        save_enabled = true;
                        localStorage.setItem(localStorageId, content);
                        self.doCountdown(elementId);
                    }
                    jQuery(footerIdRef).html(
                        self.parseMdeFooter(content, save_enabled)
                    );
                },
                onPreview: function(e){
                    let originalContent = e.getContent(),
                        parsedContent;

                    jQuery.ajax({
                        url: fetchPreviewUrl,
                        async: false,
                        data: {
                            token: csrf_token,
                            action: 'parseMarkdown',
                            content: originalContent
                        },
                        dataType: 'json',
                        success: function (data) {
                            parsedContent = data;
                        },
                        method: 'POST'
                    });

                    return parsedContent.body ? parsedContent.body : '';
                },
                additionalButtons: [
                    [{
                        name: "groupCustom",
                        data: [{
                            name: "cmdHelp",
                            title: "Help",
                            hotkey: "Ctrl+F1",
                            btnClass: "btn open-modal",
                            icon: {
                                glyph: 'fas fa-question-circle',
                                fa: 'fas fa-question-circle',
                                'fa-3': 'icon-question-sign'
                            },
                            callback: function(e) {
                                e.$editor.removeClass("md-fullscreen-mode");
                            }
                        }]
                    }]
                ],
                hiddenButtons: [
                    'cmdImage'
                ],
            }
        );

        self.addEventHelpModal(element);

        return element;
    };
    this.parseMdeFooter = function(content, auto_save, saveText) {
        if (typeof saveText == 'undefined') {
            saveText = 'autosaving';
        }
        let pattern = /[^\s]+/g,
            m = [],
            word_count = 0,
            line_count = 0;
        if (content) {
            m = content.match(pattern);
            line_count = content.split(/\\r\\n|\\r|\\n/).length;
        }
        if (m) {
            for(let i = 0; i < m.length; i++) {
                if(m[i].charCodeAt(0) >= 0x4E00) {
                    word_count += m[i].length;
                } else {
                    word_count += 1;
                }
            }
        }
        return '<div class="smallfont">lines: ' + line_count
            + '&nbsp;&nbsp;&nbsp;words: ' + word_count + ''
            + (auto_save
                    ? '&nbsp;&nbsp;&nbsp;<span class="markdown-save">' + saveText + '</span>'
                    : ''
            )
            + '</div>';
    };
    this.doCountdown = function(elementId) {
        let self = this;
        if (self.counters[elementId] >= 0) {
            if (self.counters[elementId] === 0) {
                jQuery("span.markdown-save").html('saved');
            }
            self.counters[elementId]--;
            setTimeout(function (id) {
                self.doCountdown(id)},
                1000,
                elementId
            );
        }
    };
    this.addEventHelpModal = function(element) {
        element.parent().find('button[data-handler="bootstrap-markdown-cmdHelp"]')
            .attr('data-modal-title', 'Markdown Guide')
            .attr('data-modal-size', 'modal-lg')
            .attr('href', element.data('fetchHelpUrl'));
        return this;
    };
}
});



/**
 * Form module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2017
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */
(function(module) {
    if (!WHMCS.hasModule('form')) {
        WHMCS.loadModule('form', module);
    }
})(
function () {
    this.checkAllBound = false;

    this.register = function () {
        if (!this.checkAllBound) {
            this.bindCheckAll();
            this.checkAllBound = true;
        }
    };

    this.bindCheckAll = function ()
    {
        var huntSelector = '.btn-check-all';
        jQuery('body').on('click', huntSelector, function (e) {
            var btn = jQuery(e.target);
            var targetInputs = jQuery(
                '#' + btn.data('checkbox-container') + ' input[type="checkbox"]'
            );
            if (btn.data('btn-check-toggle')) {
                // one control that changes
                var textDeselect = 'Deselect All';
                var textSelect = 'Select All';
                if (btn.data('label-text-deselect')) {
                    textDeselect = btn.data('label-text-deselect');
                }
                if (btn.data('label-text-select')) {
                    textSelect = btn.data('label-text-select');
                }

                if (btn.hasClass('toggle-active')) {
                    targetInputs.prop('checked',false);
                    btn.text(textSelect);
                    btn.removeClass('toggle-active');
                } else {
                    targetInputs.prop('checked',true);
                    btn.text(textDeselect);
                    btn.addClass('toggle-active');
                }
            } else {
                // two controls that are static
                if (btn.data('btn-toggle-on')) {
                    targetInputs.prop('checked',true);
                } else {
                    targetInputs.prop('checked',false);
                }
            }
        });
    };

    this.reloadCaptcha = (captchaElement) => {
        if (typeof grecaptcha !== 'undefined') {
            recaptchaValidationComplete = false;
            grecaptcha.reset();

            WHMCS.recaptcha.restoreDefaultCallback();

            return;
        }

        if (!captchaElement) {
            captchaElement = jQuery('#inputCaptchaImage');
        }

        const captchaInput = jQuery('#inputCaptcha');

        if (captchaElement.length) {
            captchaElement.attr(
                'src',
                whmcsBaseUrl + '/includes/verifyimage.php?nocache=' + new Date().getTime()
            );

            captchaInput.val('');
        }
    };
    return this;
});

/**
 * reCaptcha module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2020
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */
var recaptchaLoadComplete = false,
    recaptchaCount = 0,
    recaptchaType = 'recaptcha',
    recaptchaValidationComplete = false;
    var PASSWORD_RESET_BUTTON_ID = 'resetPasswordButton';

(function(module) {
    if (!WHMCS.hasModule('recaptcha')) {
        WHMCS.loadModule('recaptcha', module);
    }
})(
    function () {

        this.register = function () {
            if (recaptchaLoadComplete) {
                return;
            }
            var postLoad = [],
                recaptchaForms = jQuery(".btn-recaptcha").parents('form'),
                isInvisible = false;
            recaptchaForms.each(function (i, el){
                if (typeof recaptchaSiteKey === 'undefined') {
                    console.log('Recaptcha site key not defined');
                    return;
                }
                recaptchaCount += 1;
                var frm = jQuery(el),
                    btnRecaptcha = frm.find(".btn-recaptcha"),
                    required = (typeof requiredText !== 'undefined') ? requiredText : 'Required',
                    recaptchaId = 'divDynamicRecaptcha' + recaptchaCount;

                isInvisible = btnRecaptcha.hasClass('btn-recaptcha-invisible')

                // if no recaptcha element, make one
                var recaptchaContent = frm.find('#' + recaptchaId + ' .g-recaptcha'),
                    recaptchaElement = frm.find('.recaptcha-container'),
                    appendElement = frm;

                if (recaptchaElement.length) {
                    recaptchaElement.attr('id', recaptchaElement.attr('id') + recaptchaCount);
                    appendElement = recaptchaElement;
                }
                if (!recaptchaContent.length) {
                    appendElement.append('<div id="#' + recaptchaId + '" class="g-recaptcha"></div>');
                    recaptchaContent = appendElement.find('#' + recaptchaId);
                }
                // propagate invisible recaptcha if necessary
                if (!isInvisible) {
                    recaptchaContent.data('toggle', 'tooltip')
                        .data('placement', 'bottom')
                        .data('trigger', 'manual')
                        .attr('title', required)
                        .hide();
                }


                // alter form to work around JS behavior on .submit() when there
                // there is an input with the name 'submit'
                var btnSubmit = frm.find("input[name='submit']");
                if (btnSubmit.length) {
                    var action = frm.prop('action');
                    frm.prop('action', action + '&submit=1');
                    btnSubmit.remove();
                }

                // make callback for grecaptcha to invoke after
                // injecting token & make it known via data-callback
                var funcName = recaptchaId + 'Callback';
                window[funcName] = function () {
                    if (isInvisible) {
                        frm.submit();
                    }
                };

                // setup an on form submit event to ensure that we
                // are allowing required field validation to occur before
                // we do the invisible recaptcha checking
                if (isInvisible) {
                    recaptchaType = 'invisible';
                    frm.on('submit.recaptcha', function (event) {
                        var recaptchaId = frm.find('.g-recaptcha').data('recaptcha-id');
                        if (!grecaptcha.getResponse(recaptchaId).trim()) {
                            event.preventDefault();
                            grecaptcha.execute(recaptchaId);
                            recaptchaValidationComplete = false;
                        } else {
                            recaptchaValidationComplete = true;
                        }
                    });
                } else {
                    postLoad.push(function () {
                        recaptchaContent.slideDown('fast', function() {
                            // just in case there's a delay in DOM; rare
                            recaptchaContent.find(':first').addClass('center-block');
                        });
                    });
                    postLoad.push(function() {
                        recaptchaContent.find(':first').addClass('center-block');
                    });
                }
            });

            window.recaptchaLoadCallback = function() {
                jQuery('.g-recaptcha').each(function(i, el) {
                    var element = jQuery(el),
                        frm = element.closest('form'),
                        btn = frm.find('.btn-recaptcha'),
                        idToUse = element.attr('id').substring(1);
                    var recaptchaId = grecaptcha.render(
                        el,
                        {
                            sitekey: recaptchaSiteKey,
                            size: (btn.hasClass('btn-recaptcha-invisible')) ? 'invisible' : 'normal',
                            callback: idToUse + 'Callback'
                        }
                    );
                    element.data('recaptcha-id', recaptchaId);
                });
            }

            // fetch/invoke the grecaptcha lib
            if (recaptchaForms.length) {
                var gUrl = "https://www.google.com/recaptcha/api.js?onload=recaptchaLoadCallback&render=explicit";
                jQuery.getScript(gUrl, function () {
                    for(var i = postLoad.length - 1; i >= 0 ; i--){
                        postLoad[i]();
                    }
                });
            }
            recaptchaLoadComplete = true;
        };

        this.setupCallback = (callback) => {
            if (typeof callback !== 'function') {
                return;
            }

            jQuery('.g-recaptcha').each(function(i, el) {
                const idToUse = jQuery(el).attr('id').substring(1);
                const originalCallbackName = idToUse + 'Callback';
                const backupCallbackName = originalCallbackName + 'Original';


                if (typeof window[backupCallbackName] === 'undefined') {
                    window[backupCallbackName] = window[originalCallbackName];
                }

                window[originalCallbackName] = callback;
            });
        }

        this.restoreDefaultCallback = () => {
            jQuery('.g-recaptcha').each(function(i, el) {
                const idToUse = jQuery(el).attr('id').substring(1);
                const originalCallbackName = idToUse + 'Callback';
                const backupCallbackName = originalCallbackName + 'Original';

                if (typeof window[backupCallbackName] !== 'undefined') {
                    window[originalCallbackName] = window[backupCallbackName];
                    delete window[backupCallbackName];
                }
            });
        }

        return this;
    });
    
/**
 * General utilities module
 *
 * @copyright Copyright (c) WHMCS Limited 2005-2017
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */
(function(module) {
    if (!WHMCS.hasModule('utils')) {
        WHMCS.loadModule('utils', module);
    }
})(
function () {
    /**
     * Not crypto strong; server-side must discard for
     * something with more entropy; the value is sufficient
     * for strong client-side validation check
     */
    this.simpleRNG = function () {
        var chars = './$_-#!,^*()|';
        var r = 0;
        for (var i = 0; r < 3; i++) {
            r += Math.floor((Math.random() * 10) / 2);
        }
        r = Math.floor(r);
        var s = '';
        for (var x = 0; x < r; x++) {
            v = (Math.random() + 1).toString(24).split('.')[1];
            if ((Math.random()) > 0.5) {
                s += btoa(v).substr(0,4)
            } else {
                s += v
            }

            if ((Math.random()) > 0.5) {
                s += chars.substr(
                    Math.floor(Math.random() * 13),
                    1
                );
            }
        }

        return s;
    };

    this.getRouteUrl = function (path) {
        return whmcsBaseUrl + "/index.php?rp=" + path;
    };

    this.validateBaseUrl = function() {
        if (typeof window.whmcsBaseUrl === 'undefined') {
            console.log('Warning: The WHMCS Base URL definition is missing '
                + 'from your active template. Please refer to '
                + 'https://go.whmcs.com/1961/base-url '
                + 'for more information and details of how to resolve this '
                + 'warning.');
            window.whmcsBaseUrl = this.autoDetermineBaseUrl();
            window.whmcsBaseUrlAutoSet = true;
        } else if (window.whmcsBaseUrl === ''
            && typeof window.whmcsBaseUrlAutoSet !== 'undefined'
            && window.whmcsBaseUrlAutoSet === true
        ) {
            window.whmcsBaseUrl = this.autoDetermineBaseUrl();
        }
    };

    this.autoDetermineBaseUrl = function() {
        var windowLocation = window.location.href;
        var phpExtensionLocation = -1;

        if (typeof windowLocation !== 'undefined') {
            phpExtensionLocation = windowLocation.indexOf('.php');
        }

        if (phpExtensionLocation === -1) {
            windowLocation = jQuery('#Primary_Navbar-Home a').attr('href');
            if (typeof windowLocation !== 'undefined') {
                phpExtensionLocation = windowLocation.indexOf('.php');
            }
        }

        if (phpExtensionLocation !== -1) {
            windowLocation = windowLocation.substring(0, phpExtensionLocation);
            var lastTrailingSlash = windowLocation.lastIndexOf('/');
            if (lastTrailingSlash !== false) {
                return windowLocation.substring(0, lastTrailingSlash);
            }
        }

        return '';
    };

    this.normaliseStringValue = function(status) {
        return status ? status.toLowerCase().replace(/\s/g, '-') : '';
    };

    this.generatePassword = function(len) {
        var charset = this.getPasswordCharacterSet();
        var result = "";
        for (var i = 0; len > i; i++)
            result += charset[this.randomInt(charset.length)];
        return result;
    };
    this.getPasswordCharacterSet = function() {
        var rawCharset = '0123456789'
            + 'abcdefghijklmnopqrstuvwxyz'
            + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
            + '!#$%()*+,-.:;=@_|{ldelim}{rdelim}~';

        // Parse UTF-16, remove duplicates, convert to array of strings
        var charset = [];
        for (var i = 0; rawCharset.length > i; i++) {
            var c = rawCharset.charCodeAt(i);
            if (0xD800 > c || c >= 0xE000) {  // Regular UTF-16 character
                var s = rawCharset.charAt(i);
                if (charset.indexOf(s) == -1)
                    charset.push(s);
                continue;
            }
            if (0xDC00 > c ? rawCharset.length > i + 1 : false) {  // High surrogate
                var d = rawCharset.charCodeAt(i + 1);
                if (d >= 0xDC00 ? 0xE000 > d : false) {  // Low surrogate
                    var s = rawCharset.substring(i, i + 2);
                    i++;
                    if (charset.indexOf(s) == -1)
                        charset.push(s);
                    continue;
                }
            }
            throw "Invalid UTF-16";
        }
        return charset;
    };
    this.randomInt = function(n) {
        var x = this.randomIntMathRandom(n);
        x = (x + this.randomIntBrowserCrypto(n)) % n;
        return x;
    };
    this.randomIntMathRandom = function(n) {
        var x = Math.floor(Math.random() * n);
        if (0 > x || x >= n)
            throw "Arithmetic exception";
        return x;
    };
    this.randomIntBrowserCrypto = function(n) {
        var cryptoObject = null;

        if ("crypto" in window)
            cryptoObject = crypto;
        else if ("msCrypto" in window)
            cryptoObject = msCrypto;
        else
            return 0;

        if (!("getRandomValues" in cryptoObject) || !("Uint32Array" in window) || typeof Uint32Array != "function")
            cryptoObject = null;

        if (cryptoObject == null)
            return 0;

        // Generate an unbiased sample
        var x = new Uint32Array(1);
        do cryptoObject.getRandomValues(x);
        while (x[0] - x[0] % n > 4294967296 - n);
        return x[0] % n;
    };

    return this;
});

WHMCS.utils.validateBaseUrl();

jQuery(document).ready(function() {
    jQuery('#main-body').on('click', '.product-recommendations .product-recommendation .header', function(e) {
        if (jQuery(e.target).is('.btn, .btn span, .btn .fa')) {
            return;
        }
        e.preventDefault();
        if (jQuery('.fa-square', this).length > 0) {
            return;
        }
        jQuery(this).parent().find('.rotate').toggleClass('down');
        jQuery(this).parent().find('.body').slideToggle('fast');
    }).on('click', '.product-recommendations .product-recommendation .btn-add', function() {
        jQuery(this).attr('disabled', 'disabled')
            .find('span.arrow i')
            .removeClass('fa-chevron-right')
            .addClass('fa-spinner fa-spin');
    }).on('click', '.order-button, .order-btn, .btn-order-now', function(e) {
        if (jQuery(this).data('hasRecommendations') == 1) {
            e.preventDefault();
            var href = jQuery(this).attr('href');
            jQuery('i', this).removeClass().addClass('fas fa-spinner fa-spin');
            displayRecommendations(
                href,
                'addproductajax=1',
                true
            ).done(function() {
                window.location = href;
            });
        }
    });
    setRecommendationColors();
    if (document.URL.includes('cart.php?a=checkout') || document.URL.includes('cart.php?a=view')) {
        if (jQuery('#recommendationsModal .product-recommendation:not(.clonable)').length > 0) {
            jQuery('#recommendationsModal').modal('toggle');
        }
    }
});

function getRecommendationColors(hex, percentage) {
    var primary = tinycolor(hex),
        secondary,
        text = tinycolor('fff'),
        brightness = Math.round(Math.min(primary.getBrightness()/255) * 100),
        baseBrightnessPercent = 25;
    if (brightness < baseBrightnessPercent) {
        primary.lighten(baseBrightnessPercent - brightness);
    } else if (brightness > (100 - baseBrightnessPercent)) {
        primary.darken(brightness - (100 - baseBrightnessPercent));
    }
    secondary = primary.clone().darken(percentage);
    if (secondary.isLight()) {
        text = tinycolor('000');
    }
    return [primary.toHexString(), secondary.toHexString(), text.toHexString()];
};

function setRecommendationColors() {
    var colors,
        defaultColor = '#9abb3a';
    jQuery('.product-recommendations .product-recommendation').each(function() {
        var element = jQuery(this),
            primaryColor = element.data('color');
        if (!(primaryColor.length > 0) || (primaryColor.match(/^#[0-9A-Fa-f]{3,6}$/gi) == undefined)) {
            primaryColor = defaultColor;
        }
        colors = getRecommendationColors(primaryColor, 15);
        element.css('border-color', colors[0]);
        jQuery('.btn-add', element).css('background-color', colors[0]);
        jQuery('.expander', element).css('color', colors[0]);
        jQuery('.price', element).css('color', colors[1]);
        jQuery('.text', element).css({'color': colors[2]});
        jQuery('.arrow', element).css({'background-color': colors[1], 'color': colors[2]});
    });
}

function displayRecommendations(postUrl, postData, postForce) {
    var deferredObject = jQuery.Deferred(),
        hasRecommendations = jQuery('#divProductHasRecommendations').data('value'),
        modal = jQuery('#recommendationsModal'),
        shoppingCartBtn = jQuery('.cart-btn .badge');
    if (postForce || hasRecommendations) {
        jQuery('.cart-body button[type="submit"] i')
            .removeClass('fa-arrow-circle-right')
            .addClass('fa-spinner fa-spin');
        WHMCS.http.jqClient.jsonPost({
            url: postUrl,
            data: postData,
            success: function(data) {
                if (data.success && data.href) {
                    modal.on('hide.bs.modal', function() {
                        window.location = data.href;
                        return false;
                    });
                    jQuery('#btnContinueRecommendationsModal', modal)
                        .attr('href', data.href)
                        .click(function () {
                            jQuery('span', this).removeClass('w-hidden hidden');
                        });
                    jQuery('.modal-body', modal).html('').html(data.html);
                    setRecommendationColors();
                    modal.modal('show');
                    jQuery('i.fa-spinner.fa-spin:visible').removeClass('fa-spinner fa-spin').addClass('fa-check-circle');
                    shoppingCartBtn.text(data.count);
                } else if (!data.success && data.href) {
                    window.location = data.href;
                } else {
                    deferredObject.resolve(false);
                }
            },
            error: function() {
                deferredObject.resolve(false);
            }
        });
    } else {
        deferredObject.resolve(false);
    }
    return deferredObject.promise();
}

if (typeof localTrans === 'undefined') {
    localTrans = function (phraseId, fallback)
    {
        if (typeof _localLang !== 'undefined') {
            if (typeof _localLang[phraseId] !== 'undefined') {
                if (_localLang[phraseId].length > 0) {
                    return _localLang[phraseId];
                }
            }
        }

        return fallback;
    }
}

var domainLookupCallCount,
    furtherSuggestions,
    hideCvcOnCheckoutForExistingCard = 0;




jQuery(document).ready(function () {
    $('[data-toggle="tooltip"]').tooltip();
    var cardNumber = jQuery('#inputCardNumber'),
        existingCvv = jQuery('#inputCardCVV2');
    if (cardNumber.length) {
        cardNumber.payment('formatCardNumber');
        jQuery('#inputCardCVV').payment('formatCardCVC');
        jQuery('#inputCardStart').payment('formatCardExpiry');
        jQuery('#inputCardExpiry').payment('formatCardExpiry');
    }
    if (existingCvv.length) {
        existingCvv.payment('formatCardCVC');
    }

    /*
    *******************************************
    1. Product domain search box
    *******************************************
    */
 
    jQuery(".panel-domain-option input").each(function(){
        let that = $(this);
        setTimeout(function(){
            if (that[0].checked === true){
                that.closest('.radio-styled').addClass('checked');
                var value = that.val();
                jQuery("#domain" + value).removeClass('hidden');
            }
        },50)
    });
    setTimeout(function(){
        var checkedOption = jQuery(".panel-domain-option .radio-styled.checked");
        if (!checkedOption.length){
            var firstInput = jQuery(".panel-domain-option input:first");
            jQuery(firstInput).iCheck('check');
            jQuery("#domain" + jQuery(".panel-domain-option input:first").val()).removeClass('hidden');
        }
    }, 60)

    jQuery(".panel-domain-option input").on('ifChecked', function (event) {
        jQuery(".inline-form").addClass('hidden');
        jQuery("#domain" + jQuery(this).val()).removeClass('hidden');
    });
    /*
    *******************************************
    2. Product domain search results
    *******************************************
    */
   jQuery('#frmProductDomain').submit(function (e) {
    e.preventDefault();
    var btnSearchObj = jQuery(this).find('button[type="submit"]'),
        domainSearchResults = jQuery("#DomainSearchResults"),
        spotlightTlds = jQuery('#spotlightTlds'),
        suggestions = jQuery('#domainSuggestions'),
        btnDomainContinue = jQuery('#btnDomainContinue'),
        domainoption = jQuery(".panel-domain-option input:checked").val(),
        sldInput = jQuery("#" + domainoption + "sld"),
        messageInput = jQuery('[data-ai-advanced-search]'),
        message = messageInput.length ? messageInput.val() : '',
        sld = sldInput.val(),
        tld = '',
        pid = jQuery('#frmProductDomainPid').val(),
        tldInput = '',
        idnLanguage = jQuery('#idnLanguageSelector');

    if (!message || !message.trim()) {
        if (sld && (sld.includes(" ") || sld.includes("https://") || sld.includes("http://") || sld.includes("/"))){
            sld = sld.replace(/ /g, '');
            sld = sld.replace('https://', '');
            sld = sld.replace('http://', '');
            sld = sld.replace(/\//g, '');
            sldInput.val(sld);
        }
    }

    var suggestionsLoader = $('.suggested-domains').find('.world-loader');

    var presetPeriod = false;
    if ($('#frmProductDomain')[0].hasAttribute("data-show-tld-cycle-switcher") && $('#frmProductDomain')[0].hasAttribute("data-period")){
        presetPeriod = $('#frmProductDomain').data('period');
    }
    var freeProductDomainArray = false;
    if ($('#frmProductDomain')[0].hasAttribute("data-product-domain-free-price")){
        freeProductDomainArray = $('#frmProductDomain').data('product-domain-free-price');
        var freePriceFormat = $('#frmProductDomain').data('whmcs-free-format');
    }

    jQuery('.field-error-msg').hide();
    if (!idnLanguage.hasClass('hidden')) {
        idnLanguage.addClass('hidden');
        idnLanguage.find('select').val('');
    }
    if (domainoption == 'incart') {
        sldInput = jQuery("#" + domainoption + "sld option:selected");
        sld = sldInput.text();
    // } else if (domainoption == 'subdomain') {
    //     tldInput = jQuery("#" + domainoption + "tld option:selected");
    //     tld = tldInput.text();
    } else {
        tldInput = jQuery("#" + domainoption + "tld");
        tld = tldInput.val();
        if (!message || !message.trim()) {
            if (sld && !tld) {
                tldInput.tooltip('show');
                tldInput.focus();
                return false;
            }
            if (tld && tld.substr(0, 1) != '.') {
                tld = '.' + tld;
            }
        }
    }
    if (!sld || !sld.trim()) {
        if (!message || !message.trim()) {
            var input = (messageInput.length > 0) ? messageInput : sldInput;
            input.tooltip('show').focus();
            return false;
        }
    }
    messageInput.tooltip('hide');
    sldInput.tooltip('hide');
    if (tldInput.length) {
        tldInput.tooltip('hide');
    }


    

    jQuery('input[name="domainoption"]').iCheck('disable');
    domainLookupCallCount = 0;
    btnSearchObj.attr('disabled', 'disabled').addClass('disabled');
    btnSearchObj.find('span').addClass('invisible');
    //jQuery('.domain-lookup-loader').removeClass('hidden');
    
    //jQuery('#DomainSearchResults').addClass('hidden');
    jQuery('.spotlight-loader').removeClass('hidden');    
    jQuery('#spotlightTlds .spotlight-col').show();

    if (domainoption == 'register') {
        var inputDomainLastCheck = sldInput.length ? sldInput.attr('data-last-check') : undefined,
            inputTldLastCheck = tldInput.length ? tldInput.attr('data-last-check') : undefined;
        var currentSld = sldInput.length ? sldInput.val() : '',
            currentTld = tldInput.length ? tldInput.val() : '';
        if (!message || !message.trim()) {
            if (inputDomainLastCheck != null && inputTldLastCheck != null && inputDomainLastCheck == currentSld && inputTldLastCheck == currentTld) {
                setTimeout(function(){
                    jQuery('input[name="domainoption"]').iCheck('enable');
                    btnSearchObj.removeAttr('disabled').removeClass('disabled');
                    btnSearchObj.find('span').removeClass('invisible');
                }, 500);
                return;
            }
        }
    }
    else{
        $('#registersld').removeAttr('data-last-check');
        $('#registertld').removeAttr('data-last-check');
    }

    var spotlightsContainer = jQuery('#spotlightTlds').find('.spotlights');
    var spotlightsLoader = jQuery('#spotlightTlds').find('.world-loader');
    spotlightsContainer.addClass('invisible');
    spotlightsLoader.removeClass('hidden');

    suggestionsLoader.removeClass('hidden');
    suggestions.find('li').addClass('hidden').end()
        .find('.clone').remove().end();
    jQuery('.more-suggestions').addClass('hidden')
        .find('a').removeClass('hidden').end()
        .find('span.no-more').addClass('hidden');
    jQuery('.btn-add-to-cart').removeAttr('disabled')
        .find('span').hide().end()
        .find('span.to-add').show();
    jQuery('.domain-lookup-message').hide();
    btnDomainContinue.addClass('hidden').attr('disabled', 'disabled');
    if (domainoption != 'register') {
        jQuery('#primaryLookupResult > div').filter(function() {
            return $(this).closest('#idnLanguageSelector').length === 0;
        }).hide();
        spotlightTlds.hide();
        jQuery('.suggested-domains').hide();
    }
    // if (!domainSearchResults.is(":visible")) {
    //     domainSearchResults.removeClass('hidden');
    // }
    if (domainoption == 'register') {
        // jQuery('#DomainSearchResults').addClass('hidden');
        jQuery('#resultDomainOption').val(domainoption);
        var queryParams;
        if (message) {
            queryParams = {
                message: message,
                tlds: jQuery('#frmProductDomain select[name="tlds[]"]').val(),
                maxLength: jQuery('#frmProductDomain select[name="maxLength"]').val(),
                filter: jQuery('#frmProductDomain input[name="filter"]').prop('checked'),
                token: csrfToken,
                source: 'cartAddDomain'
            };
        } else {
            queryParams = {
                domain: sld + tld,
                sld: sld,
                tld: tld,
                token: csrfToken,
                source: 'cartAddDomain'
            };
        }

        var lookupDisplay = function (data) {
            if (data.result && data.result.error && jQuery('.domain-checker-advanced:visible').length) {
                jQuery('.domain-checker-result-headline').fadeOut('fast', function() { jQuery(this).hide(); });
                return;
            }
            jQuery.each(data.result || [], function (index, domain) {
                var pricing = null,
                    result = jQuery('#primaryLookupResult'),
                    available = result.find('.domain-available'),
                    availablePrice = result.find('.domain-price'),
                    unavailable = result.find('.domain-unavailable'),
                    unavailableTld = result.find('.domain-tld-unavailable'),
                    invalid = result.find('.domain-invalid'),
                    contactSupport = result.find('.domain-contact-support'),
                    resultDomain = jQuery('#resultDomain'),
                    resultDomainPricing = jQuery('#resultDomainPricingTerm');
                    transferEligible = result.find('.transfer-eligible');
                    transferNotEligible = result.find('.transfer-not-eligible');
                    error = result.find('.domain-error');
                result.removeClass('hidden').show();      
                
                var spotlightCurrentSearch = jQuery('#spotlight'+domain.tldNoDots);
                if (spotlightCurrentSearch.length){
                    spotlightCurrentSearch.parent().hide();
                }
                var tldCycleSwitcher = result.find('[data-tld-cycle-switcher]');
                var tldCycleSwitcherPrice = result.find('[data-tld-cycle-switcher-button]');

                if (typeof domain !== 'string' && !domain.error && domain.isValidDomain) {
                    unavailable.hide();
                    contactSupport.hide();
                    invalid.hide();
                    transferEligible.hide();
                    transferNotEligible.hide();
                    error.hide();
                    pricing = domain.pricing;
                    if (domain.isAvailable && typeof pricing !== 'string') {
                        if (domain.domainName !== domain.idnDomainName && idnLanguage.hasClass('hidden')) {
                            idnLanguage.removeClass('hidden');
                        }
                        if (domain.preferredTLDNotAvailable) {
                            unavailableTld.show().find('strong').html(domain.originalUnavailableTld);
                        }
                        available.show().find('strong').html(domain.domainName);
                        var currentPrice = pricing[Object.keys(pricing)[0]].register;
                        if (freeProductDomainArray && freeProductDomainArray.includes('.'+domain.tld)){                                                     
                            currentPrice = '<span>'+freePriceFormat + '<span class="line-through text-lighter m-l-1x">'+currentPrice+'</span></span>';
                        }
                       
                        availablePrice.show().find('.price').html(currentPrice).end();
                        available.find('button').attr('data-domain', domain.domainName);
                        
                        var isAutomaticAddToCart = $('#primaryLookupResult').attr('data-add-to-cart-on-search');

                        var isBundle = $('#primaryLookupResult').attr('data-product-bundle');
                        if ((typeof isBundle !== 'undefined' && isBundle !== false) || (typeof isAutomaticAddToCart !== 'undefined' && isAutomaticAddToCart !== false)) {
                            resultDomain.val(domain.domainName);
                            resultDomainPricing.val(Object.keys(pricing)[0]).attr('name', 'domainsregperiod[' + domain.domainName + ']');
                            var counterDomain =  parseInt(jQuery('#cartItemCount').text()),
                            domainNumber = counterDomain + 1;
                            $('.bottom-action-sticky').removeClass('hidden').addClass('is-fixed');
                            jQuery('#cartItemCount').html(domainNumber).addClass('badge-primary');
                        }

                        if (tldCycleSwitcher.length){
                            let langYear = tldCycleSwitcher.attr('data-lang-year'),
                                langYears = tldCycleSwitcher.attr('data-lang-years'),
                                registerPeriod = "";
                            tldCycleSwitcher.empty();    
                            tldCycleSwitcherPrice.removeClass('btn-readonly');
                           
                            Object.entries(pricing).forEach(entry => {
                                const [key, value] = entry;
                                if (key > 1){
                                    registerPeriod = '/' + key + langYears;
                                }
                                else{
                                    registerPeriod = '/' + key + langYear;
                                }
                                let option = `<li><a href="#" data-tld-cycle-switcher-option data-html="${value['register']}<small>${registerPeriod}</small>" data-value="${key}">${value['register']}${registerPeriod}</a></li>`;
                                tldCycleSwitcher.append(option);
                            });
                            let text = tldCycleSwitcherPrice.find('.btn-text');
                            if (presetPeriod && (!freeProductDomainArray || (freeProductDomainArray && !freeProductDomainArray.includes('.'+domain.tld)))){
                                if (presetPeriod > 1){
                                    registerPeriod = '<small>/' + presetPeriod + langYears + '</small>';
                                }
                                else{
                                    registerPeriod = '<small>/' + presetPeriod + langYear + '</small>';
                                }

                                var periodExists = tldCycleSwitcher.find('[data-value='+presetPeriod+']');
                                if (periodExists.length){
                                    tldCycleSwitcher.attr('data-value', presetPeriod);
                                    text.html(pricing[Object.keys(pricing)[presetPeriod - 1]].register + registerPeriod)
                                }
                                else{
                                    let lastElement;
                                    for (lastElement in Object.keys(pricing));
                                    lastElement;

                                    tldCycleSwitcher.attr('data-value', Object.keys(pricing)[lastElement]);
                                    if (Object.keys(pricing)[lastElement] > 1){
                                        registerPeriod = '<small>/' + Object.keys(pricing)[lastElement] + langYears + '</small>';
                                    }
                                    else{
                                        registerPeriod = '<small>/' + 1 + langYear + '</small>';
                                    }
                                    
                                    text.html(pricing[Object.keys(pricing)[lastElement]].register + registerPeriod)
                                }
                            }
                            else{
                                var firstAvaliablePeriod = Object.keys(pricing)[0];
                                if (firstAvaliablePeriod > 1){
                                    registerPeriod = '<small>/' + firstAvaliablePeriod + langYears + '</small>';
                                }
                                else{
                                    registerPeriod = '<small>/' + 1 + langYear + '</small>';
                                }
                                tldCycleSwitcher.attr('data-value', firstAvaliablePeriod);
                                
                                if (freeProductDomainArray && freeProductDomainArray.includes('.'+domain.tld)){
                                    tldCycleSwitcherPrice.addClass('btn-readonly');
                                    text.html(currentPrice);
                                }
                                else {
                                    text.html(currentPrice + registerPeriod);
                                }
                            }
                            $('[data-tld-cycle-switcher-option]').each(function(){
                                if($(this).attr('data-value') === $('[data-tld-cycle-switcher]').attr('data-value')){
                                    $(this).parent().addClass('active');
                                }
                            });
                        }
                        
                        if (typeof isAutomaticAddToCart !== 'undefined' && isAutomaticAddToCart !== false){

                            var addButton = jQuery('button[data-domain="' + domain.domainName + '"]').not('.btn-remove-domain'),
                                removeButton = jQuery('.btn-remove-domain[data-domain="' + domain.domainName + '"]');
                                addButton.find('span.to-add').hide();
                                addButton.find('span.added').show().parent().removeClass('btn-primary-faded').addClass('btn-primary').addClass('checkout').end();
                                addButton.each(function(){
                                    if ($(this).data("system-style") && $(this).data("system-style") == "futuristic"){
                                        $(this).removeClass('btn-outline');
                                    }
                                });
                                removeButton.removeClass('hidden');
                        }
                        btnDomainContinue.removeAttr('disabled');
                        

                    } else {
                        available.hide();
                        availablePrice.hide();
                        contactSupport.hide();
                        invalid.hide();
                        transferEligible.hide();
                        transferNotEligible.hide();
                        error.hide();
                        var displayDomain = domain.originalUnavailableDomain
                            ? domain.originalUnavailableDomain
                            : domain.domainName;
                        unavailable.show().find('strong').html(displayDomain);
                        if (typeof pricing === 'string' && pricing == 'ContactUs') {
                            contactSupport.show();
                        }
                    }
                } else {
                    var invalidLength = invalid.find('span.domain-length-restrictions'),
                        done = false,
                        reg = /<br\s*\/>/,
                        errors = [];
                    invalidLength.hide();
                    error.hide();
                    available.hide();
                    availablePrice.hide();
                    contactSupport.hide();
                    invalid.hide();
                    transferEligible.hide();
                    transferNotEligible.hide();
                    error.hide();
                    unavailable.hide();
                    var errorText = error.find('.message-title');
                    if (domain.minLength > 0 && domain.maxLength > 0) {
                        invalidLength.find('.min-length').html(domain.minLength).end()
                            .find('.max-length').html(domain.maxLength).end();
                        invalidLength.show();
                    } else if (data.result.error) {
                        if (!data.result.error.match(reg)) {
                            errorText.text(data.result.error);
                        } else {
                            errorText.text('');
                            errors = data.result.error.split(reg);
                            for(var i=0; i < errors.length; i++) {
                                var errorMsg = errors[i];
                                if (errorMsg.length) {
                                    if (errorText.text()) {
                                        // only add line break if there is
                                        // multiple lines of text
                                        errorText.append('<br />');
                                    }
                                    errorText.append(jQuery('<span></span>').text(errorMsg));
                                }
                            }
                        }
                        error.show();
                        done = true;
                    }
                    if (!done) {
                        invalid.show();
                    }
                }
            });
            if (sldInput.length) sldInput.attr('data-last-check', sldInput.val());
            if (tldInput.length) tldInput.attr('data-last-check', tldInput.val());
        };

        var spotlightDisplay = function (data) {
            if (data.result && data.result.error && jQuery('.domain-checker-advanced:visible').length) {
                jQuery('#spotlightTlds').fadeOut('fast', function() { jQuery(this).hide(); });
                return;
            }
            if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
                jQuery('.domain-lookup-spotlight-loader').hide();
                return;
            }
            spotlightTlds.show();

            jQuery.each(data.result, function (index, domain) {
                var tld = domain.tldNoDots,
                    pricing = domain.pricing,
                    result = jQuery('#spotlight' + tld + ' .domain-lookup-result');
                jQuery('.domain-lookup-spotlight-loader').hide();
                result.find('button').not('.btn-loading').addClass('hidden').removeClass('checkout').end();
                result.find('.btn-loading').removeClass('hidden')

                var tldCycleSwitcher = result.closest('.spotlight').find('[data-tld-cycle-switcher]');

                if (domain.isValidDomain) {
                    if (domain.isAvailable && typeof pricing !== 'string') {
                        if (domain.domainName !== domain.idnDomainName && idnLanguage.hasClass('hidden')) {
                            idnLanguage.removeClass('hidden');
                        }
                        var currentPrice = pricing[Object.keys(pricing)[0]].register;
                        if (freeProductDomainArray && freeProductDomainArray.includes('.'+domain.tld)){
                            currentPrice = '<span>' + freePriceFormat + '<span class="line-through text-lighter m-l-1x">'+currentPrice+'</span></span>';
                        }
                        result
                            .find('.spotlight-footer_price').html(currentPrice).removeClass('hidden').end()
                            .find('button.btn-add-to-cart')
                            .attr('data-domain', domain.domainName)
                            .removeClass('hidden');
                        result.find('.btn-loading').addClass('hidden');
                        result.find('button.btn-remove-domain').attr('data-domain', domain.domainName);
                        if (tldCycleSwitcher.length && (!freeProductDomainArray || (freeProductDomainArray && !freeProductDomainArray.includes('.'+domain.tld)))){
                            let langYear = tldCycleSwitcher.attr('data-lang-year'),
                                langYears = tldCycleSwitcher.attr('data-lang-years'),
                                registerPeriod = "";
                            tldCycleSwitcher.prop('disabled', false);
                            tldCycleSwitcher.parent().removeClass('hidden');
                            tldCycleSwitcher.parent().parent().find('.spotlight-footer_price').remove();
                            tldCycleSwitcher.empty();
                            Object.entries(pricing).forEach(entry => {
                                const [key, value] = entry;
                                if (key > 1){
                                    registerPeriod = '/' + key + langYears;
                                }
                                else{
                                    registerPeriod = '/' + key + langYear;
                                }
                                let option = `<option value="${key}">${value['register']}${registerPeriod}</option>`;
                                tldCycleSwitcher.append(option);
                            });
                            if (presetPeriod && (!freeProductDomainArray || (freeProductDomainArray && !freeProductDomainArray.includes('.'+domain.tld)))){
                                var periodExists = tldCycleSwitcher.find('option[value='+presetPeriod+']');
                                if (periodExists.length){
                                    tldCycleSwitcher.val(presetPeriod);
                                }
                                else{
                                    let lastElement;
                                    for (lastElement in Object.keys(pricing));
                                    lastElement;
                                    var periodExists = tldCycleSwitcher.find('option[value='+Object.keys(pricing)[lastElement]+']');
                                    if (periodExists.length){
                                        tldCycleSwitcher.val(Object.keys(pricing)[lastElement]);
                                    }
                                }
                            }
                        } else if (tldCycleSwitcher.length && freeProductDomainArray && freeProductDomainArray.includes('.'+domain.tld)) {
                            tldCycleSwitcher.parent().addClass('hidden');
                            tldCycleSwitcher.parent().parent().find('.spotlight-footer_price').remove();
                            let container = `<span class="spotlight-footer_price spotlight-footer_price-bordered">${currentPrice}</span>`;
                            tldCycleSwitcher.parent().parent().prepend(container);
                        }

                    } else {
                        if (typeof pricing === 'string') {
                            if (pricing == '') {
                                result.find('button.unavailable').removeClass('hidden').end();
                            } else {
                                result.find('button.domain-contact-support').removeClass('hidden').end();
                            }
                            result.find('span.available').addClass('hidden').end();
                            result.find('.btn-loading').addClass('hidden');
                        } else {
                            result.find('button.unavailable').removeClass('hidden').end();
                            result.find('span.available').addClass('hidden').end();
                            result.closest('.spotlight').addClass("spotlight-disabled");
                            result.find('.btn-loading').addClass('hidden');
                        }
                        if (tldCycleSwitcher.length){
                            tldCycleSwitcher.empty();
                            let option = `<option value="-">-</option>`;
                            tldCycleSwitcher.append(option);
                            tldCycleSwitcher.prop('disabled', true);
                        }
                    }
                } else {
                    result.find('button.invalid.hidden').removeClass('hidden').end()
                        .find('span.available').addClass('hidden').end()
                        .find('button').not('button.invalid').addClass('hidden');
                    result.find('.btn-loading').addClass('hidden');
                    if (tldCycleSwitcher.length){
                        tldCycleSwitcher.empty();
                        let option = `<option value="-">-</option>`;
                        tldCycleSwitcher.append(option);
                        tldCycleSwitcher.prop('disabled', true);
                    }
                }


            });
        };

        var suggestionDisplay = function (data) {
            if (typeof data != 'object' || !data.result || data.result.length == 0 || data.result.error) {
                jQuery('.domain-lookup-message').show();
                jQuery('.suggested-domains').fadeOut('fast', function () {
                    jQuery(this).addClass('hidden');
                });
                suggestionsLoader.addClass('hidden');
                return;
            }
            jQuery('.domain-lookup-message').hide();
            jQuery('.suggested-domains').removeClass('hidden').show();
            var suggestionCount = 1;
            jQuery.each(data.result || [], function (index, domain) {
                var tld = domain.tld,
                    pricing = domain.pricing;
                suggestions.find('li:first').clone(true, true).appendTo(suggestions);
                var newSuggestion = suggestions.find('li.domain-suggestion').last();
                newSuggestion.addClass('clone')
                    .find('span.domain').html(domain.sld).end()
                    .find('span.extension').html('.' + tld).end();
                    if (domain.domainName !== domain.idnDomainName && idnLanguage.hasClass('hidden')) {
                        idnLanguage.removeClass('hidden');
                    }
                var tldCycleSwitcher = newSuggestion.find('[data-tld-cycle-switcher]');
                if (typeof pricing === 'string') {
                    newSuggestion.find('button.btn-add-to-cart').remove();
                    if (pricing != '') {
                        newSuggestion.find('button.domain-contact-support').removeClass('hidden').end()
                            .find('span.price').hide();
                    } else {
                        newSuggestion.remove();
                    }
                } else {
                    var currentPrice = pricing[Object.keys(pricing)[0]].register;
                    if (freeProductDomainArray && freeProductDomainArray.includes('.'+domain.tld)){
                        currentPrice = '<span>' + freePriceFormat + '<span class="line-through text-lighter m-l-1x">'+currentPrice+'</span></span>';
                    }
                    newSuggestion.find('button.btn-add-to-cart').attr('data-domain', domain.domainName).end()
                        .find('span.price').html(currentPrice).end();
                    newSuggestion.find('button.btn-remove-domain').attr('data-domain', domain.domainName);
                    newSuggestion.find('button.btn-remove-domain').tooltip('enable');
                    if (tldCycleSwitcher.length && (!freeProductDomainArray || (freeProductDomainArray && !freeProductDomainArray.includes('.'+domain.tld)))){
                        let langYear = tldCycleSwitcher.attr('data-lang-year'),
                            langYears = tldCycleSwitcher.attr('data-lang-years'),
                            registerPeriod = "";
                        tldCycleSwitcher.removeClass('hidden');
                        tldCycleSwitcher.parent().find('actions-control').remove();
                        Object.entries(pricing).forEach(entry => {
                            const [key, value] = entry;
                            if (key > 1){
                                registerPeriod = '/' + key + langYears;
                            }
                            else{
                                registerPeriod = '/' + key + langYear;
                            }
                            let option = `<option value="${key}">${value['register']}${registerPeriod}</option>`;
                            tldCycleSwitcher.append(option);
                        });
                        if (presetPeriod){
                            var periodExists = tldCycleSwitcher.find('option[value='+presetPeriod+']');
                            if (periodExists.length){
                                tldCycleSwitcher.val(presetPeriod);
                            }
                            else{
                                let lastElement;
                                for (lastElement in Object.keys(pricing));
                                lastElement;
                                var periodExists = tldCycleSwitcher.find('option[value='+Object.keys(pricing)[lastElement]+']');
                                if (periodExists.length){
                                    tldCycleSwitcher.val(Object.keys(pricing)[lastElement]);
                                }
                            }
                        }
                    } else if (tldCycleSwitcher.length && freeProductDomainArray && freeProductDomainArray.includes('.'+domain.tld)) {
                        tldCycleSwitcher.addClass('hidden');
                        tldCycleSwitcher.parent().find('actions-control').remove();
                        let container = `<span class="actions-control form-control input-sm">${currentPrice}</span>`;
                        tldCycleSwitcher.parent().prepend(container);
                    }
                }
                if (suggestionCount <= 10) {
                    newSuggestion.removeClass('hidden');
                }
                suggestionCount++;
                if (domain.group) {
                    newSuggestion.find('span.promo')
                        .addClass(domain.group)
                        .removeClass('hidden')
                        .end();
                    newSuggestion.find('span.sales-group-' + domain.group)
                        .removeClass('hidden')
                        .end();
                }
                furtherSuggestions = suggestions.find('li.domain-suggestion.clone.hidden').length;
                if (furtherSuggestions > 0) {
                    jQuery('div.more-suggestions').removeClass('hidden');
                }
            });
            jQuery('.domain-lookup-suggestions-loader').hide();
            jQuery('#domainSuggestions').removeClass('hidden');
        };

        if (message && message.trim().search(/\s/) !== -1) {
            var suggestionReq = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                jQuery.extend({}, queryParams, { type: 'suggestions' }),
                'json'
            );
            suggestionReq.done(function (data) {
                jQuery('#DomainSearchResults').removeClass('hidden');
                if (jQuery('#DomainSearchResults').data('scroll-to-results') == true) {
                    jQuery("html, body").animate({ scrollTop: jQuery('#DomainSearchResults').offset().top - 150 }, 500);
                }
                var rawResult = data && data.result;
                var suggestionsResult;
                if (Array.isArray(rawResult)) {
                    suggestionsResult = rawResult.slice();
                } else if (rawResult && typeof rawResult === 'object' && !rawResult.error) {
                    suggestionsResult = Object.values(rawResult);
                } else {
                    suggestionsResult = [];
                }
                var topResult = suggestionsResult.length ? suggestionsResult.shift() : null;
                if (!topResult) {
                    suggestionDisplay({ result: [] });
                    spotlightsLoader.addClass('hidden');
                    spotlightsContainer.removeClass('invisible');
                    jQuery('.spotlight-tlds, .domain-lookup-primary-loader').fadeOut('fast', function() { jQuery(this).hide(); });
                    hasProductDomainLookupEnded(1, btnSearchObj);
                    return;
                }
                if (suggestionsResult.length) {
                    suggestionDisplay({ result: suggestionsResult });
                } else {
                    jQuery('.domain-lookup-message').hide();
                    jQuery('#domainSuggestions').addClass('hidden').hide();
                    jQuery('.suggested-domains').addClass('hidden').hide();
                    suggestionsLoader.addClass('hidden');
                }
                jQuery('#searchDomainInfo').removeClass('hidden').show();
                if (jQuery('#primarySuggestionHeading').length) jQuery('#primarySuggestionHeading').show();
                lookupDisplay({ result: [topResult] });
                var spotParams = jQuery.extend({}, queryParams, { message: topResult.domainName, type: 'spotlight' });
                var spotlightReq = jQuery.post(WHMCS.utils.getRouteUrl('/domain/check'), spotParams, 'json');
                spotlightReq.done(spotlightDisplay).always(function () {
                    spotlightsLoader.addClass('hidden');
                    spotlightsContainer.removeClass('invisible');
                    hasProductDomainLookupEnded(2, btnSearchObj);
                });
            }).always(function () {
                suggestionsLoader.addClass('hidden');
                hasProductDomainLookupEnded(1, btnSearchObj);
            });
        } else {
        var lookup = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                jQuery.extend({}, queryParams, { type: 'domain' }),
                'json'
            ),
            spotlight = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                jQuery.extend({}, queryParams, { type: 'spotlight' }),
                'json'
            ),
            suggestion = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                jQuery.extend({}, queryParams, { type: 'suggestions' }),
                'json'
            );
        lookup.done(lookupDisplay).always(function () {
            //jQuery('.domain-lookup-loader').addClass('hidden');
            jQuery('#DomainSearchResults').removeClass('hidden');
            if(jQuery('#DomainSearchResults').data('scroll-to-results') == true){
                jQuery("html, body").animate({ scrollTop: $('#DomainSearchResults').offset().top - 150 }, 500);
            }
            btnSearchObj.removeAttr('disabled').removeClass('disabled');
            btnSearchObj.find('span').removeClass('invisible');
            hasProductDomainLookupEnded(3, btnSearchObj);
        });
        spotlight.done(spotlightDisplay).always(function () {
            hasProductDomainLookupEnded(3, btnSearchObj);
            spotlightsLoader.addClass('hidden');
            spotlightsContainer.removeClass('invisible');
            var isAutomaticAddToCart = $('#primaryLookupResult').attr('data-add-to-cart-on-search');
            if (typeof isAutomaticAddToCart !== 'undefined' && isAutomaticAddToCart !== false){

                var domainName = jQuery('#primaryLookupResult .domain-available .btn-add-to-cart').data('domain');
                    addButton = jQuery('#spotlightTlds button[data-domain="' + domainName + '"]').not('.btn-remove-domain'),
                    removeButton = jQuery('#spotlightTlds .btn-remove-domain[data-domain="' + domainName + '"]');
                    addButton.find('span.to-add').hide();
                    addButton.find('span.added').show().parent().removeClass('btn-primary-faded').addClass('btn-primary').addClass('checkout').end();
                    addButton.each(function(){
                        if ($(this).data("system-style") && $(this).data("system-style") == "futuristic"){
                            $(this).removeClass('btn-outline');
                        }
                    });
                    removeButton.removeClass('hidden');
            }
        });
        suggestion.done(suggestionDisplay).always(function () {
            hasProductDomainLookupEnded(3, btnSearchObj);
            suggestionsLoader.addClass('hidden');
        });
        }
    } else if (domainoption == 'transfer') {
        jQuery('#resultDomainOption').val(domainoption);
        var transfer = jQuery.post(
            WHMCS.utils.getRouteUrl('/domain/check'),
            {
                token: csrfToken,
                type: 'transfer',
                domain: sld + tld,
                sld: sld,
                tld: tld,
                source: 'cartAddDomain'
            },
            'json'
        );
        transfer.done(function (data) {
            if (typeof data != 'object' || data.result.length == 0) {
                jQuery('.domain-lookup-loader').addClass('hidden');
                return;
            }
            var result = jQuery('#primaryLookupResult'),
                transfereligible = result.find('.transfer-eligible'),
                transferPrice = result.find('.domain-price'),
                transfernoteligible = result.find('.transfer-not-eligible'),
                resultDomain = jQuery('#resultDomain'),
                resultDomainPricing = jQuery('#resultDomainPricingTerm'),
                transferEligibleDesc = transfereligible.find('.transfer-eligible-desc'),
                transferEligibleDescUk = transfereligible.find('.transfer-eligible-desc-uk'),
                domainPriceText = transfereligible.find('.domain-price-text');
            if (Object.keys(data.result).length === 0) {
                jQuery('.domain-lookup-loader').addClass('hidden');
                result.removeClass('hidden').show();
                transfernoteligible.show();
            }
            jQuery.each(data.result, function (index, domain) {
                var pricing = domain.pricing;
                jQuery('.domain-lookup-loader').addClass('hidden');
                result.removeClass('hidden').show();
                if (domain.isRegistered) {
                    transfereligible.show();
                    transferPrice.show().find('.register-price-label').hide().end()
                        .find('.transfer-price-label').removeClass('hidden').show().end()
                        .find('.price').html(pricing[Object.keys(pricing)[0]].transfer).end()
                        .find('button').attr('data-domain', domain.domainName);
                    if (domain.tld.includes('uk')){
                        transferEligibleDesc.addClass('hidden');
                        transferEligibleDescUk.removeClass('hidden');
                        domainPriceText.addClass('hidden');
                    }    
                    else{
                        transferEligibleDesc.removeClass('hidden');
                        transferEligibleDescUk.addClass('hidden');
                        domainPriceText.removeClass('hidden');
                    }
                    resultDomain.val(domain.domainName);
                    resultDomainPricing.val(Object.keys(pricing)[0]).attr('name', 'domainsregperiod[' + domain.domainName + ']');
                    btnDomainContinue.removeAttr('disabled');
                } else {
                    transfernoteligible.show();
                }
            });
        }).always(function () {
            hasProductDomainLookupEnded(1, btnSearchObj);
            jQuery('.domain-lookup-loader').addClass('hidden');
            jQuery('#DomainSearchResults').removeClass('hidden');
            if(jQuery('#DomainSearchResults').data('scroll-to-results') == true){
                jQuery("html, body").animate({ scrollTop: $('#DomainSearchResults').offset().top - 150 }, 500);
            }
        });
    } else if (domainoption == 'owndomain' || domainoption == 'subdomain' || domainoption == 'incart') {
        var otherDomain = WHMCS.http.jqClient.post(
            WHMCS.utils.getRouteUrl('/domain/check'),
            {
                token: csrfToken,
                type: domainoption,
                pid: pid,
                domain: sld + tld,
                sld: sld,
                tld: tld,
                source: 'cartAddDomain'
            },
            'json'
        );
        otherDomain.done(function (data) {
            if (typeof data != 'object' || data.result.length == 0) {
                jQuery('.domain-lookup-subdomain-loader').hide();
                return;
            }
            jQuery.each(data.result, function (index, result) {
                if (result.status === true) {
                    displayRecommendations(
                        whmcsBaseUrl + '/cart.php',
                        'addproductajax=1&a=confproduct&i=' + result.num,
                        false
                    ).done(function() {
                        window.location = whmcsBaseUrl + '/cart.php?a=confproduct&i=' + result.num;
                    });
                } else {
                    jQuery('.domain-lookup-loader').addClass('hidden');
                    if (typeof result === 'string') {
                        jQuery('#primaryLookupResult').removeClass('hidden').show().find('.domain-error .message-title').html(result).closest('.domain-error').show(); 
                    } else {
                        jQuery('#primaryLookupResult').removeClass('hidden').show().find('.domain-invalid').show();
                    }
                }
            });
        }).always(function () {
            hasProductDomainLookupEnded(1, btnSearchObj);
            jQuery('.domain-lookup-loader').addClass('hidden');
            jQuery('#DomainSearchResults').removeClass('hidden');
        });
    }
    btnDomainContinue.removeClass('hidden');
});
    /*
    *******************************************
    3. Add Domain To Cart
    *******************************************
    */
    jQuery('.btn-add-to-cart').on('click', function (e) {
        if (jQuery(this).hasClass('checkout')) {
            if (jQuery(this).data('product-domain')){
                $('#frmProductDomainSelections').submit();
                return;
            } 
            else{
                window.location = 'cart.php?a=confdomains';
                return;
            }
        }
        else{
            e.preventDefault();
        }
        var domain = jQuery(this).attr('data-domain'),
            buttons = jQuery('button[data-domain="' + domain + '"]').not('.btn-remove-domain'),
            buttonsRemove = jQuery('.btn-remove-domain[data-domain="' + domain + '"]'),
            whois = jQuery(this).attr('data-whois'),
            isProductDomain = jQuery(this).hasClass('product-domain'),
            btnDomainContinue = jQuery('#btnDomainContinue'),
            resultDomain = jQuery('#resultDomain'),
            resultDomainPricing = jQuery('#resultDomainPricingTerm'),
            idnLanguage = jQuery('#idnLanguageSelector'),
            idnLanguageInput = idnLanguage.find('select');

        let tldCycleSwitcher = jQuery(this).closest('.message, .spotlight, .domain-suggestion').find('[data-tld-cycle-switcher]');

        if (!idnLanguage.hasClass('hidden') && !idnLanguageInput.val()) {
            idnLanguageInput.showInputError();
            return;
        }    
        buttons.attr('disabled', 'disabled');
        var sideOrder = ((jQuery(this).parents('.spotlight-tlds').length > 0) || (jQuery(this).parents('.suggested-domains').length > 0)) ? 1 : 0;

        if (window.location.pathname.indexOf("cart.php") < 0 ){
            var ajaxUrl = whmcsBaseUrl+'/cart.php';
        }
        else{
            var ajaxUrl = window.location.pathname;
        }

        var addToCart = jQuery.post(
            ajaxUrl,
            {
                a: 'addToCart',
                domain: domain,
                token: csrfToken,
                whois: whois,
                sideorder: sideOrder,
                idnlanguage: idnLanguageInput.val()
            },
            'json'
        ).done(function (data) {
            buttons.find('span.to-add').hide();
            if (data.result === 'added') {
                buttons.find('span.added').show().parent().removeClass('btn-primary-faded').addClass('btn-primary').end();
                buttons.each(function(){
                    if ($(this).data("system-style") && $(this).data("system-style") == "futuristic"){
                        $(this).removeClass('btn-outline');
                    }
                });
               
                buttonsRemove.removeClass('hidden');
                $('.bottom-action-sticky').removeClass('hidden').addClass('is-fixed');
                if (!isProductDomain) {
                    buttons.removeAttr('disabled').addClass('checkout').closest('.list-group-item').addClass('added');
                }
                if (resultDomain.length && !resultDomain.val()) {
                    resultDomain.val(domain);
                    resultDomainPricing.val(data.period).attr('name', 'domainsregperiod[' + domain + ']');
                    if (btnDomainContinue.length > 0 && btnDomainContinue.is(':disabled')) {
                        btnDomainContinue.removeAttr('disabled');
                    }
                }
                var counterDomain =  parseInt(jQuery('#cartItemCount').text()),
                    domainNumber = counterDomain + 1;

                jQuery('#cartItemCount').html(domainNumber).addClass('badge-primary');
                if (tldCycleSwitcher.length){
                    if (tldCycleSwitcher.is('select')){
                        period = tldCycleSwitcher.val();
                    }
                    else{
                        period = tldCycleSwitcher.data('value');
                    }
                    
                    updateDomainPeriod(domain, period);
                }
                
            } else {
                buttons.find('span.available.price').hide();
                buttons.find('span.unavailable').show();
                buttons.attr('disabled', 'disabled');
            }
        });
    });

    $('#frmProductDomainSelections').on('submit', function(e){
        var idnLanguage = jQuery('#idnLanguageSelector'),
            idnLanguageInput = idnLanguage.find('select'),
            form = jQuery(this);

        if (!idnLanguage.hasClass('hidden') && !idnLanguageInput.val()) {
            e.preventDefault();
            idnLanguageInput.showInputError();
            $('#btnDomainContinue span.invisible').removeClass('invisible');
            return false;
        }
        e.preventDefault();
        displayRecommendations(
            form.attr('action'),
            'addproductajax=1&' + form.serialize(),
            false
        ).done(function() {
            form.unbind().submit();
            form.submit();
        });
    });

    jQuery('#idnLanguageSelector').find('select').on('change', function(){
        var idnLanguage = jQuery('#idnLanguageSelector'),
            idnLanguageInput = idnLanguage.find('select');
           
        if (!idnLanguage.hasClass('hidden') && idnLanguageInput.val()) {
            idnLanguageInput.closest('.form-group').removeClass('has-error').find('.field-error-msg').hide();
        }
    });

    $('.btn-remove-domain').on('click', function (e) {
        let btnRemoveDomain = $(this), 
            template = btnRemoveDomain.data('system-template'),
            btnAddDomain = btnRemoveDomain.siblings('.btn-add-to-cart');
          
        $.ajax({
            type: 'POST',
            data: {
                domainId: ''
                },
            url: whmcsBaseUrl+'/templates/'+template+'/core/api/getcartsession.php',
            success: function (response) {
                response = JSON.parse(response);
                var domainsArr = response.session.domains,
                    domainIndex = false,
                    domain = btnRemoveDomain[0].dataset.domain; 

                btnRemoveDomain.find('i').addClass('invisible');
                btnRemoveDomain.find('.loader').removeClass('hidden');
                btnAddDomain.addClass('disabled');

                domainsArr.map((singleDomain, index) => {
                    
                    if(btnRemoveDomain[0].dataset.domain == singleDomain.domain) {
                        domainIndex = index
                    }
                });
               
                if ((domainIndex || domainIndex === 0) && domain){
                    $.ajax({
                        type: 'POST',
                        url: 'cart.php?a=remove&r=d&i=' + domainIndex,
                        success: function (responseCart) {
                            var buttons = jQuery('button[data-domain="' + domain + '"]').not('.btn-remove-domain'),
                                buttonsRemove = jQuery('.btn-remove-domain[data-domain="' + domain + '"]'),
                                resultDomain = jQuery('#resultDomain'),
                                resultDomainPricing = jQuery('#resultDomainPricingTerm');
                            
                            buttons.removeClass('btn-primary checkout disabled').addClass('btn-primary-faded');
                            buttons.each(function(){
                                if ($(this).data("system-style") && $(this).data("system-style") == "futuristic"){
                                    $(this).removeClass('btn-primary-faded').addClass('btn-outline');
                                }                               
                            });
                            
                            buttons.find('span.to-add').show();
                            buttons.find('span.added').hide()
                            btnRemoveDomain.find('.invisible').removeClass('invisible')
                            btnRemoveDomain.find('.loader').addClass('hidden')
                            buttonsRemove.addClass('hidden');

                            let domainNumber = $('#cartItemCount')
                            let domainsArrLength = [...document.querySelectorAll('#DomainSearchResults .btn-primary.checkout.btn-add-to-cart')].length
                            if(domainsArrLength == 0) {
                                $('.bottom-action-sticky').addClass('hidden');
                            }
                            domainNumber.text(domainsArrLength);

                            if (resultDomain.length && resultDomain.val() == domain) {
                                resultDomain.val('');
                                resultDomainPricing.val('');
                                resultDomainPricing.attr('name', '');
                            }
 
                        },
                        error: function (err) {
                            console.log(err)
                        },
                    });
                }
            },
            error: function (err) {
                console.log(err)
            }
        });
    });

    /*
    *******************************************
    4. Domain Register Search
    *******************************************
    */
    jQuery('#frmDomainChecker').submit(function (e) {
        e.preventDefault();

        if (
            typeof recaptchaValidationComplete !== 'undefined'
            && typeof recaptchaType !== 'undefined'
            && recaptchaType === 'invisible'
            && recaptchaValidationComplete === false
        ) {
            return;
        }

        //jQuery('#DomainSearchResults').addClass('hidden');
  
        var frmDomain = jQuery('#frmDomainChecker'),
            isAdvancedSearch = !!jQuery('[data-ai-advanced-search]').length,
            inputQuery = isAdvancedSearch ? jQuery('[data-ai-advanced-search]') : jQuery('#inputDomain'),
            inputDomain = jQuery('#inputDomain'),
            suggestions = jQuery('#domainSuggestions'),
            reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
            captcha = jQuery('#inputCaptcha'),
            idnLanguage = jQuery('#idnLanguageSelector');
        domainLookupCallCount = 0;

        if (!isAdvancedSearch) {
            var domain = inputDomain.val();
            if (domain && (domain.includes(" ") || domain.includes("https://") || domain.includes("http://") || domain.includes("/"))){
                domain = domain.replace(/ /g, '');
                domain = domain.replace('https://', '');
                domain = domain.replace('http://', '');
                domain = domain.replace(/\//g, '');
                inputDomain.val(domain);
            }
        }
        
        var suggestionsLoader = $('.suggested-domains').find('.world-loader');
        var showDomainSearchResults = function () {
            jQuery('#DomainSearchResults').removeClass('hidden');
            jQuery('.domain-pricing').hide();
            if (jQuery('#DomainSearchResults').data('scroll-to-results')) {
                jQuery("html, body").animate({ scrollTop: jQuery('#DomainSearchResults').offset().top - 150 }, 500);
            }
        };
        var resetAdvancedSearchResults = function () {
            jQuery('.domain-lookup-message').hide();
            jQuery('#searchDomainInfo').show();
            jQuery('#primaryLookupResult').show();
            jQuery('#spotlightTlds').show();
            jQuery('#domainSuggestions').hide();
            jQuery('#primarySuggestionHeading').hide();
            jQuery('.suggested-domains').removeClass('hidden').show();
        };
        
        var presetPeriod = false;
        if (frmDomain[0].hasAttribute("data-show-tld-cycle-switcher") && frmDomain[0].hasAttribute("data-period")){
            presetPeriod = frmDomain.data('period');
        }

        jQuery('.field-error-msg').hide();

        if (!idnLanguage.hasClass('hidden')) {
            idnLanguage.addClass('hidden');
            idnLanguage.find('select').val('');
        }

        // check a domain or message has been entered
        if (!inputQuery.val() || !inputQuery.val().trim()) {
            inputQuery.tooltip('show');
            inputQuery.focus();
            return;
        }
        inputQuery.tooltip('hide');
        if (jQuery('#captchaContainer').length) {
            validate_captcha(frmDomain);
            return;
        }

       

        reCaptchaContainer.tooltip('hide');
        jQuery('.domain-search-captcha').hide();
        captcha.tooltip('hide');
        // disable repeat submit and show loader
        jQuery('#btnCheckAvailability').attr('disabled', 'disabled').addClass('disabled');
        jQuery('#btnCheckAvailability > span').addClass('invisible');


        var inputDomainLastCheck = inputQuery.attr('data-last-check');
        var currentQuery = (inputQuery.val() || '').toString().trim();
        if (!isAdvancedSearch && inputDomainLastCheck != null && inputDomainLastCheck !== '' && String(inputDomainLastCheck) === currentQuery) {
            setTimeout(function(){
                jQuery('#btnCheckAvailability').removeAttr('disabled').removeClass('disabled');
                jQuery('#btnCheckAvailability > span').removeClass('invisible');
            }, 500);
            return;
        }

        //jQuery('.domain-lookup-result').addClass('hidden');
        
        //jQuery('.domain-lookup-loader').removeClass('hidden');       
        jQuery('.spotlight-loader').removeClass('hidden');      
        jQuery('#spotlightTlds .spotlight-col').show();
        var spotlightsContainer = jQuery('#spotlightTlds').find('.spotlights');
        var spotlightsLoader = jQuery('#spotlightTlds').find('.world-loader');
        spotlightsContainer.addClass('invisible');
        spotlightsLoader.removeClass('hidden');
        
        // reset elements
        suggestionsLoader.removeClass('hidden');

        suggestions.find('li').addClass('hidden').end();
        suggestions.find('.clone').remove().end();
        jQuery('.more-suggestions').addClass('hidden')
            .find('a').removeClass('hidden').end()
            .find('span.no-more').addClass('hidden');
        jQuery('.btn-add-to-cart').removeAttr('disabled')
            .find('span').hide().end()
            .find('span.to-add').show();
        jQuery('.suggested-domains').removeClass('hidden');
        if (isAdvancedSearch) {
            resetAdvancedSearchResults();
        }

        var lookupDisplayChecker = function (data) {
            if (data.result && data.result.error && jQuery('.domain-checker-advanced:visible').length) {
                jQuery('.domain-checker-result-headline').fadeOut('fast', function() { jQuery(this).hide(); });
                return;
            }
            if (typeof data != 'object' || data.result.length == 0) {
                jQuery('.domain-lookup-primary-loader').hide();
                return;
            }
            jQuery.each(data.result, function (index, domain) {
                var pricing = null,
                    result = jQuery('#primaryLookupResult'),
                    available = result.find('.domain-available'),
                    availablePrice = result.find('.domain-price'),
                    contactSupport = result.find('.domain-contact-support'),
                    unavailable = result.find('.domain-unavailable'),
                    unavailableTld = result.find('.domain-tld-unavailable'),
                    invalid = result.find('.domain-invalid'),
                    error = result.find('.domain-error');
                //jQuery('.domain-lookup-loader').addClass('hidden');
                result.find('.btn-add-to-cart').removeClass('checkout');
                jQuery('#searchDomainInfo').removeClass('hidden');
                result.removeClass('hidden').show();

                var spotlightCurrentSearch = jQuery('#spotlight'+domain.tldNoDots);
                if (spotlightCurrentSearch.length){
                    spotlightCurrentSearch.parent().hide();
                }

                var tldCycleSwitcher = result.find('[data-tld-cycle-switcher]');
                var tldCycleSwitcherPrice = result.find('[data-tld-cycle-switcher-button]');

                if (!data.result.error && domain.isValidDomain) {
                    pricing = domain.pricing;
                    unavailable.hide();
                    contactSupport.hide();
                    unavailableTld.hide();
                    invalid.hide();
                    error.hide();
                    if (domain.isAvailable && typeof pricing !== 'string') {                        
                        if (domain.domainName !== domain.idnDomainName && idnLanguage.hasClass('hidden')) {
                            idnLanguage.removeClass('hidden');
                        }
                        if (domain.preferredTLDNotAvailable) {
                            unavailableTld.show().find('strong').html(domain.originalUnavailableTld);
                        }
                        
                        available.show().find('strong').html(domain.domainName);
                        availablePrice.show().find('.price').html(pricing[Object.keys(pricing)[0]].register).end()
                        available.find('button').attr('data-domain', domain.domainName);
                        if (tldCycleSwitcher.length){
                            let langYear = tldCycleSwitcher.attr('data-lang-year'),
                                langYears = tldCycleSwitcher.attr('data-lang-years'),
                                registerPeriod = "";
                            tldCycleSwitcher.empty();
                            Object.entries(pricing).forEach(entry => {
                                const [key, value] = entry;
                                if (key > 1){
                                    registerPeriod = '/' + key + langYears;
                                }
                                else{
                                    registerPeriod = '/' + key + langYear;
                                }
                                let option = `<li><a href="#" data-tld-cycle-switcher-option data-html="${value['register']}<small>${registerPeriod}</small>" data-value="${key}">${value['register']}${registerPeriod}</a></li>`;
                                tldCycleSwitcher.append(option);
                                
                            });
                            let text = tldCycleSwitcherPrice.find('.btn-text');
                            if (presetPeriod){
                                if (presetPeriod > 1){
                                    registerPeriod = '<small>/' + presetPeriod + langYears + '</small>';
                                }
                                else{
                                    registerPeriod = '<small>/' + presetPeriod + langYear + '</small>';
                                }
                               
                                var periodExists = tldCycleSwitcher.find('[data-value='+presetPeriod+']');
                                if (periodExists.length){
                                    tldCycleSwitcher.attr('data-value', presetPeriod);
                                    text.html(pricing[Object.keys(pricing)[presetPeriod - 1]].register + registerPeriod)
                                }
                                else{
                                    let lastElement;
                                    for (lastElement in Object.keys(pricing));
                                    lastElement;

                                    tldCycleSwitcher.attr('data-value', Object.keys(pricing)[lastElement]);
                                    if (Object.keys(pricing)[lastElement] > 1){
                                        registerPeriod = '<small>/' + Object.keys(pricing)[lastElement] + langYears + '</small>';
                                    }
                                    else{
                                        registerPeriod = '<small>/' + 1 + langYear + '</small>';
                                    }
                                    
                                    text.html(pricing[Object.keys(pricing)[lastElement]].register + registerPeriod)
                                }
                            }
                            else{
                                var firstAvaliablePeriod = Object.keys(pricing)[0];
                                if (firstAvaliablePeriod > 1){
                                    registerPeriod = '<small>/' + firstAvaliablePeriod + langYears + '</small>';
                                }
                                else{
                                    registerPeriod = '<small>/' + 1 + langYear + '</small>';
                                }
                                tldCycleSwitcher.attr('data-value', firstAvaliablePeriod);
                                text.html(pricing[Object.keys(pricing)[0]].register + registerPeriod);
                            }
                            $('[data-tld-cycle-switcher-option]').each(function(){
                                if($(this).attr('data-value') === $('[data-tld-cycle-switcher]').attr('data-value')){
                                    $(this).parent().addClass('active');
                                }
                            });
                        } 
                    } else {
                        available.hide();
                        availablePrice.hide();
                        contactSupport.hide();
                        if (domain.preferredTLDNotAvailable) {
                            unavailableTld.show().find('strong').html(domain.originalUnavailableTld);
                        } else {
                            unavailable.show().find('strong').html(domain.domainName);
                        }
                        if (typeof pricing === 'string' && pricing == 'ContactUs') {
                            contactSupport.show();
                        }
                    }
                } else {
                    available.hide();
                    availablePrice.hide();
                    unavailable.hide();
                    unavailableTld.hide();
                    contactSupport.hide();
                    invalid.hide();
                    error.hide();
                    var done = false,
                        reg = /<br\s*\/>/,
                        errors = [];
                    if (!domain.isValidDomain && domain.domainErrorMessage) {
                        invalid.find('.message-title').text(domain.domainErrorMessage);
                    } else if (domain.error || index === 'error') {
                        if (typeof domain === 'string') {
                            error.find('.message-title').text(domain);
                        } else if (!domain.error.match(reg)) {
                            error.find('.message-title').text(domain.error);
                        } else {
                            error.find('.message-title').text('');
                            errors = domain.error.split(reg);
                            for(var i=0; i < errors.length; i++) {
                                var errorMsg = errors[i];
                                if (errorMsg.length) {
                                    if (error.find('.message-title').text()) {
                                        // only add line break if there is
                                        // multiple lines of text
                                        error.find('.message-title').append('<br />');
                                    }
                                    error.find('.message-title').append(jQuery('<span></span>').text(errorMsg));
                                }
                            }
                        }                     
                        
                        error.show();
                        done = true;
                    }
                    if (!done) {
                        invalid.show();
                    }
                    
                }
            });
            inputQuery.attr('data-last-check', inputQuery.val());
        };

        var suggestionDisplayChecker = function (data) {
            if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
                jQuery('.domain-lookup-loader').hide();
                jQuery('.domain-lookup-message').show();
                jQuery('.suggested-domains').fadeOut('fast', function () {
                    jQuery(this).addClass('hidden');
                });
                suggestionsLoader.addClass('hidden');
                return;
            }
            jQuery('.domain-lookup-message').hide();
            jQuery('.suggested-domains').removeClass('hidden');
            var suggestionCount = 1;
            jQuery.each(data.result || [], function (index, domain) {
                var tld = domain.tld,
                    pricing = domain.pricing;
                suggestions.find('li:first').clone(true, true).appendTo(suggestions);
                var newSuggestion = suggestions.find('li.domain-suggestion').last();
                newSuggestion.addClass('clone')
                    .find('span.domain').html(domain.sld).end()
                    .find('span.extension').html('.' + tld).end();
                var tldCycleSwitcher = newSuggestion.find('[data-tld-cycle-switcher]');
                if (typeof pricing === 'string') {
                    newSuggestion.find('button.btn-add-to-cart').remove();
                    if (pricing != '') {
                        newSuggestion.find('button.domain-contact-support').removeClass('hidden').end()
                            .find('span.price').hide();
                        if (tldCycleSwitcher.length) tldCycleSwitcher.hide();
                    } else {
                        newSuggestion.remove();
                    }
                } else {
                    if (domain.domainName !== domain.idnDomainName && idnLanguage.hasClass('hidden')) {
                        idnLanguage.removeClass('hidden');
                    }
                    if (pricing[Object.keys(pricing)[0]] != undefined){
                        newSuggestion.find('button.btn-add-to-cart').attr('data-domain', domain.domainName).end()
                            .find('span.price').html(pricing[Object.keys(pricing)[0]].register).end();
                        newSuggestion.find('button.btn-remove-domain').attr('data-domain', domain.domainName);
                        newSuggestion.find('button.btn-remove-domain').tooltip('enable');
                        if (tldCycleSwitcher.length){
                            var langYear = tldCycleSwitcher.attr('data-lang-year'),
                                langYears = tldCycleSwitcher.attr('data-lang-years'),
                                registerPeriod = "";
                            Object.entries(pricing).forEach(entry => {
                                const key = entry[0], value = entry[1];
                                registerPeriod = (key > 1) ? '/' + key + langYears : '/' + key + langYear;
                                tldCycleSwitcher.append(jQuery('<option value="'+key+'">'+value['register']+registerPeriod+'</option>'));
                            });
                            if (presetPeriod){
                                var pe = tldCycleSwitcher.find('option[value='+presetPeriod+']');
                                if (pe.length) tldCycleSwitcher.val(presetPeriod);
                                else tldCycleSwitcher.val(Object.keys(pricing)[Object.keys(pricing).length-1]);
                            }
                        }
                    } else {
                        newSuggestion.find('button.domain-contact-support').removeClass('hidden').end()
                            .find('span.price').hide();
                        if (tldCycleSwitcher.length) tldCycleSwitcher.hide();
                    }
                }
                if (suggestionCount <= 10) newSuggestion.removeClass('hidden');
                suggestionCount++;
                if (domain.group) {
                    newSuggestion.find('span.promo').addClass(domain.group).removeClass('hidden').end();
                    newSuggestion.find('span.sales-group-' + domain.group).removeClass('hidden').end();
                }
                   furtherSuggestions = suggestions.find('li.domain-suggestion.clone.hidden').length;
                if (furtherSuggestions > 0) jQuery('div.more-suggestions').removeClass('hidden');
            });
            jQuery('.domain-lookup-suggestions-loader').hide();
            suggestionsLoader.addClass('hidden');
            jQuery('#domainSuggestions').removeClass('hidden').show();
        };

        var spotlightDisplayChecker = function (data) {
            if (data.result && data.result.error && jQuery('.domain-checker-advanced:visible').length) {
                jQuery('.spotlight-tlds').fadeOut('fast', function() { jQuery(this).hide(); });
                return;
            }
            if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
                jQuery('.spotlight-loader').addClass('hidden');
                return;
            }
            jQuery.each(data.result, function (index, domain) {
                var tld = domain.tldNoDots,
                    pricing = domain.pricing,
                    result = jQuery('#spotlight' + tld + ' .domain-lookup-result');
                jQuery('.spotlight-loader').removeClass('hidden');
                result.find('button').not('.btn-loading').addClass('hidden').end();
                result.find('.btn-loading').removeClass('hidden');
                var tldCycleSwitcher = result.closest('.spotlight').find('[data-tld-cycle-switcher]');
                if (domain.isValidDomain) {
                    if (domain.isAvailable && typeof pricing !== 'string') {
                        if (domain.domainName !== domain.idnDomainName && idnLanguage.hasClass('hidden')) idnLanguage.removeClass('hidden');
                        if (pricing[Object.keys(pricing)[0]] != undefined){
                            result.find('button.unavailable').addClass('hidden').end()
                                .find('button.invalid').addClass('hidden').end()
                                .find('span.available').html(pricing[Object.keys(pricing)[0]].register).removeClass('hidden').end()
                                .find('button').not('button.unavailable').not('button.invalid').not('button.btn-remove-domain')
                                .attr('data-domain', domain.domainName).removeClass('hidden');
                            result.find('.btn-loading').addClass('hidden');
                            result.closest('.spotlight').removeClass('unavailable');
                            result.find('button.btn-remove-domain').attr('data-domain', domain.domainName);
                            if (tldCycleSwitcher.length){
                                var ly = tldCycleSwitcher.attr('data-lang-year'), lys = tldCycleSwitcher.attr('data-lang-years'), rp = "";
                                tldCycleSwitcher.prop('disabled', false).empty();
                                Object.entries(pricing).forEach(entry => {
                                    var k = entry[0], v = entry[1];
                                    rp = (k > 1) ? '/' + k + lys : '/' + k + ly;
                                    tldCycleSwitcher.append(jQuery('<option value="'+k+'">'+v['register']+rp+'</option>'));
                                });
                                if (presetPeriod && tldCycleSwitcher.find('option[value='+presetPeriod+']').length) tldCycleSwitcher.val(presetPeriod);
                            }
                        } else {
                            result.find('button.invalid').addClass('hidden').end()
                                .find('button.unavailable').removeClass('hidden').end()
                                .find('span.available').addClass('hidden').end()
                                .find('span.unavailable').removeClass('hidden').end();
                            result.closest('.spotlight').addClass('unavailable');
                            result.find('.btn-loading').addClass('hidden');
                            if (tldCycleSwitcher.length) tldCycleSwitcher.empty().append(jQuery('<option value="-">-</option>')).prop('disabled', true);
                        }
                    } else {
                        if (typeof pricing === 'string') {
                            if (pricing == '') result.find('button.unavailable').removeClass('hidden').end();
                            else result.find('button.domain-contact-support').removeClass('hidden').end();
                            result.find('button.invalid').addClass('hidden').end().find('span.available').addClass('hidden').end()
                                .find('span.unavailable').removeClass('hidden').end().find('.btn-loading').addClass('hidden');
                        } else {
                            result.find('button.invalid').addClass('hidden').end()
                                .find('button.unavailable').removeClass('hidden').end()
                                .find('span.available').addClass('hidden').end()
                                .find('span.unavailable').removeClass('hidden').end();
                            result.closest('.spotlight').addClass('unavailable');
                            result.find('.btn-loading').addClass('hidden');
                        }
                        if (tldCycleSwitcher.length) tldCycleSwitcher.empty().append(jQuery('<option value="-">-</option>')).prop('disabled', true);
                    }
                } else {
                    result.find('button.invalid.hidden').removeClass('hidden').end()
                        .find('span.available').addClass('hidden').end()
                        .find('span.unavailable').removeClass('hidden').end()
                        .find('button').not('button.invalid').addClass('hidden').end();
                    result.closest('.spotlight').addClass('unavailable');
                    result.find('.btn-loading').addClass('hidden');
                    if (tldCycleSwitcher.length) tldCycleSwitcher.empty().append(jQuery('<option value="-">-</option>')).prop('disabled', true);
                }
                result.removeClass('hidden');
                jQuery('.spotlight-loader').addClass('hidden');
            });
        };

        if (isAdvancedSearch && inputQuery.val().trim().search(/\s/) !== -1) {
            var suggestionReqChecker = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                frmDomain.serialize() + '&type=suggestions',
                'json'
            );
            var aiSpotlightStarted = false;
            suggestionReqChecker.done(function (data) {
            var rawResult = data && data.result;
            var suggestionsResult;
            if (Array.isArray(rawResult)) {
                suggestionsResult = rawResult.slice();
            } else if (rawResult && typeof rawResult === 'object' && !rawResult.error) {
                suggestionsResult = Object.values(rawResult);
            } else {
                suggestionsResult = [];
            }
            var topResult = suggestionsResult.length ? suggestionsResult.shift() : null;
                if (!topResult) {
                    suggestionDisplayChecker({ result: [] });
                    jQuery('#searchDomainInfo, #primarySuggestionHeading, #domainSuggestions').addClass('hidden').hide();
                    jQuery('#primaryLookupResult').addClass('hidden').hide();
                    jQuery('.suggested-domains').addClass('hidden').hide();
                    suggestionsLoader.addClass('hidden');
                    spotlightsLoader.addClass('hidden');
                    spotlightsContainer.removeClass('invisible');
                    jQuery('.spotlight-tlds, .domain-lookup-primary-loader').fadeOut('fast', function() { jQuery(this).hide(); });
                    hasDomainLookupEnded(1);
                    return;
                }
                if (suggestionsResult.length) {
                    suggestionDisplayChecker({ result: suggestionsResult });
                } else {
                    jQuery('.domain-lookup-message').hide();
                    jQuery('#domainSuggestions').addClass('hidden').hide();
                    jQuery('.suggested-domains').addClass('hidden').hide();
                    suggestionsLoader.addClass('hidden');
                }
                aiSpotlightStarted = true;
                if (jQuery('#primarySuggestionHeading').length) jQuery('#primarySuggestionHeading').show();
                jQuery('#searchDomainInfo').removeClass('hidden').show();
                lookupDisplayChecker({ result: [topResult] });
                var query = frmDomain.serializeArray();
                var msgItem = query.filter(function(item) { return item.name === 'message'; })[0];
                if (msgItem) msgItem.value = topResult.domainName;
                var spotlightReqChecker = jQuery.post(
                    WHMCS.utils.getRouteUrl('/domain/check'),
                    jQuery.param(query) + '&type=spotlight',
                    'json'
                );
                spotlightReqChecker.done(spotlightDisplayChecker).always(function () {
                    hasDomainLookupEnded(2);
                    spotlightsLoader.addClass('hidden');
                    spotlightsContainer.removeClass('invisible');
                });
            }).always(function () {
                showDomainSearchResults();
                jQuery('#btnCheckAvailability').removeAttr('disabled').removeClass('disabled');
                jQuery('#btnCheckAvailability > span').removeClass('invisible');
                if (!aiSpotlightStarted) {
                    hasDomainLookupEnded(1);
                } else {
                    hasDomainLookupEnded(2);
                }
            });
        } else {
        var lookup = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                frmDomain.serialize() + '&type=domain',
                'json'
            ),
            spotlight = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                frmDomain.serialize() + '&type=spotlight',
                'json'
            ),
            suggestion = jQuery.post(
                WHMCS.utils.getRouteUrl('/domain/check'),
                frmDomain.serialize() + '&type=suggestions',
                'json'
            );
        lookup.done(lookupDisplayChecker).always(function () {
            showDomainSearchResults();
            jQuery('#btnCheckAvailability').removeAttr('disabled').removeClass('disabled');
            jQuery('#btnCheckAvailability > span').removeClass('invisible');
            hasDomainLookupEnded(3);
        });
        // spotlight lookup handler
        spotlight.done(spotlightDisplayChecker).always(function () {
            hasDomainLookupEnded(3);
            spotlightsLoader.addClass('hidden');
            spotlightsContainer.removeClass('invisible');
        });
        // suggestions lookup handler
        suggestion.done(suggestionDisplayChecker).always(function () {
            hasDomainLookupEnded(3);
            suggestionsLoader.addClass('hidden');
        });
        }
    });

    $(document).on('change', '[data-tld-cycle-switcher]', function(){
        let addToCartButton = jQuery(this).closest('.spotlight, .domain-suggestion').find('.btn-add-to-cart');
        if (addToCartButton.hasClass('checkout')){
            addToCartButton.closest('.btn-group-remove').addClass('loading');
            let period = jQuery(this).val(),
                domain = addToCartButton.data('domain');
            
            updateDomainPeriod(domain, period);
        }
    });
    $(document).on('click', '[data-tld-cycle-switcher-option]', function(e){
        e.preventDefault();        
        let value = $(this).data('value'),
            insideHtml = $(this).data('html')
            button = $(this).closest('.dropdown-menu').siblings('[data-tld-cycle-switcher-button]'),
            text = button.find('.btn-text');
        text.html(insideHtml);
        $(this).closest('.dropdown-menu').attr('data-value', value);
        $('[data-tld-cycle-switcher-option]').each(function(){
            $(this).parent().removeClass('active')
        })
        $(this).parent().addClass('active')
        
        let addToCartButton = jQuery(this).closest('.message').find('.btn-add-to-cart');
        if (addToCartButton.hasClass('checkout')){
            addToCartButton.closest('.btn-group-remove').addClass('loading');
            let period = value;
                domain = addToCartButton.data('domain');
            updateDomainPeriod(domain, period);
        }

    });

    /*
    *******************************************
    5. Domain Transfer
    *******************************************
    */
    jQuery('#frmDomainTransfer').submit(function (e) {
        e.preventDefault();

        if (
            typeof recaptchaValidationComplete !== 'undefined'
            && typeof recaptchaType !== 'undefined'
            && recaptchaType === 'invisible'
            && recaptchaValidationComplete === false
        ) {
            return;
        }

        var frmDomain = jQuery('#frmDomainTransfer'),
            transferButton = jQuery('#btnTransferDomain'),
            inputDomain = jQuery('#inputTransferDomain'),
            authField = jQuery('#inputAuthCode'),
            domain = inputDomain.val(),
            authCode = authField.val(),
            authCodeModal = jQuery('#modal-epp-code');
            redirect = false,
            reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
            captcha = jQuery('#inputCaptcha');
        if (!domain) {
            inputDomain.tooltip('show');
            inputDomain.focus();
            return false;
        }

        if (domain.includes(" ") || domain.includes("https://") || domain.includes("http://") || domain.includes("/")){            
            domain = domain.replace(/ /g, '');
            domain = domain.replace('https://', '');
            domain = domain.replace('http://', '');
            domain = domain.replace(/\//g, '');
            inputDomain.val(domain);
        }
      
        inputDomain.tooltip('hide');
        if (jQuery('#captchaContainer').length) {
            validate_captcha(frmDomain);
            return;
        }
        reCaptchaContainer.tooltip('hide');
        captcha.tooltip('hide');
        transferButton.attr('disabled', 'disabled').addClass('disabled')
            .find('span:not(.loader)').addClass('invisible');
        jQuery.post(
            frmDomain.attr('action'),
            frmDomain.serialize(),
            'json'
        ).done(function (data) {
            if (typeof data != 'object') {
                transferButton.removeAttr('disabled').removeClass('disabled').find('#addToCart').removeClass('invisible');
                return false;
            }
            var result = data.result;
            if (result == 'added') {
                window.location = whmcsBaseUrl + '/cart.php?a=confdomains';
                redirect = true;
            } else {
                if (result.isRegistered == true) {
                    if (result.epp == true && !authCode) {
                        if(authCodeModal.hasClass('show')){
                            authField.tooltip('show');
                            authField.focus();  
                            authCodeModal.find('.invisible').removeClass('invisible');  
                        }
                        else{
                            authCodeModal.modal('show');
                        }
                    }
                } else {
                    authCodeModal.modal('hide');
                    authCodeModal.find('.invisible').removeClass('invisible');
                    jQuery('#transferUnavailable').html(result.unavailable)
                        .hide().removeClass('hidden').fadeIn('fast', function () {
                                setTimeout(function (input) {
                                        input.fadeOut('fast');
                                    },
                                    10000,
                                    jQuery(this)
                                );
                            }
                        );
                }
            }
        }).always(function () {
            if (redirect == false) {
                transferButton.removeAttr('disabled').removeClass('disabled').find('#addToCart').removeClass('invisible');
            }
        });
    });
    
    $('[data-epp-submit]').on('click', function(){
        var value = $('#inputAuthCode').val();
        $('input[name="epp"]').val(value);
        $('#frmDomainTransfer').submit();
    });

    /*
    *******************************************
    5. Update Config Options
    *******************************************
    */

    $("#frmConfigureProduct").on('change', 'select', function () {
        recalctotals();
    });
    jQuery("#frmConfigureProduct .section").not("#sectionCycles").on('ifChecked', 'input', function () {
        recalctotals();
    });
    jQuery("#frmConfigureProduct .section").not("#sectionCycles").on('ifUnchecked', 'input[type="checkbox"]', function () {
        recalctotals();
    });
    $("[data-change-billingcycle]").on('ifChecked', 'input', function () {
        setTimeout(function(){ recalctotals(); }, 150);
    });
    
    

    $("[data-update-config]").on('ifChecked', 'input', function () {
        $('#productConfigurableOptions').addClass('hidden');
        $('#lagomPageLoader').removeClass('hidden');
        $('#productAddonsContainer').addClass('hidden');      
        if (!jQuery("#orderSummaryLoader").is(":visible")) {
            jQuery("#orderSummaryLoader").fadeIn('fast');
        }
        if (!jQuery("#orderSummaryLoaderMob").is(":visible")) {
            jQuery("#orderSummaryLoaderMob").fadeIn('fast');
        }
        var i = $(this).closest('label').data("config-i");
        var billingCycle = $(this).closest('label').data("config-val");
        WHMCS.http.jqClient.post(whmcsBaseUrl + '/cart.php', 'a=cyclechange&ajax=1&i='+i+'&billingcycle='+billingCycle,
            function (data) {
                var co = jQuery('#productConfigurableOptions'),
                add = jQuery('#productAddonsContainer');
                if (co.length) {
                    co.html(jQuery(data).find('#productConfigurableOptions').html());
                }
                if (add.length) {
                    add.html(jQuery(data).find('#productAddonsContainer').html());
                }

                setTimeout(function(){
                    var checkboxes = $('#productConfigurableOptions, #productAddonsContainer').find('input:not(.icheck-input):not(.switch__checkbox)');

                    checkboxes.iCheck({
                        checkboxClass: 'checkbox-styled',
                        radioClass: 'radio-styled',
                        increaseArea: '40%'
                    });
                    reloadConfigOptions('#productConfigurableOptions');
                    if (typeof reloadCustomConfigOptions != 'undefined' && $.isFunction(reloadCustomConfigOptions) ) {
                        reloadCustomConfigOptions('#productConfigurableOptions');
                    }
                }, 100)

                $('#productConfigurableOptions').removeClass('hidden');
                $('#lagomPageLoader').addClass('hidden');
                $('#productAddonsContainer').removeClass('hidden');
                changeLogos();
            }
        )
        setTimeout(function(){ recalctotals(); }, 150);
    });
    /*
    *******************************************
    6. Serialize Config Form
    *******************************************
    */
    jQuery("#frmConfigureProduct").submit(function (e) {
        e.preventDefault();
        var button = jQuery('#btnCompleteProductConfig, #btnCompleteProductConfigMob'),
            btnOriginalText = jQuery(button).html(),
            postUrl = whmcsBaseUrl + '/cart.php',
            postData = 'a=confproduct&' + jQuery("#frmConfigureProduct").serialize();

        jQuery(button).find('.loader').removeClass('hidden');
        jQuery(button).find('span').addClass('invisible');

        displayRecommendations(
            postUrl,
            'addproductajax=1&' + postData,
            false
        ).done(function() {
            WHMCS.http.jqClient.post(
                postUrl,
                'ajax=1&' + postData,
                function(data) {
                    if (data) {
                        jQuery("#btnCompleteProductConfig").html(btnOriginalText);
                        jQuery("#btnCompleteProductConfigMob").html(btnOriginalText);
                        jQuery("#containerProductValidationErrorsList").html(data);
                        jQuery("#containerProductValidationErrors").removeClass('hidden').show();
                        jQuery(button).find('.loader').addClass('hidden');
                        jQuery(button).find('span').removeClass('invisible');
                        jQuery(button).prop('disabled', false).removeClass('disabled');
                        
                        // scroll to error container if below it
                        if (jQuery(window).scrollTop() > jQuery("#containerProductValidationErrors").offset().top) {
                            jQuery('html, body').scrollTop(jQuery("#containerProductValidationErrors").offset().top - 150);
                        }
                    } else {
                        window.location = whmcsBaseUrl + '/cart.php?a=confdomains';
                    }
                }
            );
        });
    });
    /*
    *******************************************
    7. Domain Renewals
    *******************************************
    */
    jQuery('#serviceRenewals').find('span.added').hide().end().find('span.to-add').find('i').hide();
    jQuery('#serviceRenewals').find('.btn-remove-renewal').hide();
    jQuery(document).on('click','.btn-add-renewal-to-cart',function () {
        var self = jQuery(this);
        var selfOuterWidth = self.outerWidth();
        var domainId = self.data('domain-id');
        var period = jQuery('#renewalPricing' + domainId).val();
        var postUrl;
        var postData;

        if (jQuery('#serviceRenewals').length >= 1) {
            var serviceId = self.data('service-id');
            if (serviceId.toString().startsWith('a-')) {
                postUrl = WHMCS.utils.getRouteUrl('/cart/service/' + serviceId.substr(2) + '/addon/renew');
            } else {
                postUrl = WHMCS.utils.getRouteUrl('/cart/service/' + serviceId + '/product/renew');
            }
            postData = {
                token: csrfToken
            };
        } else {
            var domainId = self.data('domain-id');
            postUrl = WHMCS.utils.getRouteUrl('/cart/domain/renew/add');
            postData = {
                domainId: domainId,
                period: jQuery('#renewalPricing' + domainId).val(),
                token: csrfToken
            };
        }

        if (self.hasClass('checkout')) {
            window.location = whmcsBaseUrl + '/cart.php?a=view';
            return;
        }
        if ($(this).closest('.panel').hasClass('domain-renewal-added')) {
            e.preventDefault();
        } else {
            jQuery.post(
                postUrl,
                postData,
                'json'
            ).done(function (data) {
                self.find('span.to-add').hide();
                self.find('.loader').css("display", "flex").show();
                if (data.result === 'added') {
                    setTimeout(function () {
                        self.find('.loader').hide().end().find('span.added').css("display", "flex");
                        self.closest('.panel').addClass('border-primary domain-renewal-added');
                        self.closest('.panel').find('.btn-remove-renewal').css("display", "flex");
                        self.removeClass('btn-primary-faded').addClass('btn-primary');
                    }, 500);
                }
                recalculateRenewalTotals();
            });
        }
    });
    jQuery(document).on('submit', '#removeRenewalForm', function (e) {
        e.preventDefault();

        var buttonId = '#renewDomain';
        if (jQuery('#serviceRenewals').length >= 1) {
            buttonId = '#renewService';
        }

        jQuery.post(
            whmcsBaseUrl + '/cart.php',
            jQuery(this).serialize() + '&ajax=1'
        ).done(function (data) {
            var domainId = data.i;
            var button = jQuery(buttonId + domainId);
            button.attr('disabled', 'disabled').each(function () {
                jQuery(this).find('span.added').hide().end()
                    .removeClass('checkout').find('span.to-add').show().end().removeAttr('disabled');
                jQuery(this).css('width', '');
                jQuery(this).closest('.panel').removeClass('border-primary domain-renewal-added');
                jQuery(this).removeClass('btn-primary').addClass('btn-primary-faded');
            });
            let renewAll = $('.page-domain-renewals [data-domain-renewals-add-all]');
            if (renewAll.length){
                renewAll.removeClass('disabled').prop('disabled', false);
            }
        }).always(function () {
            jQuery('#modalRemoveItem').modal('hide');
            recalculateRenewalTotals();
        });
    });
    jQuery('.select-renewal-pricing').on('change', function () {
        var
            domainId = $(this).data('domain-id'),
            period = $(this).val();
        if ($(this).closest('.panel').hasClass('domain-renewal-added')) {
            jQuery.post(
                WHMCS.utils.getRouteUrl('/cart/domain/renew/add'),
                {
                    domainId: domainId,
                    period: period,
                    token: csrfToken
                },
                'json'
            ).done(function (data) {
                recalculateRenewalTotals();
            });
        }
    });
    jQuery('#domainRenewalFilter').on('input', function () {
        var inputText = jQuery(this).val().toLowerCase();
        jQuery('#domainRenewals').find('div.search-renewal').filter(function () {
            jQuery(this).toggle(jQuery(this).data('search-name').toLowerCase().indexOf(inputText) > -1);
        }).promise().done(function(){
	        if (jQuery('div.search-renewal :visible').size() == 0) {
               jQuery('.no-renew').removeClass('hidden');
            } else {
               jQuery('.no-renew').addClass('hidden');
            }
	    });
    });

    jQuery('#serviceRenewalFilter').on('input', function() {
        var inputText = jQuery(this).val().toLowerCase();
        var hasMatchingInputs = function matchInputs(element, input) {
            var isInputMatched = false;
            if (inputText.length > 0) {
                jQuery('#hideShowServiceRenewalButton').find('span.to-show').hide().end()
                    .find('span.to-hide').show().end().removeAttr('disabled');
            }
            jQuery.each(element.data(), function(key, value) {
                if (String(value).toLowerCase().indexOf(input) > -1) {
                    isInputMatched = true;
                    return false;
                }
            });
            element.toggle(isInputMatched);
            return isInputMatched;
        }
        jQuery('#serviceRenewals').find('.service-renewal').filter(function() {
            var serviceRenewals = jQuery(this);
            var addonRenewals = serviceRenewals.find('.addon-renewals');
            var hasMatchingAddonItem = false;

            if (addonRenewals.length > 0) {
                addonRenewals.find('.service-renewal').filter(function() {
                    hasMatchingAddonItem = hasMatchingInputs(jQuery(this), inputText);
                });
            }
            if (hasMatchingAddonItem) {
                serviceRenewals.toggle(true);
            } else {
                hasMatchingInputs(serviceRenewals, inputText);
            }
            addonRenewals.toggle(hasMatchingAddonItem);
        });
    });

    /*
    *******************************************
    8. Empty Cart
    *******************************************
    */
    jQuery("#btnEmptyCart").click(function () {
        jQuery('#modalEmptyCart').modal('show');
    });
    /*
    *******************************************
    9. Use Credit on Checkout
    *******************************************
    */
    var useCreditOnCheckout = jQuery('#useCreditOnCheckout'),
        skipCreditOnCheckout = jQuery('#skipCreditOnCheckout');
    useCreditOnCheckout.on('ifChecked', function () {
        var radio = jQuery('#useCreditOnCheckout'),
            selectedPaymentMethod = jQuery('input[name="paymentmethod"]:checked'),
            selectedCC = jQuery('input[name="ccinfo"]:checked'),
            isCcSelected = selectedPaymentMethod.hasClass('is-credit-card'),
            firstNonCcGateway = jQuery('input[name="paymentmethod"]')
            .not(jQuery('input.is-credit-card[name="paymentmethod"]'))
            .first();
            container = jQuery('#paymentGatewaysContainer'),
            existingCardInfo = jQuery('#existingCardInfo'),
            ccInputFields = jQuery('#creditCardInputFields'),
            spanFullCredit = jQuery('#spanFullCredit'),
            shouldHideContainer = true;            
        if (radio.prop('checked')) {
            if (spanFullCredit.hasClass('hidden')) {
                shouldHideContainer = false;
            }
            if (isCcSelected && firstNonCcGateway.length !== 0) {
              
                firstNonCcGateway.closest('.panel-group').find('.panel.checked').removeClass('checked');
                firstNonCcGateway.iCheck('check').closest('.panel').addClass('checked');
                ccInputFields.addClass('hidden');
                
                if (shouldHideContainer) {
                    container.addClass('hidden');
                }  
            } else if (!isCcSelected && container.is(':visible')) {
                if (shouldHideContainer) {
                    container.addClass('hidden');
                }
            } else if ((!shouldHideContainer || isCcSelected) && !container.is(":visible")) {
                    ccInputFields.removeClass('hidden');
                    container.removeClass('hidden');
            }
            
            if (isCcSelected && selectedCC.val() !== 'new') {
                if (spanFullCredit.is(':visible')) {
                    hideCvcOnCheckoutForExistingCard = '1';
                    existingCardInfo.hide().find('input').attr('disabled', 'disabled');
                } else {
                    existingCardInfo.show().find('input').removeAttr('disabled');
                }
            }
        }
    });
    skipCreditOnCheckout.on('ifChecked', function () {
        var selectedPaymentMethod = jQuery('input[name="paymentmethod"]:checked'),
            isCcSelected = selectedPaymentMethod.hasClass('is-credit-card'),
            container = jQuery('#paymentGatewaysContainer');            
        if (!container.is(":visible")) {

            container.removeClass('hidden');
            if (isCcSelected) {
                
            }
        }
    });
    var applyCreditContainer = jQuery('#applyCreditContainer');

    if (
        applyCreditContainer.is(':visible')
        && applyCreditContainer.data('apply-credit') === 1
        && useCreditOnCheckout.length
    ) {
        skipCreditOnCheckout.iCheck('check');
        useCreditOnCheckout.iCheck('check');
    }
    /*
    *******************************************
    10. Payment Methods
    *******************************************
    */

   jQuery("#btnAlreadyRegistered").click(function() {
        jQuery("#containerNewUserSignup").slideUp('', function() {
            jQuery("#containerExistingUserSignin").slideDown('', function() {
                jQuery("#inputCustType").val('existing');
                jQuery("#btnAlreadyRegistered").fadeOut('', function() {
                    jQuery("#btnNewUserSignup").fadeIn();
                });
            });
        });
        jQuery("#containerNewUserSecurity").hide();
        if (jQuery("#stateselect").attr('required')) {
            jQuery("#stateselect").removeAttr('required').addClass('requiredAttributeRemoved');
        }
        jQuery('.marketing-email-optin').slideUp();
    });

    jQuery("#btnNewUserSignup").click(function() {
        jQuery("#containerExistingUserSignin").slideUp('', function() {
            jQuery("#containerNewUserSignup").slideDown('', function() {
                jQuery("#inputCustType").val('new');
                if (jQuery("#passwdFeedback").html().length == 0) {
                    jQuery("#containerNewUserSecurity").show();
                }
                jQuery("#btnNewUserSignup").fadeOut('', function() {
                    jQuery("#btnAlreadyRegistered").fadeIn();
                });
            });
            jQuery('.marketing-email-optin').slideDown();
        });
        if (jQuery("#stateselect").hasClass('requiredAttributeRemoved')) {
            jQuery("#stateselect").attr('required', 'required').removeClass('requiredAttributeRemoved');
        }
    });

    jQuery("#btnExistingLogin").click(() => {
        const inputLoginEmail = jQuery('#inputLoginEmail').val().trim();
        const inputLoginPassword = jQuery('#inputLoginPassword').val().trim();
        const btnExistingLogin = jQuery('#btnExistingLogin');

        jQuery('.checkout-error-feedback').hide();

        const loginPayload = {
            username: inputLoginEmail,
            password: inputLoginPassword,
            token: csrfToken
        };

        btnExistingLogin.prop('disabled', true)
            .addClass('disabled')
            .find('span').toggle();

        retrieveCaptchaInput()
            .then(captchaData => {
                if (!captchaData) {
                    return Promise.reject();
                }

                Object.assign(loginPayload, captchaData);

                return new Promise((resolve, reject) => {
                    WHMCS.http.jqClient.jsonPost({
                        url: WHMCS.utils.getRouteUrl('/login/cart'),
                        data: loginPayload,
                        success: (data) => {
                            if (data.redirectUrl) {
                                window.location.href = data.redirectUrl;
                            } else {
                                location.reload(true);
                            }
                            resolve();
                        },
                        error: (error) => {
                            reject(error);
                        }
                    });
                });
            })
            .catch((error) => {
                if (error) {
                    showCheckoutError(error, jQuery('#existingLoginMessage'));
                }
            })
            .finally(() => {
                btnExistingLogin.prop('disabled', false)
                    .removeClass('disabled')
                    .find('span').toggle();

                WHMCS.form.reloadCaptcha();
            });
    });


    jQuery('.account-select').on('ifChecked', function(event) {
        var userSignupContainer = jQuery('#containerNewUserSignup'),
            stateSelect = jQuery("#stateselect"),
            thisValue = jQuery(this).val(),
            btnCompleteOrder = jQuery('#btnCompleteOrder'),
            existingPayMethods = jQuery('#existingCardsContainer'),
            existingUserEmail = jQuery('#inputEmail'),
            templateName = jQuery('#existingCardsContainer').data('template');

        if (existingPayMethods.length) {
            existingPayMethods.html('');
        }

        if (existingUserEmail.length) {
            existingUserEmail.attr('value', '');
        }
        // jQuery('#containerExistingAccountSelect')
        //     .find('div.account.active')
        //     .removeClass('active');
        // jQuery(this).closest('div.account').addClass('active');
        if (thisValue === 'new') {
            if (userSignupContainer.not(':visible')) {
                // userSignupContainer.hide().removeClass('hidden').slideDown('', function () {
                //     
                //     
                // });
                jQuery("#inputCustType").val('add');
                jQuery('.marketing-email-optin').slideDown();
                if (stateSelect.hasClass('requiredAttributeRemoved')) {
                    stateSelect.attr('required', 'required')
                        .removeClass('requiredAttributeRemoved');
                }
                
            }
        } else {
            btnCompleteOrder.addClass('disabled');

            if (btnCompleteOrder.hasClass('spinner-on-click')) {
                var icon = btnCompleteOrder.find('i.fas,i.far,i.fal,i.fab');

                jQuery(icon)
                    .data('original-class', icon.attr('class'))
                    .removeAttr('class')
                    .addClass('fas fa-spinner fa-spin');
            }

            jQuery("#inputCustType").val('account');
            if (userSignupContainer.is(':visible')) {
                userSignupContainer.slideUp();
                if (stateSelect.attr('required')) {
                    stateSelect.removeAttr('required')
                        .addClass('requiredAttributeRemoved');
                }
                jQuery('.marketing-email-optin').slideUp();
            }
        }
        WHMCS.http.jqClient.jsonPost({
            url: WHMCS.utils.getRouteUrl('/cart/account/select'),
            data: {
                account_id: thisValue,
                token: csrfToken
            },
            success: function(data) {                
                var creditDiv = jQuery('#applyCreditContainer');
                jQuery('#totalDueToday').text(data.total);
                creditDiv.closest('.panel').find('.credit-balance > span').text(data.creditBalance);
                if (!data.canUseCreditOnCheckout && creditDiv.is(':visible')) {
                    var skipCreditOnCheckout = jQuery('#skipCreditOnCheckout');
                    creditDiv.closest('.panel').addClass('hidden');
                    skipCreditOnCheckout.iCheck('check');
                } else if (data.canUseCreditOnCheckout) {
                    var useCreditOnCheckout = jQuery('#useCreditOnCheckout'),
                        spanFullCredit = jQuery('#spanFullCredit'),
                        spanUseCredit = jQuery('#spanUseCredit');
                    if (data.full) {
                        hideCvcOnCheckoutForExistingCard = '1';
                        spanFullCredit.removeClass('hidden').find('span').text(data.total);
                        if (!spanUseCredit.hasClass('hidden')) {
                            spanUseCredit.addClass('hidden');
                        }
                    } else {
                        hideCvcOnCheckoutForExistingCard = '0';
                        spanUseCredit.removeClass('hidden').find('span').text(data.creditBalance);
                        if (!spanFullCredit.hasClass('hidden')) {
                            spanFullCredit.addClass('hidden');
                        }
                    }
                    useCreditOnCheckout.iCheck('check');
                    if (creditDiv.not(':visible')) {
                        creditDiv.closest('.panel').removeClass('hidden');
                    }
                }
                
                if (existingPayMethods.length) {
                    existingPayMethods.html(data.existingCards);
                    if (data.existingCards == ""){
                        $('.cc-input-container .nav-tabs').hide();
                    }
                    else{
                        $('.cc-input-container .nav-tabs').show();
                    }
                   
                    let ccimg = existingPayMethods.find('.cc-item-icon img');
                    ccimg.each(function(){
                        $(this).prop('src', $(this).attr('src').replace('//', '/'+templateName+'/'));
                    });
                    existingPayMethods.find('input[type="radio"]').iCheck({
                        inheritID: true,
                        checkboxClass: 'checkbox-styled',
                        radioClass: 'radio-styled',
                        increaseArea: '40%'
                    });
                    jQuery(".payment-methods:checked").trigger('ifChecked');
                    selectPreferredCard();
                }
            },
            always: function() {
                btnCompleteOrder.removeClass('disabled');
                if (btnCompleteOrder.hasClass('spinner-on-click')) {
                    var icon = btnCompleteOrder.find('i.fas,i.far,i.fal,i.fab');

                    if (jQuery(icon).hasClass('fa-spinner')) {
                        jQuery(icon)
                            .removeAttr('class')
                            .addClass(icon.data('original-class'));
                    }
                }
            }
        });
    });

    var cvvFieldContainer = jQuery('#cvv-field-container'),
        existingCardContainer = jQuery('#existingCardsContainer'),
        newCardInfo = jQuery('#newCardInfo'),
        newCardSaveSettings = jQuery('#newCardSaveSettings'),
        inputNoStoreContainer = jQuery('#inputNoStoreContainer'),
        existingCardInfo = jQuery('#existingCardInfo'),
        newCardOption = jQuery('#new'),
        creditCardInputFields = jQuery('#creditCardInputFields');

    jQuery('[data-paymethod-id]').on('click', function(){
        if (jQuery(this).hasClass('disabled')){

        }
        else{
            jQuery('[data-paymethod-id]').removeClass('active');
            jQuery(this).addClass('active');
            jQuery(this).find('input[type=radio]').iCheck('check');
        }
       
    });

    jQuery('#creditCardInputFields [data-radio-tab]').on('click', function(e){
        e.preventDefault();
        jQuery(this).closest('#paymentGatewaysContainer').find('#newCardInfoTab').attr('style', false);
        jQuery(this).closest('#paymentGatewaysContainer').find('#existingCardsContainer').attr('style', false);
        var link = jQuery(this).attr('href');
        jQuery(this).closest('.nav-tabs').find('.active').removeClass('active');
        jQuery(this).parent().addClass('active');
        jQuery(this).closest('.cc-input-container').find('.tab-content').find('.active').removeClass('active');
        jQuery(this).closest('.cc-input-container').find('.tab-content').find(link).addClass('active');
        var radio = jQuery(this).find('input[type=radio]');
        var that = jQuery(this);
        setTimeout(function(){
            if (radio.is(':checked')){
                if (jQuery('.payment-methods:checked').val() === 'stripe') {
                    return;
                }
                that.closest('.cc-input-container').find('.tab-content').find('#newCardInfo').show();
            }
        },500);
       
    });

    jQuery(document).on('ifChecked', '.existing-card', function(event) {
        newCardSaveSettings.hide().find('input').attr('disabled', 'disabled');
        if (jQuery('.payment-methods:checked').data('remote-inputs') === 1) {
            return;
        }
        newCardInfo.find('input').attr('disabled', 'disabled');

        if (hideCvcOnCheckoutForExistingCard !== '1') {
            existingCardInfo.find('input').removeAttr('disabled');
        } else {
            existingCardInfo.find('input').attr('disabled', 'disabled');
        }


    });
    newCardOption.on('ifChecked', function(event) {
        if (jQuery('.payment-methods:checked').val() === 'stripe') {
            return;
        }
        newCardInfo.show().find('input').removeAttr('disabled');
        newCardSaveSettings.show().find('input').removeAttr('disabled');
        existingCardInfo.find('input').attr('disabled', 'disabled');
    });

    var hasValidCredidCard = false;

    // jQuery(".payment-methods").on('ifChecked', function(event) {
    // var existingCards = jQuery(document).find('.existing-card');

    var whmcsPaymentModuleMetadata = {
        _source: 'checkout',
    };
    jQuery(".payment-methods").each(function () {
        var element = jQuery(this);
        WHMCS.payment.event.gatewayInit(whmcsPaymentModuleMetadata, element.val());
        WHMCS.payment.event.gatewayOptionInit(whmcsPaymentModuleMetadata, element.val(), element);
    })
    .on('ifChecked', function(event) {
        WHMCS.payment.event.gatewayUnselected(whmcsPaymentModuleMetadata);
        WHMCS.payment.display.errorClear();
        var element = jQuery(this);
        var afterDefaultOnSelectOptions = {
            complete: function () {
                WHMCS.payment.event.gatewaySelected(whmcsPaymentModuleMetadata, element.val(), element);
            }
        };
        var existingCards = jQuery(document).find('.existing-card');
        if (!existingCards.length) {
            existingCardInfo.find('input').attr('disabled', 'disabled');
        }
        reloadConfigOptions('#paymentGatewaysDetails');
        if (jQuery(this).hasClass('is-credit-card')) {
            var gatewayPaymentType = jQuery(this).data('payment-type'),
                gatewayModule = jQuery(this).val(),
                showLocal = jQuery(this).data('show-local'),
                relevantMethods = [];
            if (gatewayPaymentType === 'RemoteCreditCard' && gatewayModule != "paypal_acdc") {
                inputNoStoreContainer.hide().find('input').prop('disabled', 'disabled').iCheck('update');
            } else {
                if (!(inputNoStoreContainer.is(':visible'))) {
                    inputNoStoreContainer.show().find('input').removeProp('disabled').iCheck('update');
                }
            }
            existingCards.each(function(index) {
                var paymentType = jQuery(this).data('payment-type'),
                    paymentModule = jQuery(this).data('payment-gateway'),
                    payMethodId = jQuery(this).val();

                var paymentTypeMatch = (paymentType === gatewayPaymentType);

                var paymentModuleMatch = false;
                if (gatewayPaymentType === 'RemoteCreditCard') {
                    // only show remote credit cards that belong to the selected gateway
                    paymentModuleMatch = (paymentModule === gatewayModule);
                } else if (gatewayPaymentType === 'CreditCard') {
                    // any local credit card can be used with any credit card gateway
                    paymentModuleMatch = true;
                }

                if (showLocal && paymentType === 'CreditCard') {
                    paymentTypeMatch = true;
                    paymentModuleMatch = true;
                }
                
                var payMethodElements = jQuery('[data-paymethod-id="' + payMethodId + '"]');              
                if (paymentTypeMatch && paymentModuleMatch) {
                    jQuery(payMethodElements).show();
                    relevantMethods.push(this);
                } else {
                    jQuery(payMethodElements).hide();
                }
            });

            var payTabs = jQuery('#creditCardInputFields .cc-input-container > .nav-tabs');
            if (relevantMethods.length){
                payTabs.show();
            }
            else{
                payTabs.hide();
            }

            var enabledRelevantMethods = relevantMethods.filter(function (item) {
                return ! jQuery(item).attr('disabled');
            });

            if (enabledRelevantMethods.length > 0) {
                var defaultId = null;
                jQuery.each(enabledRelevantMethods, function(index, value) {
                    var jQueryElement = jQuery(value),
                        order = parseInt(jQueryElement.data('order-preference'), 10);
                    if ((defaultId === null) || (order < defaultId)) {
                        defaultId = jQueryElement.val();
                        if (order === 0) {
                            return false;
                        }
                    }
                });
                if (defaultId === null) {
                    defaultId = 'new';
                }

                jQuery.each(enabledRelevantMethods, function(index, value) {
                    var jQueryElement = jQuery(value);
                    if (jQueryElement.val() === defaultId) {
                        
                        jQueryElement.iCheck('check');
                        jQueryElement.closest('.cc-item').addClass('active');
                        return false;
                    }
                });  
                existingCardContainer.show();
                //existingCardInfo.removeClass('hidden').show().find('input').removeAttr('disabled');

                if (hideCvcOnCheckoutForExistingCard !== '1') {
                    existingCardInfo.removeClass('hidden').show().find('input').removeAttr('disabled');
                } else {
                    existingCardInfo.addClass('hidden').hide().find('input').attr('disabled', 'disabled');
                }

                jQuery(this).closest('#paymentGatewaysContainer').find('#existingCardsContainer').addClass('active');
                jQuery(this).closest('#paymentGatewaysContainer').find('#newCardInfoTab').removeClass('active');
                jQuery(this).closest('#paymentGatewaysContainer').find('.cc-input-container .nav-tabs .active').removeClass('active');
                jQuery(this).closest('#paymentGatewaysContainer').find('.cc-input-container .nav-tabs li').first().addClass('active');
            } 
            else {
                jQuery(newCardOption).iCheck('check');

                existingCardContainer.hide();
                existingCardInfo.hide().find('input').attr('disabled', 'disabled');
                jQuery(this).closest('#paymentGatewaysContainer').find('#existingCardsContainer').removeClass('active');
                jQuery(this).closest('#paymentGatewaysContainer').find('#newCardInfoTab').addClass('active');
                jQuery(this).closest('#paymentGatewaysContainer').find('.cc-input-container .nav-tabs .active').removeClass('active');
                jQuery(this).closest('#paymentGatewaysContainer').find('.cc-input-container .nav-tabs li').last().addClass('active');
                

                newCardInfo.show();
            }
            if (!creditCardInputFields.is(":visible")) {
                // $('#creditCardInputFields .panel').show();
                creditCardInputFields.slideDown(afterDefaultOnSelectOptions);
                creditCardInputFields.removeClass('hidden');
            } else {
                afterDefaultOnSelectOptions.complete();
            }
        }
        else {
            creditCardInputFields.removeClass('has-animate-height');
            // $('#creditCardInputFields .panel').show();
            // creditCardInputFields.addClass('hidden');
            creditCardInputFields.slideUp(afterDefaultOnSelectOptions);
          
        }
       
        if ($('[data-new-gateway-label]').length > 0){
            let newTab = $('[data-radio-target="#new"]');
            if (newTab.length > 0){
                let newTabText = newTab[0].textContent,
                    newText = $('[data-new-gateway-label]')[0].textContent,
                    defaultTextContent = $('[data-new-gateway-label]').data('default-text-content');
                if (newTabText != newText){
                    if (newText.replace(/(?:\r\n|\r|\n)/g, '').replace(/ /g, '') != ""){
                        newTab[0].textContent = newText;
                    }
                    else{
                        newTab[0].textContent = defaultTextContent;
                    }
                    
                }
                
            }
        }
        
    });


    jQuery('.cc-input-container .paymethod-info').click(function() {
        var payMethodId = $(this).data('paymethod-id');
        var input = jQuery('input[name="ccinfo"][value=' + payMethodId + ']:not(:disabled)');

        if (input.length > 0) {
            input.iCheck('check');
        }
    });

    $('button.btn-checkout').on('click', function(e) {
        
        var someCheckboxUnchecked = false;
        if($('.order-checkbox').length > 0){ //jeśli właczone tos w whmcs
            $('.order-checkbox').each(function(){
                let dataInput = $(this).attr('data-form-input');
                let dataAlert = $(this).find('.alert');
                let dataCheckbox = $(this).find('.checkbox');
                let isInputChecked = $(dataInput).is(":checked");

                let header = document.querySelector("#header");
                let isInSidebar = dataCheckbox.closest('.main-sidebar').length > 0;
                let scrollTopValue;
                let shouldScroll = isInSidebar ? window.innerWidth < 992 : true;
                
                if(!isInputChecked){
                    someCheckboxUnchecked = true;
                    if (shouldScroll) {
                        if (isInSidebar) {
                            if(header) {
                                scrollTopValue = dataCheckbox.offset().top - header.clientHeight - 24;
                            }
                        } else {
                            if(window.innerWidth < 992) {
                                scrollTopValue = dataCheckbox.offset().top - header.clientHeight - 24;
                            } else {
                                scrollTopValue = dataCheckbox.offset().top;
                            }
                        }
                        $('html, body').animate({
                            scrollTop: scrollTopValue
                        }, 500, function () {
                            dataAlert.removeClass('hidden');
                            dataCheckbox.addClass('has-error');
                        });
                    } else {
                        dataAlert.removeClass('hidden');
                        dataCheckbox.addClass('has-error');
                    }
                    return false;
                }
            });

            if(someCheckboxUnchecked){
                e.preventDefault();
                setTimeout(function(){
                    $('button.btn-checkout').find('span').removeClass('invisible');
                }, 600);
                return false;
            }
        }

        if ($('#validation_tax_id').length > 0 && $('#validation_tax_id').val() === 'true') {
            if (!validateTaxField() || !validateDomainContactTaxField()) {
                e.preventDefault();
                setTimeout(function(){
                    $('button.btn-checkout').find('span').removeClass('invisible');
                }, 600);
                return false;
            }
        }

        $('#submit-checkout').trigger('click');
        $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input]:not(.checked)').addClass('disabled');
        $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input]:not(.checked) input[type="radio"]').prop('disabled', true);
        
        if ($('.gateway-errors').length > 0) {
            setTimeout(function(){ 
                var gatewayError = $('.gateway-errors');
                if  ($(gatewayError).attr('style') == "undefined" || $(gatewayError).attr('style') == undefined){       
                    if ((!$(gatewayError).hasClass('w-hidden')) && ($(gatewayError)[0].innerText != "" || $(gatewayError).not(':empty'))){                   
                        $('#checkout .loader').addClass('hidden');
                        $('#checkout span').removeClass('invisible hidden');
                        $('#checkout2 .loader').addClass('hidden');
                        $('#checkout2 span').removeClass('invisible hidden');
                        $('#paymentGatewaysContainer > [data-inputs-container] > [data-virtual-input]').removeClass('disabled');
                        $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input] input[type="radio"]').prop('disabled', false);
                        $('.btn-checkout').removeClass('disabled').prop('disabled', false);
                    }
                }
                else{
                    if ((!$(gatewayError).hasClass('w-hidden') || $(gatewayError).attr('style').includes("display: block;")) && ($(gatewayError)[0].innerText != "" || $(gatewayError).not(':empty'))){                   
                        $('#checkout .loader').addClass('hidden');
                        $('#checkout span').removeClass('invisible hidden');
                        $('#checkout2 .loader').addClass('hidden');
                        $('#checkout2 span').removeClass('invisible hidden');
                        $('#paymentGatewaysContainer > [data-inputs-container] > [data-virtual-input]').removeClass('disabled');
                        $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input] input[type="radio"]').prop('disabled', false);
                        $('.btn-checkout').removeClass('disabled').prop('disabled', false);
                    }
                }

                
            }, 1500);

            let inputs = $('#frmCheckout').find('input');

            inputs.each(function(){
                if ($(this)[0].validity.valid === false){
                setTimeout(function(){  
                        $('#checkout .loader').addClass('hidden');
                        $('#checkout span').removeClass('invisible hidden');
                        $('#checkout2 .loader').addClass('hidden');
                        $('#checkout2 span').removeClass('invisible hidden');
                        $('#paymentGatewaysContainer > [data-inputs-container] > [data-virtual-input]').removeClass('disabled');
                        $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input] input[type="radio"]').prop('disabled', false);
                        $('.btn-checkout').removeClass('disabled').prop('disabled', false);
                    }, 1500);
                }
            });

        }
    });

    /*
    *******************************************
    11. Domain Contacts
    *******************************************
    */
    jQuery("#inputDomainContact").on('change', function () {
        if (this.value == "addingnew") {
            jQuery("#domainRegistrantInputFields").hide().removeClass('hidden').slideDown();
        } else {
            jQuery("#domainRegistrantInputFields").slideUp();
        }
    });


    jQuery('.mc-promo .btn-add').click(function(e) {
        var self = jQuery(this);
        self.attr('disabled', 'disabled')
            .find('span.arrow i').removeClass('fa-chevron-right').addClass('fa-spinner fa-spin');
        WHMCS.http.jqClient.post(
            whmcsBaseUrl + '/cart.php',
            {
                'a': 'addUpSell',
                'product_key': self.data('product-key'),
                'upsell_from': self.data('upsell-from'),
                'token': csrfToken
            },
            function (data) {
                if (typeof data.modal !== 'undefined') {
                    openModal(
                        data.modal,
                        '',
                        data.modalTitle,
                        '',
                        '',
                        data.modalSubmit,
                        data.modelSubmitId
                    );
                    return;
                }
                window.location.reload(true);
            },
            'json'
        );
    });

    jQuery(document).on('click', '#btnAddUpSellCheckout', function(e) {
        var upsellModalForm = jQuery('#upsellModalForm');
        WHMCS.http.jqClient.post(
            whmcsBaseUrl + '/cart.php',
            upsellModalForm.serialize(),
            function (data) {
                if (data.done){
                    jQuery('#totalCartPrice').text(data.newTotal);
                }
            },
            'json'
        );
        return false;
    });

    jQuery('.mc-promo .header').on('click', function(e) {
        e.preventDefault();
        if (jQuery(e.target).is('.btn, .btn span,.btn .ls')) {
            return;
        }
        if (jQuery(this).parent().find('.rotate').hasClass('lm-plus')){
            jQuery(this).parent().find('.rotate').removeClass('lm-plus').addClass('lm-minus');
        }
        else{
            jQuery(this).parent().find('.rotate').removeClass('lm-minus').addClass('lm-plus');
        }
        jQuery(this).parent().find('.body').slideToggle('fast');
    });
    jQuery('.mc-promos.viewcart .mc-promo:first-child .header').click();

    // Hide/show Non-Renewable Services and Service Addons
    jQuery(this).find('span.to-hide').hide().end()
        .find('span.to-show').show().end().removeAttr('disabled');
    hideNoneRenewableServices();
    jQuery('#hideShowServiceRenewalSwitch').on('change', function() {
        if ($(this).is(':checked')) {
            jQuery(this).find('span.to-show').hide().end()
                .find('span.to-hide').show().end().removeAttr('disabled');
            showNoneRenewableServices();
        } else {
            jQuery(this).find('span.to-hide').hide().end()
                .find('span.to-show').show().end().removeAttr('disabled');
            hideNoneRenewableServices();
        }
    });

    checkoutForm = jQuery('#frmCheckout');
    if (checkoutForm.length) {
        // checkoutForm.on('submit', validateCheckoutCreditCardInput);
        checkoutForm.on('submit', validateCheckoutCreditCardInput);
        checkoutForm.on('submit.paymentjs', function (event) {
            WHMCS.payment.event.checkoutFormSubmit(
                {...whmcsPaymentModuleMetadata, ...{event: event}},
                WHMCS.payment.event.previouslySelected.module,
                jQuery(this)
            );
        });
    }

    jQuery(".payment-methods:checked").trigger('ifChecked');
    if (existingCardContainer.is(':visible')) {
        newCardInfo.hide();
    }

    jQuery('[data-tos-checkbox]').on('ifChanged', function(){
        checkTos(jQuery(this).prop('checked'))
    });
    jQuery('[data-custom-tos]').each(function(){
        $(this).on('ifChanged', function(){
            let checkId = $(this).closest('.order-checkbox').data('form-input');
            let checkValue = $(this).prop('checked');
            $(checkId).prop('checked', checkValue);
        });
    });

    jQuery('[data-tos-checkbox], [data-custom-tos]').on('ifChecked', function(){
        var checkboxContainer = $(this).closest('.order-checkbox');
        checkboxContainer.find('.checkbox').removeClass('has-error');
        checkboxContainer.find('.alert').addClass('hidden');
    });

    checkTos(jQuery('[data-tos-checkbox]').prop('checked'));


    /*
    ************************************************************
    12. Change Domain Register Period on Configure Domains Page
    ************************************************************
    */

    jQuery('[data-configuredomains-tld-cycle-switcher]').on('change', function(){
        let domain = $(this).data('domain'),
            period = $(this).val(),
            container = $(this).closest('[data-configuredomains-tld-cycle-switcher-container]'),
            options = container.find('[data-domain-addon]');

        updateDomainPeriod(domain, period);

        options.each(function(){
            let price = $(this).data('price'),
                lang = $(this).data('lang-years'),
                prefix = $(this).data('currency-prefix'),
                suffix = $(this).data('currency-suffix'),
                calculatePrice = period * price,
                fullText = prefix+calculatePrice.toFixed(2)+suffix+' <span> / '+period+' '+lang+'</span>';

            $(this).html(fullText);
        });
    });

    /*
    ************************************************************
    13. Submit Login From on Checkout Page by Enter Key
    ************************************************************
    */

    let loginBtn = $('.page-viewcart #frmCheckout #btnExistingLogin'),
        loginInput = $('.page-viewcart #frmCheckout #inputLoginEmail'),
        passwordInput = $('.page-viewcart #frmCheckout #inputLoginPassword');
    
        if (loginBtn.length && loginInput.length && passwordInput.length){
            loginInput.on('keypress', function(event){
                if (event.keyCode == "13"){
                    event.preventDefault();
                    loginBtn.click();
                }
            });
            passwordInput.on('keypress', function(event){
                if (event.keyCode == "13"){
                    event.preventDefault();
                    loginBtn.click();
                }
            });
        }

        /*
        ************************************************************
        14. Renew all domains
        ************************************************************
        */
        let renewAll = $('.page-domain-renewals [data-domain-renewals-add-all]'),
            renewAllContainer = $('.page-domain-renewals [data-domain-renewals-add-all-container]'),
            renewAllCounter = $('.page-domain-renewals [data-domain-renewals-add-all-counter]');

        if (renewAll.length){
            let checkRenewalsAjaxUrl = renewAll.data('check-renew-url');
            $.ajax({
                type: 'POST',
                url: checkRenewalsAjaxUrl,
                success: function (data) {
                    let counter = renewAll.data('renewals-in-cart'),
                        allDomains = parseInt(counter) + parseInt(data);
                    renewAllCounter.html(allDomains);   
                    if (data == 0){
                        renewAll.addClass('disabled').prop('disabled', true);
                    }
                    if (allDomains != 0){
                        renewAllContainer.removeClass('hidden');
                    }  
                }
            });

            renewAll.on('click', function(){
                let text = $(this).find('.btn-text');
                let loader = $(this).find('loader');
                let ajaxUrl = $(this).data('ajax-url');

                text.addClass('invisible');
                loader.removeClass('hidden');

                $.ajax({
                    type: 'POST',
                    url: ajaxUrl,
                    success: function (data) {
                        
                        if (data == "true"){
                            $('[data-renewal-alert-no-domain]').hide();
                            $('[data-renewal-alert-added]').show();
                            renewAll.addClass('disabled').prop('disabled', true);
                            let buttons = $('#domainRenewals').find('.btn-add-renewal-to-cart')
                            if ($('#tableRenewalList').length){
                                buttons = $('#tableRenewalList').find('.btn-add-renewal-to-cart');
                            }

                            buttons.each(function () {
                                jQuery(this).find('span.added').show().end()
                                    .removeClass('checkout').find('span.to-add').hide().end();
                                
                                jQuery(this).closest('.panel').addClass('border-primary domain-renewal-added');
                                jQuery(this).addClass('btn-primary').removeClass('btn-primary-faded');
                            });

                            setTimeout(function(){
                                $('[data-renewal-alert-added]').hide();
                            },10000);

                            recalculateRenewalTotals();

                        } else {
                            $('[data-renewal-alert-no-domain]').show();
                            $('[data-renewal-alert-added]').hide();
                            setTimeout(function(){
                                $('[data-renewal-alert-no-domain]').hide();
                            }, 10000);
                        }  
                        text.removeClass('invisible');
                        loader.addClass('hidden');
                    }
                })
            });
        }
    });

/*
*******************************************
1. Product Domain Lookup Ended
*******************************************
*/
function hasProductDomainLookupEnded(total, button) {
    domainLookupCallCount++;
    if (domainLookupCallCount == total) {
        button.removeAttr('disabled').removeClass('disabled');
        button.find('span').removeClass('invisible');
        jQuery('input[name="domainoption"]').iCheck('enable');
    }
}
/*
*******************************************
2. Product Domain Lookup Ended
*******************************************
*/
function hasDomainLookupEnded(queryCnt) {
    queryCnt = (typeof queryCnt !== 'undefined') ? queryCnt : 3;
    domainLookupCallCount++;
    if (domainLookupCallCount == queryCnt) {
        jQuery('#btnCheckAvailability').removeAttr('disabled').removeClass('disabled');
        jQuery('#btnCheckAvailability > span').removeClass('invisible');
    }
}
/*
*******************************************
2. Recalc Totals
*******************************************
*/
function recalctotals() {
    if (!jQuery("#orderSummaryLoader").is(":visible")) {
        jQuery("#orderSummaryLoader").fadeIn('fast');
    }
    if (!jQuery("#orderSummaryLoaderMob").is(":visible")) {
        jQuery("#orderSummaryLoaderMob").fadeIn('fast');
    }
    var thisRequestId = Math.floor((Math.random() * 1000000) + 1);
    window.lastSliderUpdateRequestId = thisRequestId;
    var post = WHMCS.http.jqClient.post(whmcsBaseUrl + '/cart.php', 'ajax=1&a=confproduct&calctotal=true&' + jQuery("#frmConfigureProduct").serialize());
    post.done(
        function (data) {
            if (thisRequestId == window.lastSliderUpdateRequestId) {
                let summaryStyle = jQuery("#producttotal").data('summary-style');
                let summaryTotalText = jQuery('#producttotal').data('summary-total-text');
                let summaryTotalTextVat = jQuery('#producttotal').data('summary-total-text-vat');
                let summaryTotalTextExvat = jQuery('#producttotal').data('summary-total-text-exvat');
                let summaryMainGraphic = jQuery('[data-summary-main-graphic]').html();
                let summaryAddonGraphic = jQuery('[data-summary-addons-graphics]');
                jQuery("#producttotal").html(data);
                if (summaryStyle == "primary"){
                    jQuery("#producttotal").find('.btn-checkout').removeClass('.btn-primary').addClass('btn-primary-faded');
                }
                if (summaryTotalText || summaryTotalTextVat || summaryTotalTextExvat){
                    let totalTextValue = jQuery("#producttotal").find('[data-total-text]').attr('data-total-text');
                    if (totalTextValue == "incVat"){
                        jQuery("#producttotal").find('[data-total-text]').html(summaryTotalTextVat);
                    } else if (totalTextValue == "exVat"){
                        jQuery("#producttotal").find('[data-total-text]').html(summaryTotalTextExvat);
                    } else {
                        jQuery("#producttotal").find('[data-total-text]').html(summaryTotalText);
                    }
                }
                
                if (summaryMainGraphic){
                    jQuery("#producttotal").find('[data-product-main-graphic]').html(summaryMainGraphic);
                }
                if (summaryAddonGraphic.length){
                    let summaryAddons = jQuery("#producttotal").find('[data-addon-main-graphic]');
                    if (summaryAddons.length){
                        summaryAddons.each(function(){
                            let addonid = $(this).data('addon-main-graphic');
                            let addonGraphic = summaryAddonGraphic.find('[data-addon-graphic="'+addonid+'"]').html();
                            if (addonGraphic){
                                $(this).html(addonGraphic);
                            } 
                        });
                    }
                }
                jQuery("#producttotalmob").html(data);
            }
        }
    );
    post.always(
        function () {
            jQuery("#orderSummaryLoader").delay(500).fadeOut('slow');
            jQuery("#orderSummaryLoaderMob").delay(500).fadeOut('slow');
            $('#sticky-sidebar').stickySidebar('updateSticky');
        }
    );
}
/*
*******************************************
3. Recalc Renew Totals
*******************************************
*/
function recalculateRenewalTotals() {
    var routePath = '/cart/domain/renew/calculate';
    if (jQuery('#serviceRenewals').length >= 1) {
        routePath = '/cart/service/renew/calculate';
    }

    if (!jQuery("#orderSummaryLoader").is(":visible")) {
        jQuery("#orderSummaryLoader").fadeIn('fast');
    }
    var thisRequestId = Math.floor((Math.random() * 1000000) + 1);
    window.lastSliderUpdateRequestId = thisRequestId;
    jQuery.get(
        WHMCS.utils.getRouteUrl(routePath)
    ).done(function (data) {
        if (thisRequestId === window.lastSliderUpdateRequestId) {
            let summaryStyle = jQuery("#producttotal").data('summary-style');
            jQuery("#producttotal").html(data.body);
            if (summaryStyle == "primary"){
                jQuery("#producttotal").find('.btn-checkout').removeClass('.btn-primary').addClass('btn-primary-faded');
            }
            jQuery("#producttotalmob").html(data.body);
        }
    }).always(
        function () {
            jQuery("#orderSummaryLoader").delay(500).fadeOut('slow');
            jQuery("#orderSummaryLoaderMob").delay(500).fadeOut('slow');
        }
    );
}
/*
*******************************************
4. Remove Item
*******************************************
*/
function removeItem(type, num, renewalType = null) {
    if (renewalType !== null) {
        jQuery('#inputRemoveItemRenewalType').val(renewalType);
    }
    jQuery('#inputRemoveItemType').val(type);
    jQuery('#inputRemoveItemRef').val(num);
    jQuery('#modalRemoveItem').modal('show');
}
/*
*******************************************
5. Select Domain Period
*******************************************
*/
function selectDomainPeriodInCart(element ,domainName, price, period, yearsString) {
    var loader = jQuery("#orderSummaryLoader");
    var loaderMob = jQuery("#orderSummaryLoaderMob");
    var clickedElement = jQuery(element);
    if($('[data-prices-without-suffix]').length){
        var currencySuffix = $('[data-prices-without-suffix]').data('prices-without-suffix');
    }
    loader.fadeIn('fast');
    loaderMob.fadeIn('fast');

    clickedElement.parent().siblings().each(function(){
        $(this).removeClass('active');
    }) 
    clickedElement.parent().addClass('active');

    if ($('[data-prices-without-suffix]').length) {
        jQuery("[name='" + domainName + "Pricing']").html('<span data-domain-price-multi-price>' + price.replace(currencySuffix, '') + '/' +period+yearsString+ '</span><span class="caret"></span>');
    } else {
        jQuery("[name='" + domainName + "Pricing']").html('<span data-domain-price-multi-price>' + price + '/' +period+yearsString+ '</span><span class="caret"></span>');
    }

    var update = jQuery.post(
        window.location.pathname,
        {
            domain: domainName,
            period: period,
            a: 'updateDomainPeriod',
            token: csrfToken
        }
    );
    update.done(
        function (data) {
            if(typeof(stripe) !== "undefined") {
                updateStripe();
            }
            data.domains.forEach(function (domain) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery("[name='" + domain.domain + "Pricing']").closest('.cart-item-price').find('.renewal-price').html(
                        domain.renewprice.replace(currencySuffix, '') + domain.shortRenewalYearsLanguage
                    );
                }else{
                    jQuery("[name='" + domain.domain + "Pricing']").closest('.cart-item-price').find('.renewal-price').html(
                        domain.renewprice + domain.shortRenewalYearsLanguage
                    );
                }
                
                // Update domain addon prices based on new registration period
                // Use the period parameter passed to the function, or fallback to domain.regperiod
                var domainAddonsContainer = jQuery('[data-domain-addons="' + domain.domain + '"]');
                if (domainAddonsContainer.length) {
                    var newPeriod = (domain.domain === domainName ? period : domain.regperiod) || domain.regperiod || 1;
                    domainAddonsContainer.find('[data-domain-addon]').each(function() {
                        var addonElement = jQuery(this);
                        var basePrice = parseFloat(addonElement.data('domain-addon-base')) || 0;
                        var currencyPrefix = addonElement.data('currency-prefix') || '';
                        var currencySuffix = addonElement.data('currency-suffix') || '';
                        
                        if (basePrice > 0) {
                            var calculatedPrice = basePrice * newPeriod;
                            if ($('[data-prices-without-suffix]').length){
                                var formattedPrice = currencyPrefix + calculatedPrice.toFixed(2).replace(currencySuffix, '');
                            } else {    
                                var formattedPrice = currencyPrefix + calculatedPrice.toFixed(2) + currencySuffix;
                            }
                            addonElement.text(formattedPrice);
                            addonElement.attr('data-domain-addon-current', newPeriod);
                        } else {
                            if($('[data-zero-value-lang]').length){
                                addonElement.text($('[data-zero-value-lang]').data('zero-value-lang'));
                            } else {
                                if ($('[data-prices-without-suffix]').length){
                                    addonElement.text(currencyPrefix + basePrice.toFixed(2));
                                } else {
                                    addonElement.text(currencyPrefix + basePrice.toFixed(2) + currencySuffix);
                                }
                            }
                        }
                    });
                }
            });

            if($('[data-prices-without-suffix]').length){
                jQuery('[data-subtotal]').find('.item-value').html(data.subtotal.replace(currencySuffix, ''));
            } else {
                jQuery('[data-subtotal]').find('.item-value').html(data.subtotal);
            }
            if (data.promotype) {
                if($('[data-prices-without-suffix]').length){
                    jQuery('#discount').html(data.discount.replace(currencySuffix, ''));
                } else {
                    jQuery('#discount').html(data.discount);
                }
            }
            if (data.taxrate) {
                if($('[data-prices-without-suffix]').length){
                    jQuery('#taxTotal1').html(data.taxtotal.replace(currencySuffix, ''));
                } else {
                    jQuery('#taxTotal1').html(data.taxtotal);
                }
            }
            if (data.taxrate2) {
                if($('[data-prices-without-suffix]').length){
                    jQuery('#taxTotal2').html(data.taxtotal2.replace(currencySuffix, ''));
                } else {
                    jQuery('#taxTotal2').html(data.taxtotal2);
                }
            }
            var recurringSpan = jQuery('#recurring');           
            recurringSpan.find('li').not('.faded').hide();
            if (data.totalrecurringannually) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery('#recurringAnnually').show().find('.item-value')
                        .html(data.totalrecurringannually.replace(currencySuffix, ''));
                } else {
                    jQuery('#recurringAnnually').show().find('.item-value')
                        .html(data.totalrecurringannually);
                }
            }
            
            if (data.totalrecurringbiennially) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery('#recurringBiennially').show().find('.item-value')
                        .html(data.totalrecurringbiennially.replace(currencySuffix, ''));
                } else {
                    jQuery('#recurringBiennially').show().find('.item-value')
                        .html(data.totalrecurringbiennially);
                }
            }
            
            if (data.totalrecurringmonthly) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery('#recurringMonthly').show().find('.item-value')
                        .html(data.totalrecurringmonthly.replace(currencySuffix, ''));
                } else {
                    jQuery('#recurringMonthly').show().find('.item-value')
                        .html(data.totalrecurringmonthly);
                }
            }
            
            if (data.totalrecurringquarterly) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery('#recurringQuarterly').show().find('.item-value')
                        .html(data.totalrecurringquarterly.replace(currencySuffix, ''));
                } else {
                    jQuery('#recurringQuarterly').show().find('.item-value')
                        .html(data.totalrecurringquarterly);
                }
            }
            
            if (data.totalrecurringsemiannually) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery('#recurringSemiAnnually').show().find('.item-value')
                        .html(data.totalrecurringsemiannually.replace(currencySuffix, ''));
                } else {
                    jQuery('#recurringSemiAnnually').show().find('.item-value')
                        .html(data.totalrecurringsemiannually);
                }
            }
            
            if (data.totalrecurringtriennially) {
                if ($('[data-prices-without-suffix]').length) {
                    jQuery('#recurringTriennially').show().find('.item-value')
                        .html(data.totalrecurringtriennially.replace(currencySuffix, ''));
                } else {
                    jQuery('#recurringTriennially').show().find('.item-value')
                        .html(data.totalrecurringtriennially);
                }
            }

            if ($('[data-prices-without-suffix]').length) {
                jQuery('#totalDueToday').html(data.total.replace(currencySuffix, ''));
            } else {
                jQuery('#totalDueToday').html(data.total);
            }

            var promoSubtotal = $('[data-promo-subtotal]');
            if (promoSubtotal.length){
                var promoSubtotalValue = promoSubtotal.data('promo-subtotal');
                var promoTotal = (parseFloat(data.rawdiscount) + parseFloat(data.rawtotal)).toFixed(2);
                if (promoSubtotalValue.includes('0.00')){
                    promoSubtotalValue = promoSubtotalValue.replace('0.00', promoTotal);
                } else {
                    promoSubtotalValue = promoSubtotalValue.replace('0,00', promoTotal);
                }
                
                if ($('[data-prices-without-suffix]').length) {
                    promoSubtotal.html(promoSubtotalValue.replace(currencySuffix, ''));
                }
                else{
                    promoSubtotal.html(promoSubtotalValue);
                }
            }

            if ($('[data-prices-without-suffix]').length) {
                jQuery('#totalDueTodayMob').html(data.total.replace(currencySuffix, ''));
            } else {
                jQuery('#totalDueTodayMob').html(data.total);
            }

        }
    );
    update.always(
        function () {
            loader.delay(500).fadeOut('slow');
            loaderMob.delay(500).fadeOut('slow');
        }
    );
}
/*
*******************************************
6. Validate Captcha
*******************************************
*/
function validate_captcha(form)
{
    var reCaptcha = jQuery('#g-recaptcha-response'),
        reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
        captcha = jQuery('#inputCaptcha');
    if (reCaptcha.length && !reCaptcha.val()) {
        reCaptchaContainer.tooltip('show');
        return false;
    }
    if (captcha.length && !captcha.val()) {
        captcha.tooltip('show');
        return false;
    }
    var validate = jQuery.post(
        form.attr('action'),
        form.serialize() + '&a=validateCaptcha',
        'json'
    );
    validate.done(function (data) {
        if (data.error) {
            jQuery('#inputCaptcha').attr('data-original-title', data.error).tooltip('show');
            if (captcha.length) {
                jQuery('#inputCaptchaImage').replaceWith(
                    '<img id="inputCaptchaImage" src="' + whmcsBaseUrl + '/includes/verifyimage.php?nocache=' + new Date().getTime() + '" align="middle" />'
                );
            }
        } else {
            jQuery('#captchaContainer').remove();
            form.trigger('submit');
        }
    });
}
/*
*******************************************
7. More Suggestions
*******************************************
*/

function loadMoreSuggestions()
{
    var suggestions = jQuery('#domainSuggestions'),
        suggestionCount;

    for (suggestionCount = 1; suggestionCount <= 10; suggestionCount++) {
        if (furtherSuggestions > 0) {
            suggestions.find('li.domain-suggestion.hidden.clone:first').not().hide().removeClass('hidden').slideDown();
            furtherSuggestions = suggestions.find('li.domain-suggestion.clone.hidden').length;
        } else {
            jQuery('div.more-suggestions').find('a').addClass('hidden').end().find('span.no-more').removeClass('hidden');
            return;
        }
    }
}

function retrieveCaptchaInput() {
    return new Promise((resolve, reject) => {
        const captcha = jQuery('#inputCaptcha');
        const reCaptchaContainer = jQuery('.g-recaptcha');

        if (captcha.length) {
            const captchaValue = captcha.val().trim();
            if (!captchaValue) {
                captcha.tooltip('show').focus();
                reject('');
                return;
            }

            captcha.tooltip('hide');
            resolve({code: captchaValue});
            return;
        }

        if (
            (recaptchaType === 'invisible' || recaptchaType === 'v3')
            && typeof recaptchaValidationComplete !== 'undefined'
            && !recaptchaValidationComplete
        ) {
            if (typeof grecaptcha !== 'undefined' && grecaptcha.execute) {
                WHMCS.recaptcha.setupCallback((token) => {
                    if (!token) {
                        reject('');
                        return;
                    }

                    recaptchaValidationComplete = true;
                    resolve({'g-recaptcha-response': token});
                });

                grecaptcha.execute()?.catch((error) => {
                    reject(error);
                });

                if (grecaptcha.getResponse()) {
                    resolve({'g-recaptcha-response': grecaptcha.getResponse()});
                }
            } else {
                reject('');
            }

            return;
        }

        if (typeof grecaptcha !== 'undefined') {
            const reCaptchaValue = grecaptcha.getResponse();

            if (!reCaptchaValue) {
                reCaptchaContainer[0]?.scrollIntoView({block: 'center'});
                reject('');
                return;
            }

            resolve({'g-recaptcha-response': reCaptchaValue});
            return;
        }

        resolve({});
    });
}

/*
*******************************************
8. Checkout Form
*******************************************
*/

function validateCheckoutCreditCardInput(e)
{
    var newOrExisting = jQuery('input[name="ccinfo"]:checked').val(),
        submitButton = checkoutForm.find('*[type="submit"]'),
        cardType = null,
        submit = true,
        selectedPaymentMethod = checkoutForm.find('input[name="paymentmethod"]:checked'),
        isCreditCardGateway = selectedPaymentMethod.hasClass('is-credit-card'),
        isRemoteCard = selectedPaymentMethod.data('payment-type') === 'RemoteCreditCard',
        cardNumber = jQuery('#inputCardNumber');

    checkoutForm.find('.form-group').removeClass('has-error');
    checkoutForm.find('.field-error-msg').hide();

    if (isCreditCardGateway && !isRemoteCard) {
        var cvvField = checkoutForm.find('#inputCardCVV2');

        if (newOrExisting === 'new') {
            cvvField = checkoutForm.find('#inputCardCVV');

            cardType = jQuery.payment.cardType(checkoutForm.find('#inputCardNumber').val());
            if (!jQuery.payment.validateCardNumber(checkoutForm.find('#inputCardNumber').val()) || cardNumber.hasClass('unsupported')) {
                var error = cardNumber.data('message-invalid');
                if (cardNumber.hasClass('unsupported')) {
                    error = cardNumber.data('message-unsupported');
                }
                checkoutForm.find('#inputCardNumber').setInputError(error).showInputError();
                submit = false;
            }
            if (
                !jQuery.payment.validateCardExpiry(
                    checkoutForm.find('#inputCardExpiry').payment('cardExpiryVal')
                )
            ) {
                checkoutForm.find('#inputCardExpiry').showInputError();
                submit = false;
            }
        }
        if (cvvField.is(':visible') && !jQuery.payment.validateCardCVC(cvvField.val(), cardType)) {
            cvvField.showInputError();
            submit = false;
        }
        if (!submit) {
            e.preventDefault();
            setTimeout(function(){ 
                $('#checkout .loader').addClass('hidden');
                $('#checkout span').removeClass('invisible hidden');
                $('#checkout2 .loader').addClass('hidden');
                $('#checkout2 span').removeClass('invisible hidden');
                $('.btn-checkout').removeClass('disabled').prop('disabled', false);
            }, 1500);  
        }
    }
}
function selectPreferredCard()
{
    var methods = jQuery('input[name="ccinfo"]:visible'),
        select = methods.first(),
        preferred = methods.filter('[data-order-preference=0]');
    if (preferred.length) {
        select = preferred;
    }
    select.iCheck('check');
}

function showNoneRenewableServices()
{
    jQuery('.service-renewal, .addon-renewals').each(function () {
        if (jQuery(this).attr('data-is-renewable') === 'false') {
            jQuery(this).show();
        }
    });
}

function hideNoneRenewableServices()
{
    jQuery('.service-renewal, .addon-renewals').each(function (i, element) {
        var isRenewable = jQuery(this).attr('data-is-renewable');
        if (isRenewable === 'false') {
            if (hasRenewableServiceAddon(element)) {
                jQuery(this).show();
            } else {
                jQuery(this).hide();
            }
        } else if (isRenewable === 'true' ) {
            jQuery(this).show();
        }
    });
}

function hasRenewableServiceAddon(data)
{
    var hasService = false;
    jQuery(data).find('div.service-renewal').each(function (i, element) {
        if (jQuery(element).attr('data-is-renewable') === 'true') {
            return hasService = true;
        }
    });
    return hasService;
}

jQuery(document).ready(function() {
    if ($('.gateway-errors').length > 0) {
        function mutate(mutations) {
            mutations.forEach(function (mutation) {                 
                if ((!$(mutation.target).hasClass('w-hidden') || $(mutation.target).attr('style').includes("display: block;")) && ($(mutation.target)[0].innerText != "") || $(mutation.target).not(':empty')){                   
                    $('#checkout .loader').addClass('hidden');
                    $('#checkout span').removeClass('invisible hidden');
                    $('#checkout2 .loader').addClass('hidden');
                    $('#checkout2 span').removeClass('invisible hidden');
                    $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input]').removeClass('disabled');
                    $('#paymentGatewaysContainer [data-inputs-container] > [data-virtual-input] input[type="radio"]').prop('disabled', false);
                    $('.btn-checkout').removeClass('disabled').prop('disabled', false);
                }
            });
        }
    
        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
        var target = document.querySelector('.gateway-errors');
        var observer = new MutationObserver(mutate);
        var config = {characterData: false, attributes: false, childList: true, subtree: true};
        observer.observe(target, config);
    } 
    jQuery('[data-radio-tab]').on('click', function(){
        if ($(this).attr('href') == "#existingCardsContainer"){
            selectPreferredCard();
            $('#existingCardsContainer').find('input[type="radio"]:checked').closest('.cc-item').addClass('active');
        }
    });
    
    if ($('[data-new-gateway-label]').length > 0){
        let newTab = $('[data-radio-target="#new"]');
        if (newTab.length > 0){
            let newTabText = newTab[0].textContent,
                newText = $('[data-new-gateway-label]')[0].textContent,
                defaultTextContent = $('[data-new-gateway-label]').data('default-text-content');
            if (newTabText != newText){
                if (newText.replace(/(?:\r\n|\r|\n)/g, '').replace(/ /g, '') != ""){
                    newTab[0].textContent = newText;
                }
                else{
                    newTab[0].textContent = defaultTextContent;
                }
                
            }
            
        }
    }
});

/*
*******************************************
9. Select Product Billing Cycle
*******************************************
*/

function selectProductPeriodInCart(element, index, cycle, fullString)
{
    jQuery("[name='" + index + "ProductPricing']").find('.cart-item-price').html(fullString);     
    let proRata = jQuery("[name='" + index + "ProductPricing']").closest('.prod-price').find('.prorata-date');
    
    var loader = jQuery("#orderSummaryLoader");
    var loaderMob = jQuery("#orderSummaryLoaderMob");
    var clickedElement = jQuery(element)
    loader.fadeIn('fast');
    loaderMob.fadeIn('fast');

    clickedElement.parent().siblings().each(function(){
        $(this).removeClass('active');
    }) 
    clickedElement.parent().addClass('active');

    WHMCS.http.jqClient.post("cart.php?a=checkout", 'selectProductPeriod=1&pi=' + index + '&pc=' + cycle).promise().done(function(data){
        

        if (data.domains.length > 0){
           
            data.domains.forEach(function(item){
                if (item.type == "register"){
                    let cartDomainSingle = $('[data-domain-price-single="'+item.domain+'"]'),
                        cartDomainMulti = $('[data-domain-price-multi="'+item.domain+'"]'),
                        pricingCount = Object.keys(item.pricing).length;
                    if (pricingCount > 1){
                        if (cartDomainMulti.hasClass('hidden')){
                            let multiPrice = cartDomainMulti.find('[data-domain-price-multi-price]'),
                                dropItems = cartDomainMulti.find('.dropdown-menu li'),
                                renewalPrice = cartDomainMulti.find('.renewal-price');
                            if (dropItems.length == 1){
                                multiPrice.html(item.price + item.shortYearsLanguage);
                                renewalPrice.html(item.renewprice + item.shortRenewalYearsLanguage);
                                let dropdown = cartDomainMulti.find('.dropdown-menu'),
                                    langYear = dropdown.data('domain-lang-year'),
                                    langYears = dropdown.data('domain-lang-years'),
                                    currentYearLang = "";
                                dropdown.empty();
                                Object.entries(item.pricing).forEach(entry => {
                                    const [key, value] = entry;
                                    if (key == 1){
                                        currentYearLang = langYear;
                                    }
                                    else{
                                        currentYearLang = langYears;
                                    }
                                    let listItem = `<li>
                                        <a href="#" onclick="selectDomainPeriodInCart('${item.domain}', '${value.register}', ${key}, '${currentYearLang}');return false;">
                                            ${key} ${currentYearLang} @ ${value.register}
                                        </a>
                                    </li>
                                    `;
                                    dropdown.append(listItem);                           
                                });
                            
                            }

                            cartDomainSingle.addClass('hidden');
                            cartDomainMulti.removeClass('hidden')
                        }
                    }   
                    else{
                        if (cartDomainSingle.hasClass('hidden')){
                            let singlePrice = cartDomainSingle.find('[data-domain-price-single-price]'),
                                renewalPrice = cartDomainSingle.find('.renewal-price');
                            singlePrice.html(item.price + item.shortYearsLanguage)
                            renewalPrice.html(item.renewprice + item.shortRenewalYearsLanguage);

                            cartDomainSingle.removeClass('hidden');
                            cartDomainMulti.addClass('hidden');
                        }
                    } 
                }
            });
        }

        if (data.products.length > 0 && data.products[index].configoptions.length > 0){
            let cfArray = data.products[index].configoptions;
            cfArray.forEach(function callback(value, cfIndex) {
                let cfPrice = $('[data-product-config-option="'+index+'-'+cfIndex+'"]'),
                    cfOption = $('[data-product-config-option-option="'+index+'-'+cfIndex+'"]'),
                    currencyPrefix = cfPrice.data('currency-prefix'),
                    currencySuffix = cfPrice.data('currency-suffix'),
                    fullPrice = value.recurring;

                let cfPriceNumeric = fullPrice.replace(currencyPrefix,"").replace(currencySuffix,"");
                
                if (cfPriceNumeric == "0.00" || cfPriceNumeric == "0,00" && $('[data-zero-value-lang]').length){
                    cfPrice.text($('[data-zero-value-lang]').attr('data-zero-value-lang'));
                } else {
                    if ($('[data-prices-without-suffix]').length){
                        cfPrice.text(fullPrice.replace(currencySuffix, ''));
                    } else {
                        cfPrice.text(fullPrice);
                    }
                }
                if (value.type == "1" || value.type == "2"){
                    cfOption.text(value.optionname);
                } else if (value.type == 4){
                    cfOption.text(value.qty+' x '+value.option);
                }
            });
        }
        if (data.products.length > 0 && data.products[index].addons.length > 0) {
            let addonArray = data.products[index].addons;
            let $panel = $('[data-setup-fee-lang]');
            let setupFeeLang = $panel.attr('data-setup-fee-lang');
            let cycleLangs = {
                monthly: $panel.attr('data-mo-cycle-lang'),
                quarterly: $panel.attr('data-3mo-cycle-lang'),
                semiannually: $panel.attr('data-6mo-cycle-lang'),
                annually: $panel.attr('data-yr-cycle-lang'),
                biennially: $panel.attr('data-2yr-cycle-lang'),
                triennially: $panel.attr('data-3yr-cycle-lang')
            };            
            addonArray.forEach(function callback(addon, addonIndex) {
                let adddonPriceContainer = $('[data-product-addon-price="'+index+'-'+addonIndex+'"]');
                let addonPrice = addon.recurring;
                let addonSetupFee = addon.setup || "";
                let addonCycle = "";
                let displayPrice = addonPrice;

                if($('[data-prices-without-suffix]').length){
                    var currencySuffix = $('[data-prices-without-suffix]').data('prices-without-suffix');
                }
                if (addon.billingcycle && cycleLangs[addon.billingcycle]) {
                    addonCycle = cycleLangs[addon.billingcycle];
                }
                if($('[data-prices-without-suffix]').length){
                    displayPrice = displayPrice.replace(currencySuffix, '');
                }
                if (addonCycle != "") {
                    displayPrice += '/'+ addonCycle;
                }
                if (addonSetupFee != "") {
                    displayPrice += '<span class="setup-fee"> + ' + addonSetupFee + ' ' + setupFeeLang + '</span>';
                }
                adddonPriceContainer.html(displayPrice);
            });
        }

        if(typeof(stripe) !== "undefined") {
            updateStripe();
        }
        jQuery('[data-subtotal] .item-value').html(data.subtotal);
        if (data.promotype) {
            jQuery('#discount').html(data.discount);
        }
        if (data.taxrate) {
            jQuery('#taxTotal1').html(data.taxtotal);
        }
        if (data.taxrate2) {
            jQuery('#taxTotal2').html(data.taxtotal2);
        }

        var recurringSpan = jQuery('#recurring');      
        recurringSpan.find('li').not('.faded').hide();

        if (data.totalrecurringannually) {
            jQuery('#recurringAnnually').show().find('.item-value').html(data.totalrecurringannually);            
        }
        if (data.totalrecurringbiennially) {
            jQuery('#recurringBiennially').show().find('.item-value').html(data.totalrecurringbiennially);            
        }
        if (data.totalrecurringmonthly) {
            jQuery('#recurringMonthly').show().find('.item-value').html(data.totalrecurringmonthly);         
        }
        if (data.totalrecurringquarterly) {
            jQuery('#recurringQuarterly').show().find('.item-value').html(data.totalrecurringquarterly);           
        }
        if (data.totalrecurringsemiannually) {
            jQuery('#recurringSemiAnnually').show().find('.item-value').html(data.totalrecurringsemiannually);           
        }
        if (data.totalrecurringtriennially) {
            jQuery('#recurringTriennially').show().find('.item-value').html(data.totalrecurringtriennially);            
        }
        if (proRata.length && data.products[index]['proratadate']){
            proRata.html(data.products[index]['proratadate']);
        }

        if ($("input[value='producttrialmanager']").is(':checked')){
            data.total = data.total.replace(/[0-9]+[.,]+[0-9]+/, '0.00');
        }

        jQuery('#totalDueToday').html(data.total);    
        
        var promoSubtotal = $('[data-promo-subtotal]');
        if (promoSubtotal.length){
            var promoSubtotalValue = promoSubtotal.data('promo-subtotal');
            var promoTotal = (parseFloat(data.rawdiscount) + parseFloat(data.rawtotal)).toFixed(2);
            if (promoSubtotalValue.includes('0.00')){
                promoSubtotalValue = promoSubtotalValue.replace('0.00', promoTotal);
            } else {
                promoSubtotalValue = promoSubtotalValue.replace('0,00', promoTotal);
            }
            promoSubtotal.html(promoSubtotalValue);
        }

        loader.delay(500).fadeOut('slow');
        loaderMob.delay(500).fadeOut('slow');
    });
}

/*
*******************************************
10. Remove Addon
*******************************************
*/
function removeAddonItem(num, type, addonNum)
{
    let button = jQuery('#modalRemoveAddon').find('[data-remove-addon-confirm]');
    button.attr('data-pid', num);
    button.attr('data-type', type);
    button.attr('data-aid', addonNum);
    jQuery('#modalRemoveAddon').modal('show');
}

function removeAddonConfirm(button){    
    let num = button.data('pid'),
        type = button.data('type'),
        addonNum = button.data('aid');
    
    WHMCS.http.jqClient.post("cart.php?a=checkout", 'removeAddon=1&pi=' + num + '&pt=' + type + '&ai=' + addonNum).promise().done(function(data){
        location.reload(); 
    });
}

/*
*******************************************
11. Check Tos
*******************************************
*/

function checkTos(value){
    $('#accepttos').prop('checked', value);
}

/*
*******************************************
12. Update Stripe
*******************************************
*/

function updateStripe() {
    if(typeof(stripe) !== "undefined") {
        jQuery.post(
            window.location.pathname,
            {
                a: 'checkout',                      //It's like refreshing the page but in the background. Forces the stripe_credit_card_input() function to run.
            }
        ).done(function () {
            jQuery.post(
                window.location.pathname,
                {
                    rsAction: 'getStripeAmount',    //Gets the amount calculated in the stripe_credit_card_input() function.
                }
            ).done(function (data) {
                if(data.amount) {
                    amount = data.amount;
                    //initStripe();                   //Reinitialize Stripe with the new amount
                }
            });
        });
    }
}

/*
*******************************************
13. Update Domain Period
*******************************************
*/

function updateDomainPeriod(domain, period){
    var ajaxUrl = false;
    if ($('#frmDomainChecker').length){
        ajaxUrl = $('#frmDomainChecker').attr('action');
    } 
    else if ($('#frmProductDomain').length){
        ajaxUrl = $('#frmDomainChecker').attr('action');
    }
    else if($('#frmConfigureDomains').length){
        var action = $('#frmConfigureDomains').attr('action');
        var spliturl = action.split('?');
        ajaxUrl = spliturl[0];
    }
    
    var update = jQuery.post(
        ajaxUrl,
        {
            domain: domain,
            period: period,
            a: 'updateDomainPeriod',
            token: csrfToken
        }
    );
    update.done(
        function (data) {
            if ($('#resultDomainPricingTerm').length){
                $('#resultDomainPricingTerm').val(period);
            }
            $('.btn-group-remove').removeClass('loading');
        }
    );
}

/*
*******************************************
14. Add Promo Code
*******************************************
*/

function addPromocode(button){    
    let inputElement = document.getElementById('inputPromotionCode');
    
    if (!inputElement.checkValidity()) {
        setTimeout(function(){
            button.find('.invisible').removeClass('invisible');
            button.find('.loader').addClass('hidden');
        }, 100);
        inputElement.reportValidity();
        return;
    }

    let promocode = $('#inputPromotionCode').val();
    WHMCS.http.jqClient.post("cart.php?a=checkout", 'addPromoCode=1&checkcode=' + promocode).promise().done(function(data){
        var alertSuccess = $('[data-alert-promo-success]');
        var alertRawDiscount = $('[data-alert-promo-rawdiscount]');
        var alertPromoErrorMessage = $('[data-alert-promo-errormessage]');
        var alertPromoRemoved = $('[data-alert-promo-removed]');
        if($('[data-prices-without-suffix]').length){
            var currencySuffix = $('[data-prices-without-suffix]').data('prices-without-suffix');
        }
        alertSuccess.addClass('hidden');
        alertRawDiscount.addClass('hidden');
        alertPromoErrorMessage.addClass('hidden');
        alertPromoRemoved.addClass('hidden');

        var loader = jQuery("#orderSummaryLoader");
        var loaderMob = jQuery("#orderSummaryLoaderMob");
        loader.fadeIn('fast');
        loaderMob.fadeIn('fast');

        if (data.promovalue && data.promomessage == null){
            if(typeof(stripe) !== "undefined") {
                updateStripe();
            }
            if (data.promotype) {
                jQuery('[data-summary-promocode]').show();
                if ($('[data-prices-without-suffix]').length){
                    jQuery('#discount').html('-' + data.discount.replace(currencySuffix, ''));
                } else {
                    jQuery('#discount').html('-' + data.discount);
                }
            }
            if (data.promotiondescription) {
                jQuery('[data-summary-promocode-description]').html(data.promotiondescription);
            }
            if($('[data-prices-without-suffix]').length){
                jQuery('#totalDueToday').html(data.total.replace(currencySuffix, ''));
            } else {
                jQuery('#totalDueToday').html(data.total);
            }

            var promoSubtotal = $('[data-promo-subtotal]');
            if (promoSubtotal.length){
                var promoSubtotalValue = promoSubtotal.data('promo-subtotal');
                var promoTotal = (parseFloat(data.rawdiscount) + parseFloat(data.rawtotal)).toFixed(2);
                if (promoSubtotalValue.includes('0.00')){
                    promoSubtotalValue = promoSubtotalValue.replace('0.00', promoTotal);
                } else {
                    promoSubtotalValue = promoSubtotalValue.replace('0,00', promoTotal);
                }
                if($('[data-prices-without-suffix]').length){
                    promoSubtotal.html(promoSubtotalValue.replace(currencySuffix, ''));
                } else {
                    promoSubtotal.html(promoSubtotalValue);
                }
                promoSubtotal.show();
            }

            $('[data-promotion-box-code]').html(data.promotionCode);
            $('[data-promotion-desc]').html(data.promotiondescription);
            $('[data-promotion-box]').removeClass('hidden');
            $('[data-promotion-box-add]').addClass('hidden');
            jQuery('#totalDueTodayMob').html(data.total);

            if (data.rawdiscount == "0.00"){
                alertRawDiscount.removeClass('hidden');
            } else {
                alertSuccess.removeClass('hidden');
            }

            setTimeout(function(){
                // alertRawDiscount.addClass('hidden'); 
                alertSuccess.addClass('hidden');
            }, 10000);
            
            

        } else if (data.promomessage){

            alertPromoErrorMessage.removeClass('hidden');
            alertPromoErrorMessage.find('.alert-body').html(data.promomessage);
            setTimeout(function(){
                alertPromoErrorMessage.addClass('hidden');
            }, 10000);

        }
        $('#inputPromotionCode').val('');
        button.find('.invisible').removeClass('invisible');
        button.find('.loader').addClass('hidden');
        loader.delay(500).fadeOut('slow');
        loaderMob.delay(500).fadeOut('slow');
    });
}

function removePromocode(button){
    WHMCS.http.jqClient.post("cart.php?a=checkout", 'removePromoCode=1').promise().done(function(data){
        var alertSuccess = $('[data-alert-promo-success]');
        var alertRawDiscount = $('[data-alert-promo-rawdiscount]');
        var alertPromoErrorMessage = $('[data-alert-promo-errormessage]');
        var alertPromoRemoved = $('[data-alert-promo-removed]');
        if($('[data-prices-without-suffix]').length){
            var currencySuffix = $('[data-prices-without-suffix]').data('prices-without-suffix');
        }
        alertSuccess.addClass('hidden');
        alertRawDiscount.addClass('hidden');
        alertPromoErrorMessage.addClass('hidden');


        var loader = jQuery("#orderSummaryLoader");
        var loaderMob = jQuery("#orderSummaryLoaderMob");
        loader.fadeIn('fast');
        loaderMob.fadeIn('fast');

        if(typeof(stripe) !== "undefined") {
            updateStripe();
        }
        if($('[data-prices-without-suffix]').length){
            jQuery('#totalDueToday').html(data.total.replace(currencySuffix, ''));
        } else {
            jQuery('#totalDueToday').html(data.total);
        }

        var promoSubtotal = $('[data-promo-subtotal]');
        if (promoSubtotal.length){
            promoSubtotal.hide();
        }
        jQuery('[data-summary-promocode]').hide();

        $('[data-promotion-box]').addClass('hidden');
        $('[data-promotion-box-add]').removeClass('hidden');
        alertPromoRemoved.removeClass('hidden');

        button.find('.invisible').removeClass('invisible');
        button.find('.loader').addClass('hidden');
        loader.delay(500).fadeOut('slow');
        loaderMob.delay(500).fadeOut('slow');
        
        setTimeout(function(){
            alertPromoRemoved.addClass('hidden');
        }, 10000);
    });
}