(function($) {
    "use strict";
    window.marker_pos = null;
    window.marker_pos_style = null;
    window.map_view = null;
    window.map = null;
    window.vectorLayer = null;
    window.default_style = '';
    window.satellite_style = '';

    $(document).ajaxSend(function () {
        try {
            Pace.start();
        } catch (e) {}
    })
    $(document).ajaxStop(function () {
        try {
            Pace.stop();
        } catch (e) {}
    })

    document.addEventListener("DOMContentLoaded", function () {
        document.querySelectorAll("form[id^='frm']").forEach((form) => {
            const fileInput = form.querySelector("input[type='file']");
            const uploadButton = form.querySelector("input[type='submit']");
            if (!fileInput || !uploadButton) return;
            fileInput.addEventListener("change", function () {
                uploadButton.disabled = !fileInput.files.length;
            });
            form.addEventListener("reset", function () {
                uploadButton.disabled = true;
            });
            uploadButton.disabled = true;
        });
    });

    window.login = function () {
        var username = $('#username_l').val();
        var password = $('#password_l').val();
        var btn_label = $('#btn_login').html();
        $('#btn_login').html('<i class="fas fa-circle-notch fa-spin"></i>');
        $('#btn_login').addClass("disabled");
        var remember_me = $('#remember_l').is(':checked') ? 1 : 0;
        $.ajax({
            url: "ajax/login.php",
            type: "POST",
            data: {
                username_sml: username,
                password_sml: password,
                remember_sml: remember_me,
                autologin: autologin
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if(rsp.status=='ok') {
                    if(window.redirect!=='') {
                        location.href=decodeURI(window.redirect);
                    } else {
                        location.href="index.php";
                    }
                } else if(rsp.status=='missing_email') {
                    $('#btn_login').html(btn_label);
                    $('#btn_login').removeClass("disabled");
                    $('#username_l').removeClass("error-highlight");
                    $('#password_l').removeClass("error-highlight");
                    $('#login_email_required').val('').removeClass("error-highlight");
                    $('#modal_login_email').modal("show");
                } else {
                    $('#username_l').addClass("error-highlight");
                    $('#password_l').addClass("error-highlight");
                    $('#btn_login').html(btn_label);
                    $('#btn_login').removeClass("disabled");
                }
            }
        });
    }

    window.save_login_email = function () {
        var email = $('#login_email_required').val();
        var btn_label = $('#btn_login_email_required').html();
        if(email=='') {
            $('#login_email_required').addClass("error-highlight");
            return;
        }
        $('#login_email_required').removeClass("error-highlight");
        $('#btn_login_email_required').html('<i class="fas fa-circle-notch fa-spin"></i>');
        $('#btn_login_email_required').addClass("disabled");
        $.ajax({
            url: "ajax/login.php",
            type: "POST",
            data: {
                action: 'save_email',
                email: email
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if(rsp.status=='ok') {
                    if(window.redirect!=='') {
                        location.href=decodeURI(window.redirect);
                    } else {
                        location.href="index.php";
                    }
                } else {
                    $('#login_email_required').addClass("error-highlight");
                    $('#btn_login_email_required').html(btn_label);
                    $('#btn_login_email_required').removeClass("disabled");
                }
            },
            error: function () {
                $('#login_email_required').addClass("error-highlight");
                $('#btn_login_email_required').html(btn_label);
                $('#btn_login_email_required').removeClass("disabled");
            }
        });
    }

    window.send_verification_code = function() {
        var email = $('#email_f').val();
        if(email=='') {
            $('#email_f').addClass("error-highlight");
        } else {
            $('#email_f').removeClass("error-highlight");
            $('#btn_forgot_code').addClass('disabled');
            $.ajax({
                url: "ajax/send_email.php",
                type: "POST",
                data: {
                    type: 'forgot',
                    email: email,
                    language: window.language
                },
                timeout: 15000,
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        alert(window.login_labels.check_msg);
                    } else {
                        alert(rsp.msg);
                        $('#btn_forgot_code').removeClass('disabled');
                    }
                },
                error: function(){
                    alert(window.login_labels.error_msg);
                    $('#btn_forgot_code').removeClass('disabled');
                },
            });
        }
    }

    window.change_password_forgot = function() {
        var complete = true;
        var forgot_code = $('#forgot_code').val();
        var password = $('#password_f').val();
        var password2 = $('#repeat_password_f').val();
        if(forgot_code=='') {
            complete = false;
            $('#forgot_code').addClass("error-highlight");
        } else {
            $('#forgot_code').removeClass("error-highlight");
        }
        if(password=='') {
            complete = false;
            $('#password_f').addClass("error-highlight");
        } else {
            $('#password_f').removeClass("error-highlight");
        }
        if(password2=='') {
            complete = false;
            $('#repeat_password_f').addClass("error-highlight");
        } else {
            $('#repeat_password_f').removeClass("error-highlight");
        }
        if((password!='') && (password2!='')) {
            if(password!=password2) {
                complete = false;
                $('#password_f').addClass("error-highlight");
                $('#repeat_password_f').addClass("error-highlight");
            } else {
                $('#password_f').removeClass("error-highlight");
                $('#repeat_password_f').removeClass("error-highlight");
            }
        }
        if(complete) {
            $.ajax({
                url: "ajax/change_password_forgot.php",
                type: "POST",
                data: {
                    forgot_code: forgot_code,
                    password: password,
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        alert(window.login_labels.password_success);
                        location.href = 'login.php';
                    } else {
                        alert(rsp.msg);
                    }
                }
            });
        }
    }

    window.logout = function () {
        $.ajax({
            url: "ajax/logout.php",
            type: "POST",
            async: true,
            success: function (json) {
                location.href="login.php";
            }
        });
    }

    window.get_dashboard_stats = function (id_map) {
        $.ajax({
            url: "ajax/get_dashboard_stats.php",
            type: "POST",
            data: {
                id_user: window.id_user,
                id_map: id_map
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                $('#num_maps').html(rsp.count_maps);
                $('#num_markers').html(rsp.count_markers);
                $('#num_reviews').html(rsp.count_reviews);
                $('#num_markers_to_validate').html(rsp.markers_to_validate);
                $('#num_photos_to_validate').html(rsp.photos_to_validate);
                $('#num_report_issues_to_check').html(rsp.issue_reports_to_check);
                $('#avg_reviews span').html(rsp.avg_reviews);
                var total_visitors = rsp.total_visitors;
                var visitors = rsp.visitors;
                $('#num_visitors').html(rsp.total_visitors);
                var html_visitors = "";
                var d_count = 1;
                var number_of_pages = Math.ceil(rsp.count_maps/10);
                jQuery.each(visitors, function(index, visitor) {
                    var map_id = visitor.id;
                    var m_name = visitor.name;
                    var count = visitor.count;
                    var perc = count / total_visitors * 100;
                    perc = Math.round(perc);
                    var page = Math.ceil(d_count / 10);
                    d_count++;
                    html_visitors += '<div class="d_pages d_page_'+page+'"><h4 style="margin-bottom:1px" class="small font-weight-bold"><a href="index.php?p=statistics&id_map='+map_id+'">'+m_name+'</a> <span class="float-right"><i class="fas fa-chart-line"></i> <b>'+count+'</b></span></h4>\n' +
                        '                <div class="progress mb-2">\n' +
                        '                    <div class="progress-bar bg-primary" role="progressbar" style="width: '+perc+'%" aria-valuenow="'+perc+'" aria-valuemin="0" aria-valuemax="100"></div>\n' +
                        '                </div></div>';
                });
                if(html_visitors!='') {
                    if($('#list_visitors').length) {
                        $('#list_visitors').html(html_visitors).promise().done(function() {
                            $('#list_visitors').twbsPagination({
                                totalPages: number_of_pages,
                                visiblePages: 10,
                                hideOnlyOnePage: true,
                                first: '<<',
                                prev: '<',
                                next: '>',
                                last: '>>',
                                onPageClick: function (event, page) {
                                    $('.d_pages').hide();
                                    $('.d_page_'+page).show();
                                }
                            });
                        });
                    }
                }
            }
        });
    };

    window.get_maps = function (id_category=0) {
        $.ajax({
            url: "ajax/get_maps.php",
            type: "POST",
            data: {
                id_user: window.id_user,
                id_category: id_category
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                parse_map_list(rsp.map_list,rsp.categories,id_category);
            }
        });
    };

    window.persist_search = function (type) {
        sessionStorage.setItem('search_'+type,$('.search_input').val());
    }

    window.clear_search = function (type) {
        sessionStorage.setItem('search_'+type,'');
        $('.search_input').val('');
        $('.search_input').trigger('change');
    }

    window.filter_map = function () {
        var id_category = $('#filter_category option:selected').attr('id');
        if(id_category==0) {
            location.href = 'index.php?p=maps';
        } else {
            location.href = 'index.php?p=maps&cat=' + id_category;
        }
    }

    function parse_map_list(maps,categories,id_category_sel) {
        var html = '';
        var search_val = sessionStorage.getItem('search_map');
        if(search_val==null) search_val='';
        var option_categories = '';
        jQuery.each(categories, function(index, category) {
            var res = category.split("|");
            var id_category = res[0];
            var name_category = res[1];
            if(id_category_sel==id_category) {
                option_categories += "<option selected id='"+id_category+"'>"+name_category+"</option>";
            } else {
                option_categories += "<option id='"+id_category+"'>"+name_category+"</option>";
            }
        });
        if(maps.length>0) {
            html += '<div class="search_map_div card mb-2 pt-3">\n' +
                '<div class="card-body" style="padding-top: 0;padding-bottom: 0;">' +
                '<div class="row">' +
                '<div class="col-lg-6 col-md-6 col-sm-12 col-12">' +
                '   <div class="input-group mb-3">' +
                '       <span class="input-group-prepend">' +
                '           <div class="input-group-text bg-white border-right-0"><i class="fa fa-search"></i></div>' +
                '       </span>' +
                '       <input onkeyup="persist_search(\'map\')" class="search_input form-control py-2" type="text" value="'+search_val+'" placeholder="'+window.backend_labels.search_map+'" autocomplete="new-password" >' +
                '       <span class="input-group-append">' +
                '           <div onclick="clear_search(\'map\');" style="cursor: pointer;" class="input-group-text bg-gray-300 border-left-0"><i class="fa fa-times"></i></div>' +
                '       </span>' +
                '   </div>' +
                '</div>' +
                '<div class="col-lg-3 col-md-4 col-sm-12 col-12 mb-3">' +
                '   <select onchange="filter_map();" id="filter_category" data-live-search="true" class="form-control">' +
                '       <option id="0">'+window.backend_labels.all_categories+'</option>' +
                option_categories +
                '   </select>' +
                '</div>' +
                '</div></div>';
        }
        jQuery.each(maps, function(index, map) {
            var id = map.id;
            var name = map.name;
            var date_created = map.date_created;
            var username = map.username;
            var category = map.category_name;
            var map_style = map.style;
            var background_image = map.background_image;
            var edit_permission = map.edit_permission;
            var publish_permission = map.publish_permission;
            var languages = map.languages;
            var default_language = map.default_language;
            var languages_list = languages.join(' ');
            var count_markers = parseInt(map.count_markers);
            if(count_markers>0) {
                var badge_marker_style = 'badge-secondary';
            } else {
                var badge_marker_style = 'badge-light';
            }
            if (count_markers >= 1000) {
                count_markers = (count_markers / 1000).toFixed(0) + 'k';
            }
            var btn_duplicate = '';
            var btn_delete = '';
            if(window.can_create==1) {
                btn_duplicate = '<a title="'+window.backend_labels.duplicate+'" href="#" onclick="modal_duplicate_map('+id+');return false;" class="btn btn-secondary btn-sm">\n' +
                    '                            <i class="fas fa-copy"></i>\n' +
                    '                        </a>\n';
                btn_delete = '<a title="'+window.backend_labels.delete+'" href="#" onclick="modal_delete_map('+id+');return false;" class="btn btn-danger btn-sm">\n' +
                '                            <i class="fas fa-trash"></i>\n' +
                '                        </a>\n';
            }
            var btn_edit = '';
            var btn_publish = '';
            if(edit_permission) {
                btn_edit = '<a title="'+window.backend_labels.edit+'" href="index.php?p=edit_map&id='+id+'" class="btn btn-warning btn-sm">\n' +
                    '                            <i class="fas fa-edit"></i>\n' +
                    '                        </a>\n';
            }
            if(publish_permission) {
                btn_publish = '<a title="'+window.backend_labels.publish+'" href="index.php?p=publish&id_map='+id+'" class="btn btn-dark btn-sm">\n' +
                    '                            <i class="fas fa-paper-plane"></i>\n' +
                    '                        </a>\n';
            }
            if(background_image!='') {
                var path_image = '../viewer/content/'+background_image;
            } else {
                var path_image = 'img/'+map_style+'.png';
            }
            var cat_html = '';
            if(category!='') {
                cat_html = '&nbsp;&nbsp;<i class="fas fa-th-list"></i> '+category;
            }
            var html_status = '';
            if(parseInt(map.active)==1) {
                html_status = '<i style="color: green" class="fas fa-circle"></i>';
            } else {
                html_status = '<i style="color: red" class="fas fa-circle"></i>';
            }
            var languages_html = "<img class='lang_map_list' src='img/flags_lang/"+default_language+".png?v=3' /> ";
            var count_l = languages.length;
            if(count_l>4) languages = languages.slice(0, 4);
            $.each(languages,function(index_l, lang) {
                languages_html += "<img class='lang_map_list' src='img/flags_lang/"+lang+".png?v=3' /> ";
            });
            if(languages_html!='') {
                languages_html = "&nbsp;&nbsp;"+languages_html;
                var other_l_count = count_l-4;
                if(other_l_count>0) languages_html += " <span style='font-size:10px;'>+"+other_l_count+"</span>";
            }
            html += '<div class="div_map card mb-2 py-2">\n' +
                '            <div class="card-body" style="padding-top: 0;padding-bottom: 0;">\n' +
                '                <div class="row">\n' +
                '                    <div class="map_content col-md-8 text-center text-sm-center text-md-left text-lg-left">\n' +
                '                           <div style="width: 90px;height: 44px;overflow: hidden;border-radius: 6px;position: relative;" class="d-inline-block align-middle">' +
                '                               <img loading="lazy" style="width:100%;height:100%;object-fit:cover;object-position:center center" src="'+path_image+'">' +
                '                           </div>' +
                '                           <div class="vt_info d-inline-block align-middle ml-2 text-left" style="width: auto;">' +
                '                               <b>'+name+'</b><br><span style="font-size:12px">'+html_status+' '+date_created+cat_html+'&nbsp;&nbsp;<i class=\"fas fa-user\"></i> '+username+'</span>' + languages_html +
                '                           </div>' +
                '                    </div>\n' +
                '                    <div class="map_buttons col-md-4 pt-1 text-center text-sm-center text-md-right text-lg-right">\n' + btn_edit +
                '                        <a title="'+window.backend_labels.markers+'" href="index.php?p=markers&id_map='+id+'" class="btn btn-info btn-sm position-relative">\n' +
                '                            <i class="fas fa-map-marker-alt"></i>\n' +
                '                             <span style="top:-8px;right:-5px" class="badge badge-pill '+badge_marker_style+' position-absolute">'+count_markers+'</span>\n' +
                '                        </a>\n' +
                '                        <a title="'+window.backend_labels.preview+'" href="index.php?p=preview&id_map='+id+'" class="btn btn-dark btn-sm position-relative">\n' +
                '                            <i class="fas fa-eye"></i>\n' +
                '                        </a>\n' + btn_publish + btn_duplicate + btn_delete +
                '                    </div>\n' +
                '                </div>\n' +
                '            </div>\n' +
                '        </div>';
        });
        $('#maps_list').html(html).promise().done(function() {
            $('#filter_category').selectpicker();
            $('#maps_list .btn').tooltipster({
                delay: 10,
                hideOnClick: true
            });
            $('#maps_list').searchable({
                selector      : '.div_map',
                childSelector : 'div',
                searchField   : '.search_input',
                searchType    : 'default',
                clearOnLoad   : false
            });
        });
    }

    window.modal_delete_map = function(id) {
        $('#btn_delete_map').attr('onclick','delete_map('+id+');');
        $('#modal_delete_map').modal("show");
    }

    window.delete_map = function (id) {
        $('#modal_delete_map button').addClass("disabled");
        $.ajax({
            url: "ajax/delete_map.php",
            type: "POST",
            data: {
                id_user: window.id_user,
                id_map: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_delete_map button').removeClass("disabled");
                    $('#modal_delete_map').modal("hide");
                    location.reload();
                } else {
                    $('#modal_delete_map button').removeClass("disabled");
                }
            }
        });
    };

    window.modal_duplicate_map = function(id) {
        $('#btn_duplicate_map').attr('onclick','duplicate_map('+id+');');
        $('#modal_duplicate_map').modal("show");
    }

    window.duplicate_map = function (id) {
        $('#modal_duplicate_map button').addClass("disabled");
        $.ajax({
            url: "ajax/duplicate_map.php",
            type: "POST",
            data: {
                id_user: window.id_user,
                id_map: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_duplicate_map button').removeClass("disabled");
                    $('#modal_duplicate_map').modal("hide");
                    location.reload();
                } else {
                    $('#modal_duplicate_map button').removeClass("disabled");
                }
            }
        });
    };

    window.modal_delete_marker = function(id) {
        $('#btn_delete_marker').attr('onclick','delete_marker('+id+');');
        $('#modal_delete_marker').modal("show");
    }

    window.modal_clone_marker = function(id) {
        $('#btn_clone_marker').attr('onclick','clone_marker('+id+');');
        $('#modal_clone_marker').modal("show");
    }

    window.clone_marker = function (id) {
        $('#modal_clone_marker button').addClass("disabled");
        var duplicate_target_map = $('#duplicate_target_map option:selected').attr('id');
        $.ajax({
            url: "ajax/duplicate_marker.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                duplicate_target_map: duplicate_target_map,
                id_marker: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_clone_marker button').removeClass("disabled");
                    $('#modal_clone_marker').modal("hide");
                    location.href = 'index.php?p=markers';
                } else {
                    $('#modal_clone_marker button').removeClass("disabled");
                }
            }
        });
    }

    window.delete_marker = function (id) {
        $('#modal_delete_marker button').addClass("disabled");
        $.ajax({
            url: "ajax/delete_marker.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id_marker: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_delete_marker button').removeClass("disabled");
                    $('#modal_delete_marker').modal("hide");
                    location.href = 'index.php?p=markers';
                } else {
                    $('#modal_delete_marker button').removeClass("disabled");
                }
            }
        });
    };

    window.modal_delete_category = function(id) {
        $('#btn_delete_category').attr('onclick','delete_category('+id+');');
        $('#modal_delete_category').modal("show");
    }

    window.delete_category = function (id) {
        $('#modal_delete_category button').addClass("disabled");
        $.ajax({
            url: "ajax/delete_category.php",
            type: "POST",
            data: {
                id_category: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_delete_category button').removeClass("disabled");
                    $('#modal_delete_category').modal("hide");
                    location.href = 'index.php?p=categories';
                } else {
                    $('#modal_delete_category button').removeClass("disabled");
                }
            }
        });
    };

    window.modal_delete_user = function(id) {
        $('#btn_delete_user').attr('onclick','delete_user('+id+');');
        $('#modal_delete_user').modal("show");
    }

    window.delete_user = function (id) {
        $('#modal_delete_user button').addClass("disabled");
        $.ajax({
            url: "ajax/delete_user.php",
            type: "POST",
            data: {
                id_user: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_delete_user button').removeClass("disabled");
                    $('#modal_delete_user').modal("hide");
                    location.href = 'index.php?p=users';
                } else {
                    $('#modal_delete_user button').removeClass("disabled");
                }
            }
        });
    };

    window.add_map = function () {
        var complete = true;
        var name = $('#name').val();
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        if(complete) {
            $('#modal_new_map button').addClass("disabled");
            $.ajax({
                url: "ajax/add_map.php",
                type: "POST",
                data: {
                    id_user: window.id_user,
                    name: name
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#modal_new_map button').removeClass("disabled");
                        $('#modal_new_map').modal("hide");
                        location.reload();
                    } else {
                        $('#modal_new_map button').removeClass("disabled");
                    }
                }
            });
        }
    };

    window.set_session_m = function (id) {
        $.ajax({
            url: "ajax/set_session_m.php",
            type: "POST",
            data: {
                id_map: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    location.reload();
                }
            }
        });
    }

    window.preview = function(id,container_h) {
        $.ajax({
            url: "ajax/get_code.php",
            type: "POST",
            data: {
                id_map: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var code = rsp.code;
                if(code!="") {
                    $('#iframe_div').show();
                    $("#iframe_div").html("<iframe allow='accelerometer; camera; display-capture; fullscreen; geolocation; gyroscope; magnetometer; microphone; midi; xr-spatial-tracking;' " +
                        "width=\"100%\" height=\""+container_h+"px\" frameborder=\"0\" scrolling=\"no\" " +
                        "marginheight=\"0\" marginwidth=\"0\" " +
                        "src=\"../viewer/index.php?code="+code+"&ignore_embedded=1&isAdmin=1&hash="+window.hash+"\"" +
                        "></iframe>");
                }
            }
        });
    }

    window.save_map = function(reload = false) {
        var complete = true;
        var array_lang = {};
        var name = $('#name').val();
        array_lang['name'] = {};
        $('.input_lang[data-target-id="name"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['name'][lang]=value;
        });
        var id_user = $('#user option:selected').attr('id');
        var maptiler_api = $('#maptiler_api').val();
        var maptiler_api_satellite = $('#maptiler_api_satellite').val();
        var here_api = $('#here_api').val();
        var here_api_satellite = $('#here_api_satellite').val();
        var here_lang = $('#here_lang').val();
        var here_lang_satellite = $('#here_lang_satellite').val();
        var google_api = $('#google_api').val();
        var google_api_satellite = $('#google_api_satellite').val();
        var google_lang = $('#google_lang').val();
        var google_lang_satellite = $('#google_lang_satellite').val();
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        var main_color_hex = window.main_color_hex_spectrum.spectrum('get').toHexString();
        var street_basemap = $('#street_basemap').val();
        var satellite_basemap = $('#satellite_basemap').val();
        var openfreemap_street_url = $('#openfreemap_street_url').val();
        switch(window.map_style_sel) {
            case 'default':
                var map_style = $('.map_style img.style-highlight').parent().attr('id');
                var map_street_provider = 'default';
                break;
            case 'maptiler':
                if(maptiler_api=='') {
                    var map_style = 'osm_free';
                    var map_street_provider = 'default';
                } else {
                    var map_style = $('.map_style img.style-highlight').parent().attr('id');
                    var map_street_provider = 'maptiler';
                }
                break;
            case 'here':
                if(here_api=='') {
                    var map_style = 'osm_free';
                    var map_street_provider = 'default';
                } else {
                    var map_style = $('.map_style img.style-highlight').parent().attr('id');
                    var map_street_provider = 'here';
                }
                break;
            case 'google':
                if(google_api=='') {
                    var map_style = 'osm_free';
                    var map_street_provider = 'default';
                } else {
                    var map_style = $('.map_style img.style-highlight').parent().attr('id');
                    var map_street_provider = 'google';
                }
                break;
            case 'openfreemap':
                var map_style = $('.map_style img.style-highlight').parent().attr('id');
                var map_street_provider = 'openfreemap';
                break;
            case 'carto':
                var map_style = $('.map_style img.style-highlight').parent().attr('id');
                var map_street_provider = 'carto';
                break;
            case 'stadia':
                var map_style = $('.map_style img.style-highlight').parent().attr('id');
                var map_street_provider = 'stadia';
                break;
            case 'custom':
                if(street_basemap=='') {
                    var map_style = 'osm_free';
                    var map_street_provider = 'default';
                } else {
                    var map_style = 'custom';
                    var map_street_provider = 'custom';
                }
                break;
        }
        switch(window.map_style_satellite_sel) {
            case 'default':
                var map_style_satellite = $('.map_style_satellite img.style-highlight').parent().attr('id');
                var map_satellite_provider = 'default';
                break;
            case 'maptiler':
                if(maptiler_api_satellite=='') {
                    var map_style_satellite = 'arcgis';
                    var map_satellite_provider = 'default';
                } else {
                    var map_style_satellite = $('.map_style_satellite img.style-highlight').parent().attr('id');
                    var map_satellite_provider = 'maptiler';
                }
                break;
            case 'here':
                if(here_api_satellite=='') {
                    var map_style_satellite = 'arcgis';
                    var map_satellite_provider = 'default';
                } else {
                    var map_style_satellite = $('.map_style_satellite img.style-highlight').parent().attr('id');
                    var map_satellite_provider = 'here';
                }
                break;
            case 'google':
                if(google_api_satellite=='') {
                    var map_style_satellite = 'arcgis';
                    var map_satellite_provider = 'default';
                } else {
                    var map_style_satellite = $('.map_style_satellite img.style-highlight').parent().attr('id');
                    var map_satellite_provider = 'google';
                }
                break;
            case 'custom':
                if(satellite_basemap=='') {
                    var map_style_satellite = 'arcgis';
                    var map_satellite_provider = 'default';
                } else {
                    var map_style_satellite = 'custom';
                    var map_satellite_provider = 'custom';
                }
                break;
        }
        var map_type = $('#map_type option:selected').attr('id');
        var quality_preset = $('#quality_preset').val();
        var quality_resolution = $('#quality_resolution').val();
        var update_while_animating = ($('#update_while_animating').is(':checked')) ? 1 : 0;
        var update_while_interacting = ($('#update_while_interacting').is(':checked')) ? 1 : 0;
        var load_tiles_while_animating = ($('#load_tiles_while_animating').is(':checked')) ? 1 : 0;
        var load_tiles_while_interacting = ($('#load_tiles_while_interacting').is(':checked')) ? 1 : 0;
        var preload_tiles = parseInt($('#preload_tiles').val());
        var render_buffer = parseInt($('#render_buffer').val());
        var ga_tracking_id = $('#ga_tracking_id').val();
        var show_list = $('#show_list option:selected').attr('id');
        var limit_list = $('#limit_list').val();
        var enable_reviews = ($('#enable_reviews').is(':checked')) ? 1 : 0;
        var enable_add_photo = ($('#enable_add_photo').is(':checked')) ? 1 : 0;
        var viewer_auth_mode = parseInt($('#viewer_auth_mode option:selected').attr('id'));
        var add_marker_require_login = ($('#add_marker_require_login').is(':checked')) ? 1 : 0;
        var review_require_login = ($('#review_require_login').is(':checked')) ? 1 : 0;
        var add_photo_require_login = ($('#add_photo_require_login').is(':checked')) ? 1 : 0;
        var issue_report_require_login = ($('#issue_report_require_login').is(':checked')) ? 1 : 0;
        var live_tracking_require_login = ($('#live_tracking_require_login').is(':checked')) ? 1 : 0;
        var density_color = ($('#density_color').is(':checked')) ? 1 : 0;
        var enable_directions = ($('#enable_directions').is(':checked')) ? 1 : 0;
        var enable_popup_directions = ($('#enable_popup_directions').is(':checked')) ? 1 : 0;
        var enable_add_marker = parseInt($('#enable_add_marker option:selected').attr('id'));
        var enable_streetview = ($('#enable_streetview').is(':checked')) ? 1 : 0;
        var enable_share = ($('#enable_share').is(':checked')) ? 1 : 0;
        var enable_share_map = ($('#enable_share_map').is(':checked')) ? 1 : 0;
        var enable_last_update = ($('#enable_last_update').is(':checked')) ? 1 : 0;
        var default_zoom = $('#default_zoom option:selected').attr('id');
        var selected_zoom = $('#selected_zoom option:selected').attr('id');
        var duration_zoom = $('#duration_zoom').val();
        var search_highlight = $('#search_highlight option:selected').attr('id');
        var language = $('#language option:selected').attr('id');
        var languages_enabled_t = $('#languages_enabled option');
        var languages_enabled = {};
        var count_lang_enabled = 1;
        $(languages_enabled_t).each(function(index, elem){
            var id = $(this).attr('id').replace('ls_','');
            if($(this).is(':selected')) {
                languages_enabled[id]=1;
                if(id!=window.default_language) {
                    count_lang_enabled++;
                }
            } else {
                languages_enabled[id]=0;
            }
        });
        var languages_enabled_json = JSON.stringify(languages_enabled);
        var street_maxzoom = $('#street_maxzoom').val();
        var street_minzoom = $('#street_minzoom').val();
        var satellite_maxzoom = $('#satellite_maxzoom').val();
        var satellite_minzoom = $('#satellite_minzoom').val();
        var cluster_distance = $('#cluster_distance').val();
        var cluster_animation = $('#cluster_animation').val();
        var density_color_tolerance = $('#density_color_tolerance').val();
        var cat_filter = $('#cat_filter option:selected').attr('id');
        var nav_markers = ($('#nav_markers').is(':checked')) ? 1 : 0;
        if(window.font_provider=='systems') {
            var font_viewer = $('#font_viewer_system option:selected').attr('id');
        } else {
            var font_viewer = $('#font_viewer').val();
        }
        var sheet_detail = ($('#sheet_detail').is(':checked')) ? 1 : 0;
        var default_view = $('#default_view option:selected').attr('id');
        var order_by = $('#order_by option:selected').attr('id');
        var default_my_location = $('#default_my_location option:selected').attr('id');
        var my_location_zoom = $('#my_location_zoom option:selected').attr('id');
        var enable_search = ($('#enable_search').is(':checked')) ? 1 : 0;
        var enable_search_location = ($('#enable_search_location').is(':checked')) ? 1 : 0;
        var enable_list = ($('#enable_list').is(':checked')) ? 1 : 0;
        var enable_categories = $('#enable_categories option:selected').attr('id');
        var fit_categories = ($('#fit_categories').is(':checked')) ? 1 : 0;
        var enable_story = ($('#enable_story').is(':checked')) ? 1 : 0;
        var enable_popup = ($('#enable_popup').is(':checked')) ? 1 : 0;
        if(enable_popup) enable_popup=1; else enable_popup=0;
        var street_attributions = $('#street_attributions').val();
        var use_street_attributions = ($('#use_street_attributions').is(':checked')) ? 1 : 0;
        var enable_map_street = ($('#enable_map_street').is(':checked')) ? 1 : 0;
        var satellite_attributions = $('#satellite_attributions').val();
        var use_satellite_attributions = ($('#use_satellite_attributions').is(':checked')) ? 1 : 0;
        var enable_map_satellite = ($('#enable_map_satellite').is(':checked')) ? 1 : 0;
        var markers_size = $('#markers_size').val();
        var color_hex = $('#color_hex').val();
        var icon_color_hex = $('#icon_color_hex').val();
        var icon = $('#marker_icon_input').val();
        var unicode = window.getComputedStyle(document.getElementById("marker_icon"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
        if(unicode=='6e')  {
            icon='';
        } else {
            icon = icon + '|' + unicode;
        }
        var id_icon_library = $('#marker_library_icon').val();
        var icon_type = parseInt($('#icon_type option:selected').attr('id'));
        switch (icon_type) {
            case 0:
                icon = '';
                id_icon_library = 0;
                break;
            case 1:
                id_icon_library = 0;
                break;
            case 2:
                icon = '';
                break;
        }
        var color_hex_hover = $('#color_hex_hover').val();
        var icon_color_hex_hover = $('#icon_color_hex_hover').val();
        var weather = $('#weather option:selected').attr('id');
        var cat_filter_type = $('#cat_filter_type option:selected').attr('id');
        var no_category_sel_mode = $('#no_category_sel_mode option:selected').attr('id');
        var category_featured_mode = $('#category_featured_mode option:selected').attr('id');
        var enable_globe = $('#enable_globe option:selected').attr('id');
        var sheet_mobile = $('#sheet_mobile option:selected').attr('id');
        var direction_map = $('#direction_map option:selected').attr('id');
        var streetview_map = $('#streetview_map option:selected').attr('id');
        var logo_height = $('#logo_height').val();
        var logo_height_mobile = $('#logo_height_mobile').val();
        var logo_link = $('#logo_link').val();
        var pin_marker_size = $('#pin_marker_size').val();
        var pin_color_hex = $('#pin_color_hex').val();
        var pin_icon_color_hex = $('#pin_icon_color_hex').val();
        var pin_icon = $('#marker_icon_input_pin').val();
        var pin_unicode = window.getComputedStyle(document.getElementById("marker_icon_pin"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
        if(pin_unicode=='6e')  {
            pin_icon='';
        } else {
            pin_icon = pin_icon + '|' + pin_unicode;
        }
        var pin_id_icon_library = $('#marker_library_icon_pin').val();
        var pin_icon_type = parseInt($('#pin_icon_type option:selected').attr('id'));
        switch (pin_icon_type) {
            case 0:
                pin_icon = '';
                pin_id_icon_library = 0;
                break;
            case 1:
                pin_id_icon_library = 0;
                break;
            case 2:
                pin_icon = '';
                break;
        }
        var pin_marker_enable = ($('#pin_marker_enable').is(':checked')) ? 1 : 0;
        var pin_marker_align = $('#pin_marker_align option:selected').attr('id');
        var auto_start = $('#auto_start option:selected').attr('id');
        var loading_visible = ($('#loading_visible').is(':checked')) ? 1 : 0;
        var lazy_loading = parseInt($('#lazy_loading option:selected').attr('id'));
        var lazy_loading_max_markers = parseInt($('#lazy_loading_max_markers').val());
        if(isNaN(lazy_loading) || lazy_loading<0 || lazy_loading>2) lazy_loading=0;
        if(isNaN(lazy_loading_max_markers) || lazy_loading_max_markers<1) lazy_loading_max_markers=3000;
        if(lazy_loading_max_markers>50000) lazy_loading_max_markers=50000;
        var loading_background_color = $('#loading_background_color').val();
        var loading_text_color = $('#loading_text_color').val();
        var search_radius_enabled = ($('#search_radius_enabled').is(':checked')) ? 1 : 0;
        var search_radius_m = parseInt($('#search_radius_m').val());
        if(search_radius_m==0) search_radius_m=-1;
        var default_extra_fields = {};
        for(var i=1;i<=20;i++) {
            var icon_e = $('#marker_icon_input_e'+i).val();
            default_extra_fields[i]=icon_e;
        }
        default_extra_fields = JSON.stringify(default_extra_fields);
        var default_am_fields = {};
        default_am_fields['street']=($('#am_street').is(':checked')) ? 1 : 0;
        default_am_fields['city']=($('#am_city').is(':checked')) ? 1 : 0;
        default_am_fields['state']=($('#am_state').is(':checked')) ? 1 : 0;
        default_am_fields['postal_code']=($('#am_postal_code').is(':checked')) ? 1 : 0;
        default_am_fields['county']=($('#am_county').is(':checked')) ? 1 : 0;
        default_am_fields['country']=($('#am_country').is(':checked')) ? 1 : 0;
        default_am_fields['categories']=($('#am_categories').is(':checked')) ? 1 : 0;
        default_am_fields['website']=($('#am_website').is(':checked')) ? 1 : 0;
        default_am_fields['email']=($('#am_email').is(':checked')) ? 1 : 0;
        default_am_fields['phone']=($('#am_phone').is(':checked')) ? 1 : 0;
        default_am_fields['whatsapp']=($('#am_whatsapp').is(':checked')) ? 1 : 0;
        default_am_fields['description']=($('#am_description').is(':checked')) ? 1 : 0;
        default_am_fields['hours']=($('#am_hours').is(':checked')) ? 1 : 0;
        default_am_fields['images']=($('#am_images').is(':checked')) ? 1 : 0;
        for(var i=1;i<=20;i++) {
            default_am_fields['field_'+i]=($('#am_field_'+i).is(':checked')) ? 1 : 0;
        }
        default_am_fields = JSON.stringify(default_am_fields);
        var default_am_placeholders = {};
        for(var i=1;i<=20;i++) {
            default_am_placeholders[i]=$('#am_placeholder_'+i).val();
        }
        default_am_placeholders = JSON.stringify(default_am_placeholders);
        array_lang['default_am_placeholders'] = {};
        for (var i = 1; i <= 20; i++) {
            $('.input_lang[data-target-id="am_placeholder_' + i + '"]').each(function() {
                var lang = $(this).attr('data-lang');
                var value = $(this).val();
                if (!array_lang['default_am_placeholders'][lang]) {
                    array_lang['default_am_placeholders'][lang] = {};
                }
                array_lang['default_am_placeholders'][lang][i] = value;
            });
        }
        for (var lang in array_lang['default_am_placeholders']) {
            array_lang['default_am_placeholders'][lang] = JSON.stringify(array_lang['default_am_placeholders'][lang]);
        }
        var share_providers_t = $('#share_providers option');
        var share_providers = '';
        $(share_providers_t).each(function(index, elem){
            var id = $(this).attr('id');
            if(id !== undefined) {
                id = id.replace('provider_','');
                if($(this).is(':selected')) {
                    share_providers = share_providers+id+',';
                }
            }
        });
        if(share_providers!='') {
            share_providers = share_providers.substring(0,share_providers.length-1);
        }
        var enable_intro = ($('#enable_intro').is(':checked')) ? 1 : 0;
        var intro_only_direct = ($('#intro_only_direct').is(':checked')) ? 1 : 0;
        var intro_params = {
            background: $('#intro_background').val(),
            title: $('#intro_title').val().replace(/"/g, "'"),
            title_size: $('#intro_title_size').val(),
            title_color: $('#intro_title_color').val(),
            description: $('#intro_description').val().replace(/"/g, "'"),
            description_size: $('#intro_description_size').val(),
            description_color: $('#intro_description_color').val(),
            image_height: $('#intro_image_height').val(),
            button: $('#intro_button').val().replace(/"/g, "'"),
            button_size: $('#intro_button_size').val(),
            button_background: $('#intro_button_background').val(),
            button_color: $('#intro_button_color').val()
        };
        var intro_params_lang = { ...intro_params };
        array_lang['intro_params'] = {};
        $('.input_lang[data-target-id="intro_title"]').each(function() {
            var lang = $(this).attr('data-lang');
            intro_params_lang.title = $(this).val();
            intro_params_lang.description = $('.input_lang[data-target-id="intro_description"][data-lang="'+lang+'"]').val();
            intro_params_lang.button = $('.input_lang[data-target-id="intro_button"][data-lang="'+lang+'"]').val();
            array_lang['intro_params'][lang] = JSON.stringify(intro_params_lang);
        });
        intro_params = JSON.stringify(intro_params);
        var cookie_consent = ($('#cookie_consent').is(':checked')) ? 1 : 0;
        var show_legal = ($('#show_legal').is(':checked')) ? 1 : 0;
        var unit_map = $('#unit_map option:selected').attr('id');
        var marker_images_num = $('#marker_images_num').val();
        var marker_images_compression = $('#marker_images_compression').val();
        var marker_images_max_size = $('#marker_images_max_size').val();
        var my_location_mode = $('#my_location_mode option:selected').attr('id');
        var street_basemap_overlay = $('#street_basemap_overlay').val();
        var street_overlay_opacity = $('#street_overlay_opacity').val();
        var satellite_basemap_overlay = $('#satellite_basemap_overlay').val();
        var satellite_overlay_opacity = $('#satellite_overlay_opacity').val();
        var info_enable = ($('#info_enable').is(':checked')) ? 1 : 0;
        var info_auto_open = $('#info_auto_open option:selected').attr('id');
        var info_icon = $('#info_icon_input').val();
        var unicode_info = window.getComputedStyle(document.getElementById("info_icon"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
        if(unicode_info=='6e')  {
            info_icon='';
        } else {
            info_icon = info_icon + '|' + unicode_info;
        }
        var info_content = $('#info_content').summernote('code');
        array_lang['info_content'] = {};
        $('.input_lang[data-target-id="info_content"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).summernote('code');
            array_lang['info_content'][lang]=value;
        });
        var song_link = $('#song_link').val();
        var song_bg_volume = $('#song_bg_volume').val();
        var tts_enable = ($('#tts_enable').is(':checked')) ? 1 : 0;
        var live_tracking = $('#live_tracking option:selected').attr('id');
        var live_tracking_interval = $('#live_tracking_interval').val();
        var live_tracking_timeout = $('#live_tracking_timeout').val();
        var live_tracking_only_admin = ($('#live_tracking_only_admin').is(':checked')) ? 1 : 0;
        var song_autoplay = $('#song_autoplay option:selected').attr('id');
        var song_loop = ($('#song_loop').is(':checked')) ? 1 : 0;
        var custom_html = window.custom_html.getValue();
        var marker_sel_zoom = $('#marker_sel_zoom option:selected').attr('id');
        var pwa_enable = ($('#pwa_enable').is(':checked')) ? 1 : 0;
        var include_sitemap = ($('#include_sitemap').is(':checked')) ? 1 : 0;
        var show_categories_marker = $('#show_categories_marker option:selected').attr('id');
        var order_by_distance = ($('#order_by_distance').is(':checked')) ? 1 : 0;
        var enable_issue_reports = ($('#enable_issue_reports').is(':checked')) ? 1 : 0;
        var show_scale_control = ($('#show_scale_control').is(':checked')) ? 1 : 0;
        var enable_measure = ($('#enable_measure').is(':checked')) ? 1 : 0;
        var default_prefix = $('#default_prefix option:selected').attr('id');
        var id_categories = [];
        $("#category option:selected").each(function () {
            id_categories.push(parseInt($(this).attr('id')));
        });
        var add_marker_fields_mandatory_t = $('#add_marker_fields_mandatory option');
        var add_marker_fields_mandatory = "";
        $(add_marker_fields_mandatory_t).each(function(index, elem){
            var val = $(this).val();
            if($(this).is(':selected') && !$(this).is(':disabled')) {
                add_marker_fields_mandatory=add_marker_fields_mandatory+val+',';
            }
        });
        if(add_marker_fields_mandatory!='') {
            add_marker_fields_mandatory = add_marker_fields_mandatory.substring(0,add_marker_fields_mandatory.length-1);
        }
        var add_marker_multiple_category = ($('#add_marker_multiple_category').is(':checked')) ? 1 : 0;
        var address_format_data = $("#address-sorter li").map(function() {
            var $li = $(this);
            return {
                field: $li.data("field"),
                enabled: $li.find("input[type='checkbox']").is(":checked")
            };
        }).get();
        var all_disabled = address_format_data.every(function(item) {
            return !item.enabled;
        });
        if (all_disabled) {
            address_format_data.forEach(function(item) {
                item.enabled = true;
            });
        }
        var address_format_json = JSON.stringify(address_format_data);
        var add_markers_countries_allowed = $('#add_markers_countries_allowed').val();
        if (!add_markers_countries_allowed) {
            add_markers_countries_allowed = [];
        }
        var add_markers_countries_allowed_json = JSON.stringify(add_markers_countries_allowed);
        var wake_lock = $('#wake_lock option:selected').attr('id');
        if(complete) {
            var array_lang_json = JSON.stringify(array_lang);
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            $('#modal_change_languages button').addClass('disabled');
            $.ajax({
                url: "ajax/save_map.php",
                type: "POST",
                data: {
                    id_map: id_map,
                    id_user: id_user,
                    name: name,
                    main_color_hex: main_color_hex,
                    markers_size: markers_size,
                    markers_color_hex: color_hex,
                    markers_icon_color_hex: icon_color_hex,
                    markers_color_hex_hover: color_hex_hover,
                    markers_icon_color_hex_hover: icon_color_hex_hover,
                    markers_icon: icon,
                    markers_id_icon_library: id_icon_library,
                    map_style: map_style.replaceAll('_p_','.'),
                    map_style_satellite: map_style_satellite.replaceAll('_p_','.'),
                    map_type: map_type,
                    quality_preset: quality_preset,
                    quality_resolution: quality_resolution,
                    update_while_animating: update_while_animating,
                    update_while_interacting: update_while_interacting,
                    load_tiles_while_animating: load_tiles_while_animating,
                    load_tiles_while_interacting: load_tiles_while_interacting,
                    preload_tiles: preload_tiles,
                    render_buffer: render_buffer,
                    maptiler_api: maptiler_api,
                    maptiler_api_satellite: maptiler_api_satellite,
                    logo: window.logo,
                    logo_mobile: window.logo_mobile,
                    ga_tracking_id: ga_tracking_id,
                    show_list: show_list,
                    limit_list: limit_list,
                    default_zoom: default_zoom,
                    selected_zoom: selected_zoom,
                    duration_zoom: duration_zoom,
                    search_highlight: search_highlight,
                    density_color: density_color,
                    density_color_tolerance: density_color_tolerance,
                    enable_reviews: enable_reviews,
                    enable_add_photo: enable_add_photo,
                    viewer_auth_mode: viewer_auth_mode,
                    add_marker_require_login: add_marker_require_login,
                    review_require_login: review_require_login,
                    add_photo_require_login: add_photo_require_login,
                    issue_report_require_login: issue_report_require_login,
                    live_tracking_require_login: live_tracking_require_login,
                    enable_directions: enable_directions,
                    enable_popup_directions: enable_popup_directions,
                    enable_streetview: enable_streetview,
                    enable_share: enable_share,
                    language: language,
                    languages_enabled: languages_enabled_json,
                    url_street: street_basemap,
                    url_sat: satellite_basemap,
                    street_maxzoom: street_maxzoom,
                    street_minzoom: street_minzoom,
                    satellite_maxzoom: satellite_maxzoom,
                    satellite_minzoom: satellite_minzoom,
                    street_attributions: street_attributions,
                    satellite_attributions: satellite_attributions,
                    cluster_distance: cluster_distance,
                    cluster_animation: cluster_animation,
                    cat_filter: cat_filter,
                    nav_markers: nav_markers,
                    enable_add_marker: enable_add_marker,
                    font_viewer: font_viewer,
                    sheet_detail: sheet_detail,
                    default_view: default_view,
                    order_by: order_by,
                    default_my_location: default_my_location,
                    my_location_zoom: my_location_zoom,
                    enable_search: enable_search,
                    enable_search_location: enable_search_location,
                    enable_list: enable_list,
                    enable_categories: enable_categories,
                    fit_categories: fit_categories,
                    enable_story: enable_story,
                    weather: weather,
                    cat_filter_type: cat_filter_type,
                    no_category_sel_mode: no_category_sel_mode,
                    category_featured_mode: category_featured_mode,
                    enable_globe: enable_globe,
                    enable_popup: enable_popup,
                    sheet_mobile: sheet_mobile,
                    logo_height: logo_height,
                    logo_height_mobile: logo_height_mobile,
                    logo_link: logo_link,
                    pin_marker_size: pin_marker_size,
                    pin_color_hex: pin_color_hex,
                    pin_icon_color_hex: pin_icon_color_hex,
                    pin_icon: pin_icon,
                    pin_id_icon_library: pin_id_icon_library,
                    pin_marker_align: pin_marker_align,
                    pin_marker_enable: pin_marker_enable,
                    direction_map: direction_map,
                    streetview_map: streetview_map,
                    auto_start: auto_start,
                    loading_visible: loading_visible,
                    lazy_loading: lazy_loading,
                    lazy_loading_max_markers: lazy_loading_max_markers,
                    loading_background_color: loading_background_color,
                    loading_text_color: loading_text_color,
                    background_image: window.background_image,
                    background_image_mobile: window.background_image_mobile,
                    search_radius_enabled: search_radius_enabled,
                    search_radius_m: search_radius_m,
                    default_extra_fields: default_extra_fields,
                    default_am_fields: default_am_fields,
                    default_am_placeholders: default_am_placeholders,
                    share_providers: share_providers,
                    enable_share_map: enable_share_map,
                    enable_last_update: enable_last_update,
                    use_street_attributions: use_street_attributions,
                    use_satellite_attributions: use_satellite_attributions,
                    enable_map_street: enable_map_street,
                    enable_map_satellite: enable_map_satellite,
                    map_street_provider: map_street_provider,
                    map_satellite_provider: map_satellite_provider,
                    here_api: here_api,
                    here_api_satellite: here_api_satellite,
                    here_lang: here_lang,
                    here_lang_satellite: here_lang_satellite,
                    google_api: google_api,
                    google_api_satellite: google_api_satellite,
                    google_lang: google_lang,
                    google_lang_satellite: google_lang_satellite,
                    enable_intro: enable_intro,
                    intro_only_direct: intro_only_direct,
                    intro_image: window.intro_image,
                    intro_params: intro_params,
                    cookie_consent: cookie_consent,
                    show_legal: show_legal,
                    unit_map: unit_map,
                    marker_images_num: marker_images_num,
                    marker_images_compression: marker_images_compression,
                    marker_images_max_size: marker_images_max_size,
                    my_location_mode: my_location_mode,
                    street_basemap_overlay: street_basemap_overlay,
                    street_overlay_opacity: street_overlay_opacity,
                    satellite_basemap_overlay: satellite_basemap_overlay,
                    satellite_overlay_opacity: satellite_overlay_opacity,
                    info_enable: info_enable,
                    info_auto_open: info_auto_open,
                    info_icon: info_icon,
                    info_content: info_content,
                    song: window.song,
                    song_link: song_link,
                    song_bg_volume: song_bg_volume,
                    song_autoplay: song_autoplay,
                    song_loop: song_loop,
                    tts_enable: tts_enable,
                    live_tracking: live_tracking,
                    live_tracking_interval: live_tracking_interval,
                    live_tracking_timeout: live_tracking_timeout,
                    live_tracking_only_admin: live_tracking_only_admin,
                    custom_html: custom_html,
                    marker_sel_zoom: marker_sel_zoom,
                    pwa_enable: pwa_enable,
                    include_sitemap: include_sitemap,
                    show_categories_marker: show_categories_marker,
                    id_categories: id_categories,
                    openfreemap_street_url: openfreemap_street_url,
                    order_by_distance: order_by_distance,
                    add_marker_fields_mandatory: add_marker_fields_mandatory,
                    add_marker_multiple_category: add_marker_multiple_category,
                    enable_issue_reports: enable_issue_reports,
                    default_prefix: default_prefix,
                    address_format: address_format_json,
                    add_markers_countries_allowed: add_markers_countries_allowed_json,
                    show_scale_control: show_scale_control,
                    enable_measure: enable_measure,
                    wake_lock: wake_lock,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        if(rsp.favicon!=1) {
                            generate_favicons(rsp.favicon);
                        }
                        window.map_need_save = false;
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                        if(reload) {
                            $('#modal_change_languages').modal('hide');
                            $('#modal_change_languages button').removeClass('disabled');
                            location.reload();
                        } else {
                            $('#modal_change_languages button').removeClass('disabled');
                        }
                    } else {
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                        $('#modal_change_languages button').removeClass('disabled');
                    }
                }, error: function() {
                    $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                    $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                    setTimeout(function () {
                        $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                        $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                        $('#save_btn').removeClass("disabled");
                    },1000);
                    $('#modal_change_languages button').removeClass('disabled');
                }
            });
        }
    }

    window.delete_logo = function () {
        window.logo = '';
        window.map_need_save = true;
        $('#div_delete_logo').hide();
        $('#div_image_logo').hide();
        $('#div_upload_logo').show();
        $('#div_image_logo img').attr('src','');
    }

    window.delete_logo_mobile = function () {
        window.logo_mobile = '';
        window.map_need_save = true;
        $('#div_delete_logo_mobile').hide();
        $('#div_image_logo_mobile').hide();
        $('#div_upload_logo_mobile').show();
        $('#div_image_logo_mobile img').attr('src','');
    }

    window.change_style_marker = function () {
        if(marker_pos===null || marker_pos===undefined) return;
        var color_hex = $('#color_hex').val();
        var icon_label = $('#icon_label').val();
        var icon_color = $('#icon_color_hex').val();
        var icon_type = parseInt($('#icon_type option:selected').attr('id'));
        var marker_size = $('#marker_size').val();
        var unicode = window.getComputedStyle(document.getElementById("marker_icon"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
        var marker_library_icon = $('#marker_library_icon').val();
        var icon_image = $('#marker_library_icon_preview').attr('src');
        if(icon_type==2 && marker_library_icon==0) icon_type=0;
        if(color_hex=='') color_hex='rgba(0,0,0,0)';
        if(icon_color=='') icon_color='#ffffff';
        if(unicode=='6e')  {
            unicode='';
        }
        if(icon_label!='') {
            if(marker_size==0) {
                var scale_text = window.markers_size;
            } else {
                var scale_text = marker_size;
            }
            var icon_label_size = parseInt($('#icon_label_size').val());
            var icon_label_color = $('#icon_label_color').val();
            if(icon_label_color=='') {
                icon_label_color = '#000000';
            }
            var style_label = new ol.style.Style({
                text: new ol.style.Text({
                    text: icon_label.replace(/\\n/g, '\n'),
                    font: 'bold '+((scale_text<=1) ? icon_label_size : (icon_label_size*scale_text))+'px/1.2 Calibri,sans-serif',
                    fill: new ol.style.Fill({ color: icon_label_color }),
                    stroke: new ol.style.Stroke({ color: '#ffffff', width: 1 }),
                    textAlign: 'center',
                    textBaseline: 'top',
                    offsetY: 20*scale_text
                })
            });
        } else {
            var style_label = null;
        }
        var style = null;
        marker_pos.setStyle(null);
        marker_pos_style.setStyle(null);
        switch(icon_type) {
            case 0:
                if(marker_size==0) {
                    var scale = window.markers_size/10;
                } else {
                    var scale = marker_size/10;
                }
                var radius = 140*scale;
                style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: radius,
                        stroke: new ol.style.Stroke({
                            color: color_hex,
                            width: 3,
                        }),
                        fill: new ol.style.Fill({
                            color: color_hex,
                            weight: 1
                        })
                    })
                });
                break;
            case 1:
                if(marker_size==0) {
                    var scale = window.markers_size/10;
                } else {
                    var scale = marker_size/10;
                }
                var radius = 140*scale;
                var font_size = 120*scale;
                style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: radius,
                        stroke: new ol.style.Stroke({
                            color: color_hex,
                            width: 3,
                        }),
                        fill: new ol.style.Fill({
                            color: color_hex,
                            weight: 1
                        })
                    }),
                    text: new ol.style.Text({
                        text: String.fromCharCode("0x" + unicode),
                        font: '900 '+font_size+'px "Font Awesome 7 Free"',
                        fill: new ol.style.Fill({
                            color: icon_color
                        })
                    })
                });
                break;
            case 2:
                if(marker_size==0) {
                    var scale = window.markers_size/10;
                } else {
                    var scale = marker_size/10;
                }
                style = new ol.style.Style({
                    image: new ol.style.Icon({
                        anchor: [0.5, 0.5],
                        anchorXUnits: 'fraction',
                        anchorYUnits: 'fraction',
                        scale: scale,
                        opacity: 1,
                        src: icon_image,
                    })
                });
                break;
        }
        if(style_label!=null) {
            marker_pos.setStyle([style,style_label]);
            marker_pos_style.setStyle([style,style_label]);
        } else {
            marker_pos.setStyle(style);
            marker_pos_style.setStyle(style);
        }
    }

    function draw_geometries() {
        if(window.saved_geometries!='') {
            var features = new ol.format.GeoJSON().readFeatures(saved_geometries, { featureProjection: 'EPSG:3857' });
            features.forEach(function(feature){ feature.setId(undefined) });
            var source = new ol.source.Vector({
                features: features,
            });
            var vector_geometries = new ol.layer.Vector({
                source: source,
                zIndex: 1,
                style: function (f) {
                    return new ol.style.Style({
                        image: new ol.style.Circle({
                            radius: 5,
                            stroke: new ol.style.Stroke({ width: 1.5, color: f.get('color') || [255,0,0] }),
                            fill: new ol.style.Fill({ color: (f.get('color') || [255,0,0]).concat([.5]) })
                        }),
                        stroke: new ol.style.Stroke({ width: 2.5, color: f.get('color') || [255,0,0] }),
                        fill: new ol.style.Fill({ color: (f.get('color') || [255,0,0]).concat([.5]) })
                    })
                }
            });
            vector_geometries.setZIndex(1);
            map.addLayer(vector_geometries);
        }
    }

    window.draw_geodata = function() {
        $.ajax({
            url: "../viewer/ajax/get_geodata.php",
            type: "POST",
            data: {
                id_map: window.id_map
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var array_geodata = rsp.geodata;
                if (array_geodata.length > 0) {
                    $.each(array_geodata,function(index,geodata) {
                        try {
                            var geojson_layer = new ol.layer.Vector({
                                source: new ol.source.Vector({
                                    url: geodata.file,
                                    format: new ol.format.GeoJSON()
                                }),
                                style: function (f) {
                                    return new ol.style.Style({
                                        image: new ol.style.Circle({
                                            radius: 5,
                                            stroke: new ol.style.Stroke({ width: (f.get('stroke-width') || 1.5), color: hexToRgbA((f.get('stroke') || '#000000'),(f.get('stroke-opacity') || 0.5)) }),
                                            fill: new ol.style.Fill({ color: hexToRgbA((f.get('fill') || '#ffffff'),(f.get('fill-opacity') || 0.5)) })
                                        }),
                                        stroke: new ol.style.Stroke({ width: (f.get('stroke-width') || 1.5), color: hexToRgbA((f.get('stroke') || '#000000'),(f.get('stroke-opacity') || 0.5)) }),
                                        fill: new ol.style.Fill({ color: hexToRgbA((f.get('fill') || '#ffffff'),(f.get('fill-opacity') || 0.5)) })
                                    })
                                }
                            });
                            geojson_layer.setZIndex(1);
                            map.addLayer(geojson_layer);
                        } catch (e) {
                            console.log(e);
                        }
                    });
                }
            }
        });
    }

    window.get_map_default_style = function() {
        var default_style="";
        switch(window.map_street_provider) {
            case 'default':
                switch(window.map_style) {
                    case 'osm_free':
                        default_style = new ol.layer.WebGLTile({
                            source: new ol.source.XYZ({
                                url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                                maxZoom: window.street_maxzoom,
                            })
                        });
                        break;
                    case 'arcgis_street':
                        default_style = new ol.layer.WebGLTile({
                            source: new ol.source.XYZ({
                                url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
                                maxZoom: window.street_maxzoom,
                            })
                        });
                        break;
                    case 'arcgis_topo':
                        default_style = new ol.layer.WebGLTile({
                            source: new ol.source.XYZ({
                                url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
                                maxZoom: window.street_maxzoom,
                            })
                        });
                        break;
                }
                break;
            case 'carto':
                default_style = new ol.layer.WebGLTile({
                    source: new ol.source.XYZ({
                        url: 'https://{a-d}.basemaps.cartocdn.com/rastertiles/'+window.map_style+'/{z}/{x}/{y}{r}.png',
                        maxZoom: window.street_maxzoom,
                    })
                });
                break;
            case 'stadia':
                default_style = new ol.layer.WebGLTile({
                    source: new ol.source.XYZ({
                        url: 'https://tiles.stadiamaps.com/tiles/'+window.map_style+'/{z}/{x}/{y}@2x.png',
                        maxZoom: window.street_maxzoom,
                    })
                });
                break;
            case 'maptiler':
                default_style = new ol.layer.WebGLTile({
                    source: new ol.source.TileJSON({
                        url: 'https://api.maptiler.com/maps/'+window.map_style+'/tiles.json?key='+window.maptiler_api,
                        axZoom: window.street_maxzoom,
                        tileSize: 512,
                        crossOrigin: 'anonymous',
                    })
                });
                break;
            case 'here':
                if(window.here_lang=='') {
                    var here_url = 'https://maps.hereapi.com/v3/base/mc/{z}/{x}/{y}/jpeg?size=512&style='+window.map_style+'&apiKey='+window.here_api;
                } else {
                    var here_url = 'https://maps.hereapi.com/v3/base/mc/{z}/{x}/{y}/jpeg?size=512&lang='+window.here_lang+'&style='+window.map_style+'&apiKey='+window.here_api;
                }
                default_style = new ol.layer.WebGLTile({
                    source: new ol.source.XYZ({
                        url: here_url,
                        axZoom: window.street_maxzoom,
                        tileSize: 512,
                        crossOrigin: 'anonymous',
                    })
                });
                break;
            case 'google':
                switch(window.map_style) {
                    case 'google_roadmap':
                        var google_source = new ol.source.Google({
                            key: window.google_api,
                            mapType: 'roadmap',
                            scale: 'scaleFactor2x',
                            highDpi: true,
                            maxZoom: window.street_maxzoom,
                            language: window.google_lang
                        });
                        break;
                    case 'google_terrain':
                        var google_source = new ol.source.Google({
                            key: window.google_api,
                            mapType: 'terrain',
                            layerTypes: ['layerRoadmap'],
                            scale: 'scaleFactor2x',
                            highDpi: true,
                            maxZoom: window.street_maxzoom,
                            language: window.google_lang
                        });
                        break;
                }
                default_style = new ol.layer.WebGLTile({
                    source: google_source
                });
                break;
            case 'openfreemap':
                default_style = new ol.layer.Group();
                if(window.openfreemap_street_url!='') {
                    var url_openfreemap = window.openfreemap_street_url;
                } else {
                    var url_openfreemap = 'https://tiles.openfreemap.org/styles/'+window.map_style.replace('openfreemap_','');
                }
                olms.apply(default_style, url_openfreemap);
                break;
            case 'custom':
                default_style = new ol.layer.WebGLTile({
                    source: new ol.source.XYZ({
                        url: window.street_basemap,
                        maxZoom: window.street_maxzoom,
                    })
                });
                break;
        }
        return default_style;
    }

    window.get_map_satellite_style = function() {
        var satellite_style;
        switch(window.map_satellite_provider) {
            case 'default':
                switch(window.map_style_satellite) {
                    case 'arcgis':
                        satellite_style = new ol.layer.WebGLTile({
                            source: new ol.source.XYZ({
                                url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
                                maxZoom: (window.satellite_maxzoom>=19) ? 19 : window.satellite_maxzoom,
                            })
                        });
                        break;
                }
                break;
            case 'maptiler':
                switch(window.map_style_satellite) {
                    case 'satellite-v2':
                        var endpoint_maptiler = "tiles";
                        break;
                    default:
                        var endpoint_maptiler = "maps";
                        break;
                }
                satellite_style = new ol.layer.WebGLTile({
                    source: new ol.source.TileJSON({
                        url: 'https://api.maptiler.com/'+endpoint_maptiler+'/'+window.map_style_satellite+'/tiles.json?key='+window.maptiler_api_satellite,
                        axZoom: window.satellite_maxzoom,
                        tileSize: 512,
                        crossOrigin: 'anonymous',
                    })
                });
                break;
            case 'here':
                if(window.here_lang_satellite=='') {
                    var here_url = 'https://maps.hereapi.com/v3/base/mc/{z}/{x}/{y}/jpeg?size=512&style='+window.map_style_satellite+'&apiKey='+window.here_api_satellite;
                } else {
                    var here_url = 'https://maps.hereapi.com/v3/base/mc/{z}/{x}/{y}/jpeg?size=512&lang='+window.here_lang_satellite+'&style='+window.map_style_satellite+'&apiKey='+window.here_api_satellite;
                }
                satellite_style = new ol.layer.WebGLTile({
                    source: new ol.source.XYZ({
                        url: here_url,
                        axZoom: window.satellite_maxzoom,
                        tileSize: 512,
                        crossOrigin: 'anonymous',
                    })
                });
                break;
            case 'google':
                switch(window.map_style_satellite) {
                    case 'google_satellite':
                        var google_source = new ol.source.Google({
                            key: window.google_api_satellite,
                            mapType: 'satellite',
                            scale: 'scaleFactor2x',
                            highDpi: true,
                            maxZoom: window.satellite_maxzoom,
                            language: window.google_lang_satellite
                        });
                        break;
                    case 'google_hybrid':
                        var google_source = new ol.source.Google({
                            key: window.google_api_satellite,
                            mapType: 'satellite',
                            layerTypes: ['layerRoadmap'],
                            scale: 'scaleFactor2x',
                            highDpi: true,
                            maxZoom: window.satellite_maxzoom,
                            language: window.google_lang_satellite
                        });
                        break;
                }
                satellite_style = new ol.layer.WebGLTile({
                    source: google_source
                });
                break;
            case 'custom':
                satellite_style = new ol.layer.WebGLTile({
                    source: new ol.source.XYZ({
                        url: window.satellite_basemap,
                        maxZoom: window.satellite_maxzoom,
                    })
                });
                break;
        }
        return satellite_style;
    }

    window.initialize_map_marker = function (lon,lat,mode) {
        marker_pos = new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.fromLonLat([lon,lat]))
        });
        marker_pos_style = new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.fromLonLat([9,9]))
        });
        change_style_marker();
        var vectorSource = new ol.source.Vector({
            features: [marker_pos]
        });
        var vectorSource_style = new ol.source.Vector({
            features: [marker_pos_style]
        });
        switch(mode) {
            case 'edit':
                var zoom = 14;
                vectorLayer = new ol.layer.Vector({
                    source: vectorSource,
                    zIndex: 2
                });
                break;
            case 'add':
                if(lat=='0') {
                    var zoom = 1;
                } else {
                    var zoom = 10;
                }
                vectorLayer = new ol.layer.Vector({
                    source: vectorSource,
                    zIndex: 2,
                    visible: false
                });
                break;
        }
        map_view = new ol.View({
            center: ol.proj.fromLonLat([lon,lat]),
            zoom: zoom
        });
        default_style = get_map_default_style();
        satellite_style = get_map_satellite_style();
        var initial_layer=default_style;
        if(window.enable_map_street==0 || window.enable_map_satellite==0) {
            if(window.enable_map_street==1) {
                initial_layer=default_style;
            }
            if(window.enable_map_satellite==1) {
                initial_layer=satellite_style;
            }
        }
        map = new ol.Map({
            target: 'map_marker',
            controls : ol.control.defaults.defaults({
                attribution : false,
                zoom : true,
            }),
            layers: [initial_layer,vectorLayer],
            view: map_view
        });
        new ol.Map({
            target: 'map_marker_style',
            controls : ol.control.defaults.defaults({
                attribution : false,
                zoom : false,
            }),
            layers: [initial_layer,new ol.layer.Vector({
                source: vectorSource_style,
                zIndex: 2
            })],
            view: new ol.View({
                center: ol.proj.fromLonLat([9,9]),
                zoom: 16
            })
        });
        if(window.enable_map_street==0 && window.enable_map_satellite==1) {
            change_map_style('satellite_style');
        } else if(window.enable_map_street==1 && window.enable_map_satellite==1 && window.default_view=='satellite') {
            change_map_style('satellite_style');
        }
        var currZoom = parseInt(map.getView().getZoom());
        $('#zoom_level').html(currZoom);
        map.on('moveend', function(e) {
            var newZoom = parseInt(map.getView().getZoom());
            if (currZoom != newZoom) {
                $('#zoom_level').html(newZoom);
                currZoom = newZoom;
            }
        });
        map.on('click', function(evt){
            vectorLayer.setVisible(true);
            marker_pos.getGeometry().setCoordinates(evt.coordinate);
            var lat_lon = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
            window.lon_marker = parseFloat(lat_lon[0]).toFixed(6);
            window.lat_marker = parseFloat(lat_lon[1]).toFixed(6);
            $('#lon').html(window.lon_marker);
            $('#lat').html(window.lat_marker);
            check_set_position();
            $('#longitude_edit').val(window.lon_marker);
            $('#latitude_edit').val(window.lat_marker);
            draw_geofence();
            window.marker_need_save = true;
        });
        var drag_interaction = new ol.interaction.Translate({layers: [vectorLayer]});
        vectorLayer.on('change',function(evt) {
            var coordinates = marker_pos.getGeometry().getCoordinates();
            var lat_lon = ol.proj.transform(coordinates, 'EPSG:3857', 'EPSG:4326');
            window.lon_marker = parseFloat(lat_lon[0]).toFixed(6);
            window.lat_marker = parseFloat(lat_lon[1]).toFixed(6);
            $('#lon').html(window.lon_marker);
            $('#lat').html(window.lat_marker);
            check_set_position();
            $('#longitude_edit').val(window.lon_marker);
            $('#latitude_edit').val(window.lat_marker);
            draw_geofence();
        });
        map.addInteraction(drag_interaction);
        draw_geofence();
        draw_geometries();
        draw_geodata();
    };

    function hexToRgbA(hex,opacity){
        var c;
        if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
            c= hex.substring(1).split('');
            if(c.length== 3){
                c= [c[0], c[0], c[1], c[1], c[2], c[2]];
            }
            c= '0x'+c.join('');
            return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+opacity+')';
        }
        return 'rgba(0,0,0,'+opacity+')';
    }

    window.change_map_style = function (id) {
        switch(id) {
            case 'default_style':
                $('#satellite_style').show();
                $('#default_style').hide();
                try {
                    map.removeLayer(satellite_style);
                    map.getLayers().insertAt(0, default_style);
                } catch (e) {}
                break;
            case 'satellite_style':
                $('#satellite_style').hide();
                $('#default_style').show();
                try {
                    map.removeLayer(default_style);
                    map.getLayers().insertAt(0, satellite_style);
                } catch (e) {}
                break;
        }
    }

    window.set_marker_position = function() {
        var lat = $('#latitude_edit').val();
        var lon = $('#longitude_edit').val();
        if(lat!='' && lon!='') {
            lat = lat.replace(",",".");
            lon = lon.replace(",",".");
            marker_pos.getGeometry().setCoordinates(ol.proj.fromLonLat([lon,lat]));
            var coordinates = marker_pos.getGeometry().getCoordinates();
            var size = map.getSize();
            var w = size[0]/2;
            var h = size[1]/2;
            map_view.centerOn(coordinates, size, [w,h]);
            window.lon_marker = parseFloat(lon).toFixed(6);
            window.lat_marker = parseFloat(lat).toFixed(6);
            $('#lon').html(window.lon_marker);
            $('#lat').html(window.lat_marker);
            $('#longitude_edit').val(window.lon_marker);
            $('#latitude_edit').val(window.lat_marker);
            draw_geofence();
            window.marker_need_save = true;
            vectorLayer.setVisible(true);
        }
    }

    function getYouTubeId(url) {
        if (!url || typeof url !== 'string') return null;
        const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;
        const match = url.match(regExp);
        return (match && match[2].length === 11) ? match[2] : null;
    }

    function getVimeoId(url) {
        if (!url || typeof url !== 'string') return null;
        const regExp = /vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/;
        const match = url.match(regExp);
        return match ? match[1] : null;
    }

    window.getMediaType = function(resource) {
        if (!resource || typeof resource !== 'string') return 'unknown';
        if (getYouTubeId(resource)) return 'youtube';
        if (getVimeoId(resource)) return 'vimeo';
        const parts = resource.split('.');
        if (parts.length === 1) return 'unknown';
        const extension = parts.pop().toLowerCase().split('?')[0];
        const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
        const videoExtensions = ['mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'webm'];
        if (imageExtensions.includes(extension)) return 'image';
        if (videoExtensions.includes(extension)) return 'video';
        return 'unknown';
    }

    window.get_marker_images = function(id) {
        $('#image_gallery').empty();
        $('#msg_sel_image').show();
        $('#sender_info_card').hide();
        $('#btn_setmain_image').addClass('d-none');
        $('#btn_delete_image').addClass('d-none');
        $('#btn_validate_image').addClass('d-none');
        $('#btn_preview_media').addClass('d-none');
        $('#btn_show_image').addClass('d-none');
        $('#btn_hide_image').addClass('d-none');
        $('#btn_rotate_image_l').addClass('d-none');
        $('#btn_rotate_image_r').addClass('d-none');
        $('#div_edit_video_link').addClass('d-none');
        $.ajax({
            url: "ajax/get_marker_images.php",
            type: "POST",
            data: { id_marker: id },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                jQuery.each(rsp, function(index, marker_image) {
                    var icon_main = (parseInt(marker_image.main) == 1)
                        ? '<i style="display:block;" class="fas fa-star"></i>'
                        : '<i style="display:none;" class="fas fa-star"></i>';
                    var gps = marker_image.gps;
                    var lat = '', lon = '', icon_gps = '<i style="display:none;" class="fas fa-location"></i>';
                    if (gps !== null) {
                        lat = gps.lat;
                        lon = gps.lon;
                        icon_gps = '<i style="display:block;" class="fas fa-location"></i>';
                    }
                    if (marker_image.image.startsWith('media_')) {
                        var path_i = 'media';
                    } else {
                        var path_i = 'marker_images';
                    }
                    var to_validate = marker_image.to_validate;
                    var validate_style = (to_validate == '1') ? 'border: 3px solid #f6c23e;' : '';
                    var type = getMediaType(marker_image.image);
                    var sender_name = marker_image.sender_name ? marker_image.sender_name.replace(/'/g, "&apos;").replace(/"/g, "&quot;") : '';
                    var sender_email = marker_image.sender_email ? marker_image.sender_email.replace(/'/g, "&apos;").replace(/"/g, "&quot;") : '';
                    var anchor_open = "<a data-tovalidate='"+to_validate+"' style='position:relative; "+validate_style+"' data-id='"+marker_image.id+"' data-lat='"+lat+"' data-lon='"+lon+"' data-exclude='"+marker_image.exclude+"' data-action='update' data-image='"+marker_image.image+"' data-main='"+marker_image.main+"' data-sendername='"+sender_name+"' data-senderemail='"+sender_email+"' href='#'>";
                    switch (type) {
                        case 'image':
                            $('#image_gallery').append(
                                anchor_open +
                                "<i class=\"fa-solid fa-image\"></i>" + icon_main + icon_gps +
                                "<img draggable='false' src='../viewer/"+path_i+"/thumb/"+marker_image.image+"'/></a>"
                            );
                            break;
                        case 'video':
                            $('#image_gallery').append(
                                anchor_open +
                                "<i class=\"fa-solid fa-video\"></i>" + icon_main + icon_gps +
                                "<video draggable='false' muted src='../viewer/"+path_i+"/"+marker_image.image+"#t=2'/></a>"
                            );
                            break;
                        case 'youtube':
                            var ytId = getYouTubeId(marker_image.image);
                            var ytThumb = ytId ? "https://img.youtube.com/vi/" + ytId + "/mqdefault.jpg" : "images/placeholder_video.jpg";
                            $('#image_gallery').append(
                                anchor_open +
                                "<i class=\"fa-brands fa-youtube\"></i>" + icon_main + icon_gps +
                                "<img draggable='false' src='"+ytThumb+"'/></a>"
                            );
                            break;
                        case 'vimeo':
                            var vimeoImgId = 'vimeo_thumb_' + marker_image.id;
                            var vPlaceholder = "images/placeholder_video.jpg";
                            $('#image_gallery').append(
                                anchor_open +
                                "<i class=\"fa-brands fa-vimeo-v\"></i>" + icon_main + icon_gps +
                                "<img id='"+vimeoImgId+"' draggable='false' src='"+vPlaceholder+"'/></a>"
                            );
                            $.getJSON('https://vimeo.com/api/oembed.json?url=' + encodeURIComponent(marker_image.image), function(data) {
                                if(data && data.thumbnail_url) {
                                    $('#' + vimeoImgId).attr('src', data.thumbnail_url);
                                }
                            });
                            break;
                    }
                });
                if (typeof marker_image_max !== 'undefined' && marker_image_max != -1) {
                    marker_images_uploaded = parseInt(rsp.length);
                    if (marker_images_uploaded >= marker_image_max) {
                        $('#gallery-dropzone').addClass('disabled');
                    }
                }
                var el = document.getElementById('image_gallery');
                if(el) Sortable.create(el);
                $('#image_gallery a').off('click').on('click', function (event) {
                    event.preventDefault();
                    select_image($(this));
                });
            }
        });
    };

    window.set_marker_position_image = function() {
        var lat = $('#image_gallery a.image-highlight').attr('data-lat');
        var lon = $('#image_gallery a.image-highlight').attr('data-lon');
        $('#latitude_edit').val(lat);
        $('#longitude_edit').val(lon);
        set_marker_position();
        $('#image_gps_pos_btn').addClass('disabled');
        var html_btn = $('#image_gps_pos_btn').html();
        $('#image_gps_pos_btn').html('<i class="fas fa-check"></i>&nbsp;&nbsp;'+window.backend_labels.position_set);
        $('#image_gps_pos_btn').removeClass('btn-primary').addClass('btn-success');
        setTimeout(function () {
            $('#image_gps_pos_btn').html(html_btn);
            $('#image_gps_pos_btn').addClass('btn-primary').removeClass('btn-success');
            $('#image_gps_pos_btn').removeClass('disabled');
        },1000);
    }

    function isImage(str) {
        return /\.(jpg|jpeg|png|webp)$/i.test(str);
    }

    window.add_video_link = function() {
        var url = $('#video_link_input').val();
        if(url == '') return;
        var type = getMediaType(url);
        if(type != 'youtube' && type != 'vimeo') {
            alert("Invalid URL. Please enter a valid YouTube or Vimeo link.");
            return;
        }
        var count_images = $('#image_gallery a[data-main="1"]').length;
        var main = (count_images == 0) ? '1' : '0';
        var icon_main = (main == '1') ? '<i style="display:block;" class="fas fa-star"></i>' : '<i style="display:none;" class="fas fa-star"></i>';
        var id = 0;
        var lat = '', lon = '';
        var icon_gps = '<i style="display:none;" class="fas fa-location"></i>';
        var thumbnail = "images/placeholder_video.jpg";
        var icon_type = "<i class=\"fa-solid fa-video\"></i>";
        if(type == 'youtube') {
            var ytId = getYouTubeId(url);
            thumbnail = ytId ? "https://img.youtube.com/vi/" + ytId + "/mqdefault.jpg" : "images/placeholder_video.jpg";
            icon_type = "<i class=\"fa-brands fa-youtube\"></i>";
        } else if(type == 'vimeo') {
            icon_type = "<i class=\"fa-brands fa-vimeo-v\"></i>";
        }
        var html = "<a data-id='"+id+"' data-lat='"+lat+"' data-lon='"+lon+"' data-exclude='0' data-action='insert' data-image='"+url+"' data-main='"+main+"' href='#'>" +
            icon_type + icon_main + icon_gps +
            "<img draggable='false' class='img_thumb' src='"+thumbnail+"'/></a>";

        $('#image_gallery').append(html);
        if(type == 'vimeo') {
            var $lastLink = $('#image_gallery a').last();
            $.getJSON('https://vimeo.com/api/oembed.json?url=' + encodeURIComponent(url), function(data) {
                if(data && data.thumbnail_url) {
                    $lastLink.find('img').attr('src', data.thumbnail_url);
                }
            });
        }
        $('#modal_add_video_link').modal('hide');
        $('#video_link_input').val('');
        $('#image_gallery a').off('click').on('click', function (event) {
            event.preventDefault();
            select_image($(this));
        });
        window.marker_need_save = true;
    }

    window.update_video_link = function() {
        if(sel_elem == null) return;
        var new_url = $('#video_link_edit').val();
        if(new_url == '') return;
        var type = getMediaType(new_url);
        if(type != 'youtube' && type != 'vimeo') {
            alert("Invalid URL.");
            return;
        }
        sel_elem.attr('data-image', new_url);
        sel_elem.data('image', new_url);
        if(sel_elem.data('action') != 'insert') {
            sel_elem.attr('data-action', 'update');
            sel_elem.data('action', 'update');
        }
        var icon_i = sel_elem.find('i').first();
        if(type == 'youtube') {
            icon_i.attr('class', 'fa-brands fa-youtube');
        } else {
            icon_i.attr('class', 'fa-brands fa-vimeo-v');
        }
        var img_tag = sel_elem.find('img');
        if(type == 'youtube') {
            sel_elem.data("image",new_url);
            var ytId = getYouTubeId(new_url);
            var thumb = ytId ? "https://img.youtube.com/vi/" + ytId + "/mqdefault.jpg" : "images/placeholder_video.jpg";
            img_tag.attr('src', thumb);
        } else if(type == 'vimeo') {
            sel_elem.data("image",new_url);
            img_tag.attr('src', "images/placeholder_video.jpg");
            $.getJSON('https://vimeo.com/api/oembed.json?url=' + encodeURIComponent(new_url), function(data) {
                if(data && data.thumbnail_url) {
                    img_tag.attr('src', data.thumbnail_url);
                }
            });
        }
        window.marker_need_save = true;
        var btn = $('#div_edit_video_link button');
        var original_html = btn.html();
        btn.html('<i class="fas fa-check"></i>');
        setTimeout(function() { btn.html(original_html); }, 1000);
    }

    var sel_elem = null, map_image_gps = null;
    window.select_image = function (elem) {
        sel_elem = elem;
        var main = elem.data("main");
        var exclude = elem.data("exclude");
        var lat = elem.data("lat");
        var lon = elem.data("lon");
        var action = elem.data("action");
        var image = elem.data('image');
        var id = elem.data('id');
        var to_validate = elem.data('tovalidate');
        $('#image_gallery a').removeClass("image-highlight");
        elem.addClass("image-highlight");
        $('#btn_setmain_image, #btn_hide_image, #btn_show_image, #btn_rotate_image_l, #btn_rotate_image_r, #div_edit_video_link, #btn_validate_image, #btn_preview_media, #btn_delete_image').addClass('d-none');
        var sender_name = elem.attr("data-sendername");
        var sender_email = elem.attr("data-senderemail");
        if (sender_name && sender_name.trim() !== '') {
            $('#sender_info_card').show();
            $('#sender_name_val').text(sender_name);
            if (sender_email && sender_email.trim() !== '') {
                $('#sender_email_div').show();
                $('#sender_email_val').text(sender_email).attr('href', 'mailto:' + sender_email);
            } else {
                $('#sender_email_div').hide();
            }
        } else {
            $('#sender_info_card').hide();
        }
        $('#btn_preview_media').removeClass('d-none');
        $('#btn_delete_image').removeClass('d-none');
        $('#msg_sel_image').hide();
        if (to_validate == '1') {
            $('#btn_validate_image').removeClass('d-none');
            $('#msg_sel_image_2').hide();
        } else {
            $('#btn_setmain_image').removeClass('d-none');
            if(main=='1') {
                $('#btn_setmain_image button').html('<i class="fa fa-star"></i>&nbsp;&nbsp;'+window.backend_labels.main_image);
                $('#btn_setmain_image button').prop('disabled',true);
            } else {
                $('#btn_setmain_image button').html(window.backend_labels.set_as_main);
                $('#btn_setmain_image button').prop('disabled',false);
            }
            if(exclude=='0') {
                $('#btn_show_image').addClass('d-none');
                $('#btn_hide_image').removeClass('d-none');
            } else {
                $('#btn_show_image').removeClass('d-none');
                $('#btn_hide_image').addClass('d-none');
            }
            $('#msg_sel_image_2').hide();
            var type = getMediaType(image);
            if(type == 'youtube' || type == 'vimeo') {
                $('#div_edit_video_link').removeClass('d-none');
                $('#video_link_edit').val(image);
                $('#btn_rotate_image_l').addClass('d-none');
                $('#btn_rotate_image_r').addClass('d-none');
            } else {
                $('#div_edit_video_link').addClass('d-none');
                if(action!='delete' && isImage(image)) {
                    $('#btn_rotate_image_l').removeClass('d-none');
                    $('#btn_rotate_image_r').removeClass('d-none');
                    $('#btn_rotate_image_l button').attr('onclick',"rotate_image('"+image+"',"+id+",90)");
                    $('#btn_rotate_image_r button').attr('onclick',"rotate_image('"+image+"',"+id+",-90)");
                } else {
                    $('#btn_rotate_image_l').addClass('d-none');
                    $('#btn_rotate_image_r').addClass('d-none');
                }
            }
        }
        if(lat!='' && lon!=''){
            $('#msg_no_image_gps').hide();
            $('#image_gps_pos_div').show();
            var blueDotStyle = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 9,
                    fill: new ol.style.Fill({ color: 'blue' }),
                    stroke: new ol.style.Stroke({ color: 'white', width: 2 })
                })
            });
            setTimeout(function() {
                if(map_image_gps==null) {
                    const markerFeature = new ol.Feature({
                        geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat]))
                    });
                    markerFeature.setStyle(blueDotStyle);
                    var vectorSource_image_gps = new ol.source.Vector({
                        features: [markerFeature]
                    });
                    default_style = get_map_default_style();
                    satellite_style = get_map_satellite_style();
                    var initial_layer=default_style;
                    if(window.enable_map_street==0 || window.enable_map_satellite==0) {
                        if(window.enable_map_street==1) initial_layer=default_style;
                        if(window.enable_map_satellite==1) initial_layer=satellite_style;
                    }
                    map_image_gps = new ol.Map({
                        target: 'image_gps_pos',
                        controls : ol.control.defaults.defaults({ attribution : false, zoom : false }),
                        layers: [initial_layer,new ol.layer.Vector({ source: vectorSource_image_gps, zIndex: 2 })],
                        view: new ol.View({ center: ol.proj.fromLonLat([lon,lat]), zoom: 16 })
                    });
                } else {
                    const newCoord = ol.proj.fromLonLat([lon, lat]);
                    map_image_gps.getView().setCenter(newCoord);
                    map_image_gps.getView().setZoom(16);
                    const vectorLayer = map_image_gps.getLayers().item(1);
                    const vectorSource = vectorLayer.getSource();
                    vectorSource.clear();
                    const markerFeature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat])) });
                    markerFeature.setStyle(blueDotStyle);
                    vectorSource.addFeature(markerFeature);
                }
            },250);
        } else {
            $('#msg_no_image_gps').show();
            $('#image_gps_pos_div').hide();
        }
    }

    window.delete_image = function () {
        window.marker_need_save = true;
        if(marker_image_max!=-1) {
            window.marker_images_uploaded = window.marker_images_uploaded-1;
            if(marker_images_uploaded<marker_image_max) {
                $('#gallery-dropzone').removeClass('disabled');
                $('#gallery-dropzone')[0].dropzone.options.maxFiles = marker_image_max-marker_images_uploaded;
            }
        }
        var main = sel_elem.data("main");
        sel_elem.attr('data-action', 'delete');
        sel_elem.data('action', 'delete');
        sel_elem.attr('data-main', '0');
        sel_elem.data('main', '0');
        sel_elem.css('background-color','red');
        sel_elem.css('pointer-events','none');
        sel_elem.css('opacity',0.1);
        sel_elem.removeClass('image-highlight');
        $('#btn_setmain_image, #btn_delete_image, #btn_show_image, #btn_hide_image, #btn_rotate_image_l, #btn_rotate_image_r, #div_edit_video_link, #btn_validate_image, #btn_preview_media').addClass('d-none');
        $('#msg_sel_image').show();
        if(main=='1') {
            $("#image_gallery a").each(function(index) {
                if($(this).data('action')!='delete') {
                    $(this).attr('data-main', '1');
                    $(this).data('main', '1');
                    return false;
                }
            });
        }
    }

    window.preview_media = function() {
        if(!sel_elem) return;
        var image = sel_elem.data('image');
        var type = getMediaType(image);
        var path_i = image.startsWith('media_') ? 'media' : 'marker_images';
        var src = '../viewer/' + path_i + '/' + image;
        $('#modal_preview_media .modal-body').empty();
        if(type === 'image') {
            $('#modal_preview_media .modal-body').html('<img src="'+src+'" style="width:100%; height:auto; display:block;" />');
        } else if(type === 'video') {
            $('#modal_preview_media .modal-body').html('<video src="'+src+'" controls autoplay style="width:100%; height:auto; display:block;"></video>');
        } else if(type === 'youtube') {
            var ytId = getYouTubeId(image);
            $('#modal_preview_media .modal-body').html('<iframe width="100%" height="600px" src="https://www.youtube.com/embed/'+ytId+'?autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>');
        } else if(type === 'vimeo') {
            var vimId = getVimeoId(image);
            $('#modal_preview_media .modal-body').html('<iframe width="100%" height="600px" src="https://player.vimeo.com/video/'+vimId+'?autoplay=1" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>');
        }
        $('#modal_preview_media').modal('show');
    };

    window.validate_image = function () {
        if(!sel_elem) return;
        if(confirm(window.backend_labels.sure_validate_image)) {
            var id = sel_elem.data("id");
            $('#btn_validate_image button').addClass('disabled');
            var btn_html = $('#btn_validate_image button').html();
            $('#btn_validate_image button').html('<i class="fas fa-circle-notch fa-spin"></i>');
            $.ajax({
                url: "ajax/validate_marker_image.php",
                type: "POST",
                async: true,
                data: {
                    id_marker: window.id_marker,
                    id_image: id
                },
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        sel_elem.css('border', '');
                        sel_elem.data('tovalidate', '0');
                        sel_elem.attr('data-tovalidate', '0');
                        select_image(sel_elem);
                    }
                    $('#btn_validate_image button').html(btn_html);
                    $('#btn_validate_image button').removeClass('disabled');
                },
                error: function() {
                    $('#btn_validate_image button').html(btn_html);
                    $('#btn_validate_image button').removeClass('disabled');
                }
            });
        }
    };

    window.set_as_main = function () {
        window.marker_need_save = true;
        $("#image_gallery a").each(function(index) {
            $(this).attr('data-main', '0');
            $(this).data('main', '0');
            $(this).find('.fa-star').hide();
        });
        sel_elem.attr('data-main', '1');
        sel_elem.data('main', '1');
        sel_elem.find('.fa-star').show();
        select_image(sel_elem);
    }

    window.show_image = function () {
        window.marker_need_save = true;
        sel_elem.attr('data-exclude', '0');
        sel_elem.data('exclude', '0');
        select_image(sel_elem);
    }

    window.hide_image = function () {
        window.marker_need_save = true;
        sel_elem.attr('data-exclude', '1');
        sel_elem.data('exclude', '1');
        select_image(sel_elem);
    }

    window.delete_icon = function () {
        $("#marker_icon").removeClass();
        $('#marker_icon_input').val('');
        $('#btn_delete_icon').prop('disabled',true);
        window.marker_need_save = true;
    }

    window.address_to_position = function () {
        const geocode_mode = window.geocoding_provider;
        const button = $('#btn_address_position');
        const btn_html = button.html();
        button.html('<i class="fas fa-circle-notch fa-spin"></i>');
        const addressComponents = [
            $('#street').val(),
            $('#city').val(),
            $('#postal_code').val(),
            $('#country').val(),
            $('#county').val(),
            $('#state').val()
        ];
        const query = addressComponents.join(',').replace(/\ /g, '+');
        function addressToPosition_queryNominatim(q) {
            return $.get(`https://nominatim.openstreetmap.org/search?q=${q}&format=json&polygon=1&addressdetails=1`);
        }
        function addressToPosition_queryGoogle(q) {
            return $.get(`ajax/google_address_to_position.php?query=${q}`);
        }
        function updateCoordinates(lat, lon) {
            $('#latitude_edit').val(lat);
            $('#longitude_edit').val(lon);
            set_marker_position();
            map_view.setZoom(16);
        }
        function resetButton(statusClass) {
            button.removeClass('btn-primary btn-success btn-danger').addClass(statusClass);
            setTimeout(() => button.removeClass(statusClass).addClass('btn-primary'), 300);
            button.html(btn_html);
        }
        function attemptNominatimQueries(components) {
            const queries = [
                components.join(','),
                [components[0], components[2], components[3]].join(','),
                [components[0], components[2]].join(',')
            ];
            let queryIndex = 0;
            function tryNextQuery() {
                if (queryIndex >= queries.length) {
                    resetButton('btn-danger');
                    return;
                }
                const q = queries[queryIndex].replace(/\ /g, '+');
                queryIndex++;
                addressToPosition_queryNominatim(q).done((data) => {
                    if (data.length > 0) {
                        updateCoordinates(data[0].lat, data[0].lon);
                        resetButton('btn-success');
                    } else {
                        tryNextQuery();
                    }
                }).fail(() => resetButton('btn-danger'));
            }
            tryNextQuery();
        }
        function attemptGoogleQuery() {
            addressToPosition_queryGoogle(query)
                .done((response) => {
                    if (response.status === 'OK' && response.results.length > 0) {
                        const location = response.results[0].geometry.location;
                        updateCoordinates(location.lat, location.lng);
                        resetButton('btn-success');
                    } else {
                        resetButton('btn-danger');
                    }
                })
                .fail(() => resetButton('btn-danger'));
        }
        if (geocode_mode === 'google') {
            attemptGoogleQuery();
        } else if (geocode_mode === 'nominatim') {
            attemptNominatimQueries(addressComponents);
        }
    };

    function containsOnlyNumbersOrUnderscores(str) {
        return /^[0-9_]+$/.test(str);
    }

    window.position_to_address = function () {
        const button = $('#btn_position_address');
        const btn_html = button.html();
        button.html('<i class="fas fa-circle-notch fa-spin"></i>');
        var lat = $('#latitude_edit').val();
        var lon = $('#longitude_edit').val();
        const geocode_mode = window.geocoding_provider;
        function positionToAddress_queryNominatim(lat, lon) {
            return $.get(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=json&addressdetails=1`);
        }
        function positionToAddress_queryGoogle(lat, lon) {
            return $.get(`ajax/google_position_to_address.php?lat=${lat}&lon=${lon}`);
        }
        function populateAddressFields(address) {
            try {
                $('#street').val((containsOnlyNumbersOrUnderscores(address.road) ? address.quarter : address.road) || address.route);
            } catch (e) {}
            try {
                $('#city').val(address.city || address.locality);
            } catch (e) {}
            if ($('#city').val() === '') {
                try {
                    $('#city').val(address.town || address.village);
                } catch (e) {}
            }
            try {
                $('#postal_code').val(address.postcode || address.postal_code);
            } catch (e) {}
            try {
                $('#country').val(address.country || address.country_name);
            } catch (e) {}
            try {
                $('#county').val(address.county || address.administrative_area_level_2);
            } catch (e) {}
            try {
                $('#state').val(address.state || address.administrative_area_level_1);
            } catch (e) {}
        }
        function resetButton(statusClass) {
            button.removeClass('btn-primary btn-success btn-danger').addClass(statusClass);
            setTimeout(() => button.removeClass(statusClass).addClass('btn-primary'), 300);
            button.html(btn_html);
        }
        if (geocode_mode === 'google') {
            positionToAddress_queryGoogle(lat, lon).done((response) => {
                if (response.status === 'OK' && response.results.length > 0) {
                    const addressComponents = response.results[0].address_components;
                    const address = {};
                    addressComponents.forEach((component) => {
                        component.types.forEach((type) => {
                            address[type] = component.long_name;
                        });
                    });
                    populateAddressFields(address);
                    resetButton('btn-success');
                } else {
                    resetButton('btn-danger');
                }
            })
            .fail(() => resetButton('btn-danger'));
        } else if (geocode_mode === 'nominatim') {
            positionToAddress_queryNominatim(lat, lon)
                .done((data) => {
                    if (data && data.address) {
                        populateAddressFields(data.address);
                        resetButton('btn-success');
                    } else {
                        resetButton('btn-danger');
                    }
                })
                .fail(() => resetButton('btn-danger'));
        }
    };

    window.marker_geocode_reverse = function(id_marker, lat, lon) {
        const geocode_mode = window.geocoding_provider;
        function markerGeocode_queryNominatim(lat, lon) {
            return $.get(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=json&addressdetails=1`);
        }
        function markerGeocode_queryGoogle(lat, lon) {
            return $.get(`ajax/google_position_to_address.php?lat=${lat}&lon=${lon}`);
        }
        function handleAddress(resolve, address) {
            var street = (containsOnlyNumbersOrUnderscores(address.road) ? address.quarter : address.road) || address.route;
            var city = address.city || address.locality;
            if(city=='' || city==undefined) {
                city = address.town || address.village;
            }
            var postal_code = address.postcode || address.postal_code;
            var country = address.country || address.country_name;
            var county = address.county || address.administrative_area_level_2;
            var state = address.state || address.administrative_area_level_1;
            var result = {
                street: street,
                city: city,
                postal_code: postal_code,
                country: country,
                county: county,
                state: state
            };
            resolve(result);
        }
        return new Promise((resolve, reject) => {
            if (geocode_mode === 'google') {
                markerGeocode_queryGoogle(lat,lon).done((response) => {
                    if (response.status === 'OK' && response.results.length > 0) {
                        const addressComponents = response.results[0].address_components;
                        const address = {};
                        addressComponents.forEach((component) => {
                            component.types.forEach((type) => {
                                address[type] = component.long_name;
                            });
                        });
                        handleAddress(resolve, address);
                    } else {
                        resolve(null);
                    }
                })
                .fail(() => resolve(null));
            } else if (geocode_mode === 'nominatim') {
                markerGeocode_queryNominatim(lat,lon).done((data) => {
                    if (data && data.address) {
                        handleAddress(resolve, data.address);
                    } else {
                        resolve(null);
                    }
                }).fail(() => resolve(null));
            } else {
                resolve(null);
            }
        });
    }

    window.marker_geocode = function(id_marker, street, city, postal_code, country, county, state) {
        const geocode_mode = window.geocoding_provider;
        const addressComponents = [street, city, postal_code, country, county, state];
        const query = addressComponents.join(',').replace(/\ /g, '+');
        function markerGeocode_queryNominatim(q) {
            return $.get(`https://nominatim.openstreetmap.org/search?q=${q}&format=json&polygon=1&addressdetails=1`);
        }
        function markerGeocode_queryGoogle(q) {
            return $.get(`ajax/google_address_to_position.php?query=${q}`);
        }
        return new Promise((resolve, reject) => {
            function handleGeocodeData(data) {
                if (data && data.length > 0) {
                    const lat = data[0].lat || data[0].geometry.location.lat;
                    const lon = data[0].lon || data[0].geometry.location.lng;
                    resolve({ lat, lon });
                } else {
                    resolve(null);
                }
            }
            function tryNominatimQueries(components) {
                const queries = [
                    components.join(','),
                    [components[0], components[2], components[3]].join(','), // without city
                    [components[0], components[2]].join(',') // street and postal code only
                ];
                let queryIndex = 0;
                function tryNextQuery() {
                    if (queryIndex >= queries.length) {
                        resolve(null);
                        return;
                    }
                    const q = queries[queryIndex].replace(/\ /g, '+');
                    queryIndex++;
                    markerGeocode_queryNominatim(q).done((data) => {
                        if (data.length > 0) {
                            handleGeocodeData(data);
                        } else {
                            tryNextQuery();
                        }
                    }).fail(() => resolve(null));
                }
                tryNextQuery();
            }
            if (geocode_mode === 'google') {
                markerGeocode_queryGoogle(query)
                    .done((response) => {
                        if (response.status === 'OK' && response.results.length > 0) {
                            handleGeocodeData(response.results);
                        } else {
                            resolve(null);
                        }
                    })
                    .fail(() => resolve(null));
            } else if (geocode_mode === 'nominatim') {
                tryNominatimQueries(addressComponents);
            } else {
                resolve(null);
            }
        });
    };

    window.save_marker = function () {
        var complete = true;
        var array_lang = {};
        var name = $('#name').val();
        array_lang['name'] = {};
        $('.input_lang[data-target-id="name"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['name'][lang]=value;
        });
        var categories_t = $('#category option');
        var categories = [];
        $(categories_t).each(function(index, elem){
            var id = $(this).attr('id');
            if($(this).is(':selected') && !$(this).is(':disabled')) {
                categories.push(id);
            }
        });
        var street = $('#street').val();
        var city = $('#city').val();
        var postal_code = $('#postal_code').val();
        var country = $('#country').val();
        var county = $('#county').val();
        var state = $('#state').val();
        var website = $('#website').val();
        var website_caption = $('#website_caption').val();
        var email = $('#email').val();
        var phone = $('#phone').val();
        if(phone!='') {
            var phone_prefix = $('#phone_prefix').val();
            phone = phone_prefix+phone;
        }
        var whatsapp = $('#whatsapp').val();
        if(whatsapp!='') {
            var whatsapp_prefix = $('#whatsapp_prefix').val();
            whatsapp = whatsapp_prefix+whatsapp;
        }
        var color_hex = $('#color_hex').val();
        var icon_color_hex = $('#icon_color_hex').val();
        var color_hex_hover = $('#color_hex_hover').val();
        var icon_color_hex_hover = $('#icon_color_hex_hover').val();
        var marker_size = $('#marker_size').val();
        var icon = $('#marker_icon_input').val();
        var icon_label = $('#icon_label').val();
        array_lang['icon_label'] = {};
        $('.input_lang[data-target-id="icon_label"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['icon_label'][lang]=value;
        });
        var icon_label_color = $('#icon_label_color').val();
        var icon_label_size = $('#icon_label_size').val();
        var unicode = window.getComputedStyle(document.getElementById("marker_icon"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
        if(unicode=='6e')  {
            icon='';
        } else {
            icon = icon + '|' + unicode;
        }
        var id_icon_library = $('#marker_library_icon').val();
        var icon_type = parseInt($('#icon_type option:selected').attr('id'));
        switch (icon_type) {
            case 0:
                icon = '';
                id_icon_library = 0;
                break;
            case 1:
                id_icon_library = 0;
                break;
            case 2:
                icon = '';
                break;
        }
        var icon_e1 = $('#marker_icon_input_e1').val();
        var icon_e2 = $('#marker_icon_input_e2').val();
        var icon_e3 = $('#marker_icon_input_e3').val();
        var icon_e4 = $('#marker_icon_input_e4').val();
        var icon_e5 = $('#marker_icon_input_e5').val();
        var icon_e6 = $('#marker_icon_input_e6').val();
        var icon_e7 = $('#marker_icon_input_e7').val();
        var icon_e8 = $('#marker_icon_input_e8').val();
        var icon_e9 = $('#marker_icon_input_e9').val();
        var icon_e10 = $('#marker_icon_input_e10').val();
        var icon_e11 = $('#marker_icon_input_e11').val();
        var icon_e12 = $('#marker_icon_input_e12').val();
        var icon_e13 = $('#marker_icon_input_e13').val();
        var icon_e14 = $('#marker_icon_input_e14').val();
        var icon_e15 = $('#marker_icon_input_e15').val();
        var icon_e16 = $('#marker_icon_input_e16').val();
        var icon_e17 = $('#marker_icon_input_e17').val();
        var icon_e18 = $('#marker_icon_input_e18').val();
        var icon_e19 = $('#marker_icon_input_e19').val();
        var icon_e20 = $('#marker_icon_input_e20').val();
        var icon_b1 = $('#marker_icon_input_b1').val();
        var title_b1 = $('#extra_button_title_1').val();
        var visible_e1 = ($('#extra_field_visible_1').is(':checked')) ? 1 : 0;
        var visible_e2 = ($('#extra_field_visible_2').is(':checked')) ? 1 : 0;
        var visible_e3 = ($('#extra_field_visible_3').is(':checked')) ? 1 : 0;
        var visible_e4 = ($('#extra_field_visible_4').is(':checked')) ? 1 : 0;
        var visible_e5 = ($('#extra_field_visible_5').is(':checked')) ? 1 : 0;
        var visible_e6 = ($('#extra_field_visible_6').is(':checked')) ? 1 : 0;
        var visible_e7 = ($('#extra_field_visible_7').is(':checked')) ? 1 : 0;
        var visible_e8 = ($('#extra_field_visible_8').is(':checked')) ? 1 : 0;
        var visible_e9 = ($('#extra_field_visible_9').is(':checked')) ? 1 : 0;
        var visible_e10 = ($('#extra_field_visible_10').is(':checked')) ? 1 : 0;
        var visible_e11 = ($('#extra_field_visible_11').is(':checked')) ? 1 : 0;
        var visible_e12 = ($('#extra_field_visible_12').is(':checked')) ? 1 : 0;
        var visible_e13 = ($('#extra_field_visible_13').is(':checked')) ? 1 : 0;
        var visible_e14 = ($('#extra_field_visible_14').is(':checked')) ? 1 : 0;
        var visible_e15 = ($('#extra_field_visible_15').is(':checked')) ? 1 : 0;
        var visible_e16 = ($('#extra_field_visible_16').is(':checked')) ? 1 : 0;
        var visible_e17 = ($('#extra_field_visible_17').is(':checked')) ? 1 : 0;
        var visible_e18 = ($('#extra_field_visible_18').is(':checked')) ? 1 : 0;
        var visible_e19 = ($('#extra_field_visible_19').is(':checked')) ? 1 : 0;
        var visible_e20 = ($('#extra_field_visible_20').is(':checked')) ? 1 : 0;
        array_lang['extra_button_title_1'] = {};
        $('.input_lang[data-target-id="extra_button_title_1"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_button_title_1'][lang]=value;
        });
        var field_e = [];
        for (var i = 1; i <= 20; i++) {
            field_e[i] = window.editor_html_extra_fields[i].getValue();
            array_lang['extra_field_value_' + i] = {};
            $('.input_lang[data-target-id="extra_field_value_' + i + '"]').each(function() {
                var lang = $(this).attr('data-lang');
                var value = (window.editor_html_extra_fields_langs[i] && window.editor_html_extra_fields_langs[i][lang])
                    ? window.editor_html_extra_fields_langs[i][lang].getValue()
                    : $(this).text();
                array_lang['extra_field_value_' + i][lang] = value;
            });
        }
        var value_b1 = window.editor_html_extra_button_1.getValue();
        array_lang['extra_button_value_1'] = {};
        $('.input_lang[data-target-id="extra_button_value_1"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_extra_button_1_langs[lang] ? window.editor_html_extra_button_1_langs[lang].getValue() : $(this).text();
            array_lang['extra_button_value_1'][lang]=value;
        });
        console.log(array_lang['extra_button_value_1']);
        var name_e1 = $('#extra_field_name_1').val();
        array_lang['extra_field_name_1'] = {};
        $('.input_lang[data-target-id="extra_field_name_1"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_1'][lang]=value;
        });
        var name_e2 = $('#extra_field_name_2').val();
        array_lang['extra_field_name_2'] = {};
        $('.input_lang[data-target-id="extra_field_name_2"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_2'][lang]=value;
        });
        var name_e3 = $('#extra_field_name_3').val();
        array_lang['extra_field_name_3'] = {};
        $('.input_lang[data-target-id="extra_field_name_3"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_3'][lang]=value;
        });
        var name_e4 = $('#extra_field_name_4').val();
        array_lang['extra_field_name_4'] = {};
        $('.input_lang[data-target-id="extra_field_name_4"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_4'][lang]=value;
        });
        var name_e5 = $('#extra_field_name_5').val();
        array_lang['extra_field_name_5'] = {};
        $('.input_lang[data-target-id="extra_field_name_5"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_5'][lang]=value;
        });
        var name_e6 = $('#extra_field_name_6').val();
        array_lang['extra_field_name_6'] = {};
        $('.input_lang[data-target-id="extra_field_name_6"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_6'][lang]=value;
        });
        var name_e7 = $('#extra_field_name_7').val();
        array_lang['extra_field_name_7'] = {};
        $('.input_lang[data-target-id="extra_field_name_7"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_7'][lang]=value;
        });
        var name_e8 = $('#extra_field_name_8').val();
        array_lang['extra_field_name_8'] = {};
        $('.input_lang[data-target-id="extra_field_name_8"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_8'][lang]=value;
        });
        var name_e9 = $('#extra_field_name_9').val();
        array_lang['extra_field_name_9'] = {};
        $('.input_lang[data-target-id="extra_field_name_9"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_9'][lang]=value;
        });
        var name_e10 = $('#extra_field_name_10').val();
        array_lang['extra_field_name_10'] = {};
        $('.input_lang[data-target-id="extra_field_name_10"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_10'][lang]=value;
        });
        var name_e11 = $('#extra_field_name_11').val();
        array_lang['extra_field_name_11'] = {};
        $('.input_lang[data-target-id="extra_field_name_11"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_11'][lang]=value;
        });
        var name_e12 = $('#extra_field_name_12').val();
        array_lang['extra_field_name_12'] = {};
        $('.input_lang[data-target-id="extra_field_name_12"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_12'][lang]=value;
        });
        var name_e13 = $('#extra_field_name_13').val();
        array_lang['extra_field_name_13'] = {};
        $('.input_lang[data-target-id="extra_field_name_13"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_13'][lang]=value;
        });
        var name_e14 = $('#extra_field_name_14').val();
        array_lang['extra_field_name_14'] = {};
        $('.input_lang[data-target-id="extra_field_name_14"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_14'][lang]=value;
        });
        var name_e15 = $('#extra_field_name_15').val();
        array_lang['extra_field_name_15'] = {};
        $('.input_lang[data-target-id="extra_field_name_15"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_15'][lang]=value;
        });
        var name_e16 = $('#extra_field_name_16').val();
        array_lang['extra_field_name_16'] = {};
        $('.input_lang[data-target-id="extra_field_name_16"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_16'][lang]=value;
        });
        var name_e17 = $('#extra_field_name_17').val();
        array_lang['extra_field_name_17'] = {};
        $('.input_lang[data-target-id="extra_field_name_17"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_17'][lang]=value;
        });
        var name_e18 = $('#extra_field_name_18').val();
        array_lang['extra_field_name_18'] = {};
        $('.input_lang[data-target-id="extra_field_name_18"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_18'][lang]=value;
        });
        var name_e19 = $('#extra_field_name_19').val();
        array_lang['extra_field_name_19'] = {};
        $('.input_lang[data-target-id="extra_field_name_19"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_19'][lang]=value;
        });
        var name_e20 = $('#extra_field_name_20').val();
        array_lang['extra_field_name_20'] = {};
        $('.input_lang[data-target-id="extra_field_name_20"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['extra_field_name_20'][lang]=value;
        });
        var active = ($('#active').is(':checked')) ? 1 : 0;
        var open_sheet = ($('#open_sheet').is(':checked'))  ? 1 : 0;
        var view_popup = ($('#view_popup').is(':checked')) ? 1 : 0;
        var centered = ($('#centered').is(':checked')) ? 1 : 0;
        var featured = ($('#featured').is(':checked')) ? 1 : 0;
        var visible_map = ($('#visible_map').is(':checked')) ? 1 : 0;
        var visible_search = ($('#visible_search').is(':checked')) ? 1 : 0;
        if(window.id_marker==0) {
            var to_validate = 0;
        } else {
            if($('#to_validate').length) {
                var to_validate = ($('#to_validate').is(':checked')) ? 0 : 1;
            } else {
                var to_validate = 0;
            }
        }
        var view_directions = ($('#view_directions').is(':checked')) ? 1 : 0;
        var view_street_view = ($('#view_street_view').is(':checked')) ? 1 : 0;
        var view_review = ($('#view_review').is(':checked')) ? 1 : 0;
        var view_add_photo = ($('#view_add_photo').is(':checked')) ? 1 : 0;
        var view_share = ($('#view_share').is(':checked')) ? 1 : 0;
        var view_last_update = ($('#view_last_update').is(':checked')) ? 1 : 0;
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        var hours = window.hours_editor.root.innerHTML;
        array_lang['hours'] = {};
        $('.input_lang[data-target-id="hours_div"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.hours_editor_lang[lang] ? window.hours_editor_lang[lang].root.innerHTML : $(this).html();
            array_lang['hours'][lang]=value;
        });

        var description = window.description_editor.root.innerHTML;
        array_lang['description'] = {};
        $('.input_lang[data-target-id="description_div"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.description_editor_lang[lang] ? window.description_editor_lang[lang].root.innerHTML : $(this).html();
            array_lang['description'][lang]=value;
        });
        var array_images = [];
        $("#image_gallery a").each(function(index) {
            var id = $(this).data("id");
            var main = $(this).data("main");
            var exclude = $(this).data("exclude");
            var action = $(this).data("action");
            var image = $(this).data("image");
            array_images.push({id:id,main:main,exclude:exclude,action:action,image:image});
        });
        var array_images_json = JSON.stringify(array_images);
        var min_zoom_level = $('#min_zoom_level option:selected').attr('id');
        var geofence_radius = $('#geofence_radius').val();
        var geofence_color = $('#geofence_color').val();
        var popup_image_height = $('#popup_image_height').val();
        var popup_background = $('#popup_background').val();
        var popup_color = $('#popup_color').val();
        var open_extra_content = $('#open_extra_content').is(':checked');
        var lat = $('#latitude_edit').val();
        var lon = $('#longitude_edit').val();
        if(open_extra_content) open_extra_content=1; else open_extra_content=0;
        if($('#enable_schedule').is(':checked')) {
            var date_from = $('#date_from').val();
            var date_to = $('#date_to').val();
            var ignore_year = ($("#ignore_year").is(':checked')) ? 1 : 0;
            var hour_from = $('#hour_from').val();
            var hour_to = $('#hour_to').val();
            var days_1 = ($("#days_1").is(':checked')) ? 1 : 0;
            var days_2 = ($("#days_2").is(':checked')) ? 1 : 0;
            var days_3 = ($("#days_3").is(':checked')) ? 1 : 0;
            var days_4 = ($("#days_4").is(':checked')) ? 1 : 0;
            var days_5 = ($("#days_5").is(':checked')) ? 1 : 0;
            var days_6 = ($("#days_6").is(':checked')) ? 1 : 0;
            var days_7 = ($("#days_7").is(':checked')) ? 1 : 0;
            var schedule = {};
            schedule['from_date'] = date_from;
            schedule['to_date'] = date_to;
            schedule['ignore_year'] = ignore_year;
            schedule['from_hour'] = hour_from;
            schedule['to_hour'] = hour_to;
            schedule['days'] = days_1+","+days_2+","+days_3+","+days_4+","+days_5+","+days_6+","+days_7;
            schedule = JSON.stringify(schedule);
        } else {
            schedule = '';
        }
        if($('#enable_schedule_box').is(':checked')) {
            var date_from = $('#date_from_box').val();
            var date_to = $('#date_to_box').val();
            var ignore_year = ($("#ignore_year_box").is(':checked')) ? 1 : 0;
            var hour_from = $('#hour_from_box').val();
            var hour_to = $('#hour_to_box').val();
            var days_1 = ($("#days_1_box").is(':checked')) ? 1 : 0;
            var days_2 = ($("#days_2_box").is(':checked')) ? 1 : 0;
            var days_3 = ($("#days_3_box").is(':checked')) ? 1 : 0;
            var days_4 = ($("#days_4_box").is(':checked')) ? 1 : 0;
            var days_5 = ($("#days_5_box").is(':checked')) ? 1 : 0;
            var days_6 = ($("#days_6_box").is(':checked')) ? 1 : 0;
            var days_7 = ($("#days_7_box").is(':checked')) ? 1 : 0;
            var schedule_box = {};
            schedule_box['from_date'] = date_from;
            schedule_box['to_date'] = date_to;
            schedule_box['ignore_year'] = ignore_year;
            schedule_box['from_hour'] = hour_from;
            schedule_box['to_hour'] = hour_to;
            schedule_box['days'] = days_1+","+days_2+","+days_3+","+days_4+","+days_5+","+days_6+","+days_7;
            schedule_box = JSON.stringify(schedule_box);
        } else {
            schedule_box = '';
        }
        var box_warning = $('#box_warning').val();
        array_lang['box_warning'] = {};
        $('.input_lang[data-target-id="box_warning"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['box_warning'][lang]=value;
        });
        var type = $('#type option:selected').attr('id');
        var link = $('#link_t').val();
        var tripadvisor_location_id = $('#tripadvisor_location_id').val();
        var song_link = $('#song_link').val();
        var song_bg_volume = $('#song_bg_volume').val();
        var song_volume = $('#song_volume').val();
        var song_play_bg = ($('#song_play_bg').is(':checked')) ? 1 : 0;
        var selected_zoom = $('#selected_zoom option:selected').attr('id');
        var duration_zoom = $('#duration_zoom').val();
        if(link=='') type='default';
        if(complete) {
            var array_lang_json = JSON.stringify(array_lang);
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            $.ajax({
                url: "ajax/save_marker.php",
                type: "POST",
                data: {
                    id: window.id_marker,
                    name: name,
                    id_categories: categories,
                    street: street,
                    city: city,
                    postal_code: postal_code,
                    country: country,
                    county: county,
                    state: state,
                    website: website,
                    website_caption: website_caption,
                    email: email,
                    phone: phone,
                    whatsapp: whatsapp,
                    h_desc: hours,
                    description: description,
                    lat: lat,
                    lon: lon,
                    min_zoom_level: min_zoom_level,
                    array_images: array_images_json,
                    active: active,
                    open_sheet: open_sheet,
                    view_popup: view_popup,
                    to_validate: to_validate,
                    centered: centered,
                    featured: featured,
                    view_directions: view_directions,
                    view_street_view: view_street_view,
                    view_review: view_review,
                    view_add_photo: view_add_photo,
                    view_share: view_share,
                    view_last_update: view_last_update,
                    color_hex: color_hex,
                    icon_color_hex: icon_color_hex,
                    color_hex_hover: color_hex_hover,
                    icon_color_hex_hover: icon_color_hex_hover,
                    marker_size: marker_size,
                    icon: icon,
                    icon_label: icon_label,
                    icon_label_color: icon_label_color,
                    icon_label_size: icon_label_size,
                    id_icon_library: id_icon_library,
                    icon_e1: icon_e1,
                    icon_e2: icon_e2,
                    icon_e3: icon_e3,
                    icon_e4: icon_e4,
                    icon_e5: icon_e5,
                    icon_e6: icon_e6,
                    icon_e7: icon_e7,
                    icon_e8: icon_e8,
                    icon_e9: icon_e9,
                    icon_e10: icon_e10,
                    icon_e11: icon_e11,
                    icon_e12: icon_e12,
                    icon_e13: icon_e13,
                    icon_e14: icon_e14,
                    icon_e15: icon_e15,
                    icon_e16: icon_e16,
                    icon_e17: icon_e17,
                    icon_e18: icon_e18,
                    icon_e19: icon_e19,
                    icon_e20: icon_e20,
                    field_e1: field_e[1],
                    field_e2: field_e[2],
                    field_e3: field_e[3],
                    field_e4: field_e[4],
                    field_e5: field_e[5],
                    field_e6: field_e[6],
                    field_e7: field_e[7],
                    field_e8: field_e[8],
                    field_e9: field_e[9],
                    field_e10: field_e[10],
                    field_e11: field_e[11],
                    field_e12: field_e[12],
                    field_e13: field_e[13],
                    field_e14: field_e[14],
                    field_e15: field_e[15],
                    field_e16: field_e[16],
                    field_e17: field_e[17],
                    field_e18: field_e[18],
                    field_e19: field_e[19],
                    field_e20: field_e[20],
                    name_e1: name_e1,
                    name_e2: name_e2,
                    name_e3: name_e3,
                    name_e4: name_e4,
                    name_e5: name_e5,
                    name_e6: name_e6,
                    name_e7: name_e7,
                    name_e8: name_e8,
                    name_e9: name_e9,
                    name_e10: name_e10,
                    name_e11: name_e11,
                    name_e12: name_e12,
                    name_e13: name_e13,
                    name_e14: name_e14,
                    name_e15: name_e15,
                    name_e16: name_e16,
                    name_e17: name_e17,
                    name_e18: name_e18,
                    name_e19: name_e19,
                    name_e20: name_e20,
                    icon_b1: icon_b1,
                    title_b1: title_b1,
                    value_b1: value_b1,
                    visible_e1: visible_e1,
                    visible_e2: visible_e2,
                    visible_e3: visible_e3,
                    visible_e4: visible_e4,
                    visible_e5: visible_e5,
                    visible_e6: visible_e6,
                    visible_e7: visible_e7,
                    visible_e8: visible_e8,
                    visible_e9: visible_e9,
                    visible_e10: visible_e10,
                    visible_e11: visible_e11,
                    visible_e12: visible_e12,
                    visible_e13: visible_e13,
                    visible_e14: visible_e14,
                    visible_e15: visible_e15,
                    visible_e16: visible_e16,
                    visible_e17: visible_e17,
                    visible_e18: visible_e18,
                    visible_e19: visible_e19,
                    visible_e20: visible_e20,
                    geofence_radius: geofence_radius,
                    geofence_color: geofence_color,
                    popup_image_height: popup_image_height,
                    popup_background: popup_background,
                    popup_color: popup_color,
                    open_extra_content: open_extra_content,
                    schedule: schedule,
                    schedule_box: schedule_box,
                    box_warning: box_warning,
                    type: type,
                    link: link,
                    visible_map: visible_map,
                    visible_search: visible_search,
                    song: window.song,
                    song_link: song_link,
                    song_bg_volume: song_bg_volume,
                    song_volume: song_volume,
                    song_play_bg: song_play_bg,
                    selected_zoom: selected_zoom,
                    duration_zoom: duration_zoom,
                    tripadvisor_location_id: tripadvisor_location_id,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        if(window.id_marker==0) {
                            window.marker_need_save = false;
                            location.href='index.php?p=markers';
                        } else {
                            window.marker_need_save = false;
                            $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                            setTimeout(function () {
                                $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                                $('#save_btn').removeClass("disabled");
                            },1000);
                            get_marker_images(window.id_marker);
                        }
                    } else {
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                    }
                }, error: function () {
                    $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                    $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                    setTimeout(function () {
                        $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                        $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                        $('#save_btn').removeClass("disabled");
                    },1000);
                }
            });
        }
    }

    var layerCircle;
    function addCircle(lon,lat,radius,color) {
        var rgb = color.replace('rgba(','').replace(')','').split(',');
        rgb = "rgb("+rgb[0]+","+rgb[1]+","+rgb[2]+")";
        var centerLongitudeLatitude = ol.proj.fromLonLat([lon, lat]);
        layerCircle = new ol.layer.Vector({
            source: new ol.source.Vector({
                features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, radius))]
            }),
            style: [
                new ol.style.Style({
                    stroke: new ol.style.Stroke({
                        color: rgb,
                        width: 1
                    }),
                    fill: new ol.style.Fill({
                        color: color
                    })
                })
            ]
        });
        layerCircle.setZIndex(1);
        map.addLayer(layerCircle);
    }

    window.check_schedule = function () {
        if($('#enable_schedule').is(':checked')) {
            $('#schedule_content').removeClass('disabled');
        } else {
            $('#schedule_content').addClass('disabled');
        }
    }

    window.check_schedule_box = function () {
        if($('#enable_schedule_box').is(':checked')) {
            $('#schedule_content_box').removeClass('disabled');
        } else {
            $('#schedule_content_box').addClass('disabled');
        }
    }

    window.draw_geofence = function() {
        map.removeLayer(layerCircle);
        var geofence_radius = parseInt($('#geofence_radius').val());
        var geofence_color = $('#geofence_color').val();
        if(geofence_radius>0) {
            var lat = parseFloat(window.lat_marker);
            var lon = parseFloat(window.lon_marker);
            addCircle(lon, lat, geofence_radius, geofence_color);
        }
    }

    window.assign_icon_to_markers = function (type,id) {
        $('.btn_assign_icons').addClass('disabled');
        var retVal = confirm(window.backend_labels.icons_assign_msg);
        if( retVal == true ) {
            var markers_size = $('#markers_size').val();
            var color_hex = $('#color_hex').val();
            var icon_color_hex = $('#icon_color_hex').val();
            var color_hex_hover = $('#color_hex_hover').val();
            var icon_color_hex_hover = $('#icon_color_hex_hover').val();
            var icon = $('#marker_icon_input').val();
            var unicode = window.getComputedStyle(document.getElementById("marker_icon"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
            if(unicode=='6e')  {
                icon='';
            } else {
                icon = icon + '|' + unicode;
            }
            var id_icon_library = $('#marker_library_icon').val();
            var icon_type = parseInt($('#icon_type option:selected').attr('id'));
            switch (icon_type) {
                case 0:
                    icon = '';
                    id_icon_library = 0;
                    break;
                case 1:
                    id_icon_library = 0;
                    break;
                case 2:
                    icon = '';
                    break;
            }
            $.ajax({
                url: "ajax/assign_icon_to_markers.php",
                type: "POST",
                data: {
                    type: type,
                    id: id,
                    markers_size: markers_size,
                    markers_color_hex: color_hex,
                    markers_icon_color_hex: icon_color_hex,
                    markers_color_hex_hover: color_hex_hover,
                    markers_icon_color_hex_hover: icon_color_hex_hover,
                    markers_icon: icon,
                    markers_id_icon_library: id_icon_library,
                },
                async: false,
                success: function (json) {
                    $('.btn_assign_icons').removeClass('disabled');
                }
            });
        } else {
            $('.btn_assign_icons').removeClass('disabled');
            return false;
        }
    }

    window.assign_fields_to_markers = function (id) {
        $('.btn_assign_fields').addClass('disabled');
        var retVal = confirm(window.backend_labels.fields_assign_msg);
        if( retVal == true ) {
            var default_extra_fields = {};
            for(var i=1;i<=20;i++) {
                var icon = $('#marker_icon_input_e'+i).val();
                default_extra_fields[i]=icon;
            }
            default_extra_fields = JSON.stringify(default_extra_fields);
            $.ajax({
                url: "ajax/assign_fields_to_markers.php",
                type: "POST",
                data: {
                    id: id,
                    default_extra_fields: default_extra_fields
                },
                async: false,
                success: function (json) {
                    $('.btn_assign_fields').removeClass('disabled');
                }
            });
        } else {
            $('.btn_assign_fields').removeClass('disabled');
            return false;
        }
    }

    window.save_category = function () {
        var complete = true;
        var name = $('#name').val();
        var id_category_parent = $('#id_category_parent option:selected').attr('id');
        var default_selected = ($('#default_selected').is(':checked')) ? 1 : 0;
        var featured = ($('#featured').is(':checked')) ? 1 : 0;
        var add_from_map = ($('#add_from_map').is(':checked')) ? 1 : 0;
        var array_lang = {};
        array_lang['name'] = {};
        $('.input_lang[data-target-id="name"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['name'][lang]=value;
        });
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        var default_am_fields = {};
        if($('#add_markers_fields_override').is(':checked')) {
            default_am_fields['street']=($('#am_street').is(':checked')) ? 1 : 0;
            default_am_fields['city']=($('#am_city').is(':checked')) ? 1 : 0;
            default_am_fields['state']=($('#am_state').is(':checked')) ? 1 : 0;
            default_am_fields['postal_code']=($('#am_postal_code').is(':checked')) ? 1 : 0;
            default_am_fields['county']=($('#am_county').is(':checked')) ? 1 : 0;
            default_am_fields['country']=($('#am_country').is(':checked')) ? 1 : 0;
            default_am_fields['categories']=($('#am_categories').is(':checked')) ? 1 : 0;
            default_am_fields['website']=($('#am_website').is(':checked')) ? 1 : 0;
            default_am_fields['email']=($('#am_email').is(':checked')) ? 1 : 0;
            default_am_fields['phone']=($('#am_phone').is(':checked')) ? 1 : 0;
            default_am_fields['whatsapp']=($('#am_whatsapp').is(':checked')) ? 1 : 0;
            default_am_fields['description']=($('#am_description').is(':checked')) ? 1 : 0;
            default_am_fields['hours']=($('#am_hours').is(':checked')) ? 1 : 0;
            default_am_fields['images']=($('#am_images').is(':checked')) ? 1 : 0;
            for(var i=1;i<=20;i++) {
                default_am_fields['field_'+i]=($('#am_field_'+i).is(':checked')) ? 1 : 0;
            }
        }
        default_am_fields = JSON.stringify(default_am_fields);
        if(complete) {
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            var array_lang_json = JSON.stringify(array_lang);
            if(window.id_category!=0) {
                var markers_size = $('#markers_size').val();
                var color_hex = $('#color_hex').val();
                var icon_color_hex = $('#icon_color_hex').val();
                var color_hex_hover = $('#color_hex_hover').val();
                var icon_color_hex_hover = $('#icon_color_hex_hover').val();
                var icon = $('#marker_icon_input').val();
                var unicode = window.getComputedStyle(document.getElementById("marker_icon"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
                if(unicode=='6e')  {
                    icon='';
                } else {
                    icon = icon + '|' + unicode;
                }
                var id_icon_library = $('#marker_library_icon').val();
                var icon_type = parseInt($('#icon_type option:selected').attr('id'));
                switch (icon_type) {
                    case 0:
                        icon = '';
                        id_icon_library = 0;
                        break;
                    case 1:
                        id_icon_library = 0;
                        break;
                    case 2:
                        icon = '';
                        break;
                }
            } else {
                var markers_size = '';
                var color_hex = '';
                var icon_color_hex = '';
                var color_hex_hover = '';
                var icon_color_hex_hover = '';
                var icon = '';
                var id_icon_library = '';
            }
            var color_hex_c = $('#color_hex_c').val();
            var icon_color_hex_c = $('#icon_color_hex_c').val();
            var icon_c = $('#marker_icon_input_c').val();
            var unicode_c = window.getComputedStyle(document.getElementById("marker_icon_c"), ':before').content.replace(/'|"/g, '').charCodeAt(0).toString(16);
            if(unicode_c=='6e')  {
                icon_c='';
            } else {
                icon_c = icon_c + '|' + unicode_c;
            }
            var id_icon_library_c = $('#marker_library_icon_c').val();
            var icon_type_c = parseInt($('#icon_type_c option:selected').attr('id'));
            switch (icon_type_c) {
                case 0:
                    icon_c = '';
                    id_icon_library_c = 0;
                    break;
                case 1:
                    id_icon_library_c = 0;
                    break;
                case 2:
                    icon_c = '';
                    break;
            }
            $.ajax({
                url: "ajax/save_category.php",
                type: "POST",
                data: {
                    id: window.id_category,
                    name: name,
                    id_category_parent: id_category_parent,
                    default_selected: default_selected,
                    featured: featured,
                    add_from_map: add_from_map,
                    markers_size: markers_size,
                    markers_color_hex: color_hex,
                    markers_icon_color_hex: icon_color_hex,
                    markers_color_hex_hover: color_hex_hover,
                    markers_icon_color_hex_hover: icon_color_hex_hover,
                    markers_icon: icon,
                    markers_id_icon_library: id_icon_library,
                    color_hex_c: color_hex_c,
                    icon_color_hex_c: icon_color_hex_c,
                    icon_c: icon_c,
                    id_icon_library_c: id_icon_library_c,
                    default_am_fields: default_am_fields,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        if(window.id_category==0) {
                            window.category_need_save = false;
                            location.href='index.php?p=categories';
                        } else {
                            window.category_need_save = false;
                            $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                            setTimeout(function () {
                                $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                                $('#save_btn').removeClass("disabled");
                            },1000);
                        }

                    } else {
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                    }
                }
            });
        }
    }

    window.add_user = function () {
        var complete = true;
        var username = $('#username').val();
        var email = $('#email').val();
        var role = $('#role option:selected').attr('id');
        var password = $('#password').val();
        var password2 = $('#repeat_password').val();
        if(username=='') {
            complete = false;
            $('#username').addClass("error-highlight");
        } else {
            $('#username').removeClass("error-highlight");
        }
        if(password=='') {
            complete = false;
            $('#password').addClass("error-highlight");
        } else {
            $('#password').removeClass("error-highlight");
        }
        if(password2=='') {
            complete = false;
            $('#repeat_password').addClass("error-highlight");
        } else {
            $('#repeat_password').removeClass("error-highlight");
        }
        if((password!='') && (password2!='')) {
            if(password!=password2) {
                complete = false;
                $('#password').addClass("error-highlight");
                $('#repeat_password').addClass("error-highlight");
            } else {
                $('#password').removeClass("error-highlight");
                $('#repeat_password').removeClass("error-highlight");
            }
        }
        if(complete) {
            $('#modal_new_user button').addClass("disabled");
            $.ajax({
                url: "ajax/add_user.php",
                type: "POST",
                data: {
                    username: username,
                    email: email,
                    password: password,
                    role: role
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#modal_new_user button').removeClass("disabled");
                        $('#modal_new_user').modal("hide");
                        location.reload();
                    } else {
                        $('#modal_new_user button').removeClass("disabled");
                    }
                }
            });
        }
    };

    window.get_user_stats = function (id_user_edit) {
        $.ajax({
            url: "ajax/get_user_stats.php",
            type: "POST",
            data: {
                id_user: id_user_edit
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                $('#num_maps').html(rsp.count_maps);
                $('#num_markers').html(rsp.count_markers);
            }
        });
    };

    window.change_password = function () {
        var complete = true;
        var password = $('#password').val();
        var password2 = $('#repeat_password').val();
        if(password=='') {
            complete = false;
            $('#password').addClass("error-highlight");
        } else {
            $('#password').removeClass("error-highlight");
        }
        if(password2=='') {
            complete = false;
            $('#repeat_password').addClass("error-highlight");
        } else {
            $('#repeat_password').removeClass("error-highlight");
        }
        if((password!='') && (password2!='')) {
            if(password!=password2) {
                complete = false;
                $('#password').addClass("error-highlight");
                $('#repeat_password').addClass("error-highlight");
            } else {
                $('#password').removeClass("error-highlight");
                $('#repeat_password').removeClass("error-highlight");
            }
        }
        if(complete) {
            $('#modal_change_password button').addClass("disabled");
            $.ajax({
                url: "ajax/change_password.php",
                type: "POST",
                data: {
                    id: window.id_user_edit,
                    password: password,
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        window.user_need_save = false;
                        $('#modal_change_password button').removeClass("disabled");
                        $('#modal_change_password').modal("hide");
                        $('#password').val('');
                        $('#repeat_password').val('');
                    } else {
                        $('#modal_change_password button').removeClass("disabled");
                    }
                }
            });
        }
    };

    window.save_user = function(id_user_edit) {
        var complete = true;
        var username = $('#username').val();
        var email = $('#email').val();
        var role = $('#role option:selected').attr('id');
        var active = ($('#active').is(':checked')) ? 1 : 0;
        if(username=='') {
            complete = false;
            $('#username').addClass("error-highlight");
        } else {
            $('#username').removeClass("error-highlight");
        }
        if(complete) {
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            $.ajax({
                url: "ajax/save_user.php",
                type: "POST",
                data: {
                    id: id_user_edit,
                    username: username,
                    email: email,
                    role: role,
                    active: active,
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        window.user_need_save = false;
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                    } else {
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                    }
                }
            });
        }
    }

    window.change_friendly_url = function(type,id_elem,id) {
        var friendly_url = $('#'+id_elem).val();
        if(friendly_url=='') {
            $('#'+id_elem).parent().find('.input-group-append').addClass('disabled');
            $('#link_f_vr').parent().addClass('disabled');
        } else {
            $('#'+id_elem).parent().find('.input-group-append').removeClass('disabled');
            $('#link_f_vr').parent().removeClass('disabled');
        }
        var url = window.link_f+friendly_url;
        var url_vr = window.link_f_vr+friendly_url;
        $.ajax({
            url: 'ajax/set_friendly_url.php',
            type: "POST",
            data: {
                type: type,
                id: id,
                friendly_url: friendly_url
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if(rsp.status=='ok') {
                    $('#open_link_f').attr('href',url);
                    $('#copy_link_f').attr('data-clipboard-text',url);
                    $('#qrcode_link_f').attr('onclick','open_qr_code_modal(\''+url+'\')');
                    $('#link_open_vr').attr('href',url_vr);
                    $('#link_copy_vr').attr('data-clipboard-text',url_vr);
                    $('#link_qr_vr').attr('onclick','open_qr_code_modal(\''+url_vr+'\')');
                    $('#link_f_vr').val(url_vr);
                    $('#link_f').attr('data-default-value',url);
                    $('.input_lang[data-target-id="link_f"]').each(function() {
                        var lang = $(this).attr('data-lang');
                        if($('#link_f').val()=='') {
                            $(this).val('');
                            var link_f = '';
                        } else {
                            $(this).val($('#link_f').val()+"@"+lang);
                            var link_f = window.link_f+$('#link_f').val()+"@"+lang;
                        }
                        $('.input_lang[data-target-id="link_f"][data-lang="'+lang+'"]').attr('data-default-value',link_f);
                        $('.input_lang[data-target-id="open_link_f"][data-lang="'+lang+'"]').attr('href',link_f);
                        $('.input_lang[data-target-id="copy_link_f"][data-lang="'+lang+'"]').attr('data-clipboard-text',link_f);
                        $('.input_lang[data-target-id="qrcode_link_f"][data-lang="'+lang+'"]').attr('onclick','open_qr_code_modal(\''+link_f+'\')');
                    });
                    $('#'+id_elem).removeClass('error-highlight');
                    $('#'+id_elem).css('color','unset');
                } else {
                    $('#'+id_elem).addClass('error-highlight');
                    $('#'+id_elem).css('color','red');
                }
            }
        })
    }

    window.delete_image_meta = function (type,id) {
        window.image_meta = '';
        $('#div_delete_image_meta').hide();
        $('#div_upload_image_meta').show();
        if(window.image_meta_default=='') {
            $('.facebook-preview__image').addClass('d-none');
            $('.facebook-preview__image').attr('src','');
        } else {
            $('.facebook-preview__image').removeClass('d-none');
            $('.facebook-preview__image').attr('src','../viewer/content/'+window.image_meta_default);
        }
        save_metadata(type,id);
    }

    window.change_meta_title = function() {
        var meta_title = '';
        if($('#meta_title').is(':visible')) {
            meta_title = $('#meta_title').val();
        } else {
            $('.input_lang[data-target-id="meta_title"]').each(function() {
                if($(this).is(':visible')) {
                    meta_title = $(this).val();
                }
            });
        }
        if(meta_title=='') {
            if(window.title_meta_default=='') {
                $('.facebook-preview__title').html('');
            } else {
                $('.facebook-preview__title').html(title_meta_default);
            }
        } else {
            $('.facebook-preview__title').html(meta_title);
        }
    }

    window.change_meta_description = function() {
        var meta_description = '';
        if($('#meta_description').is(':visible')) {
            meta_description = $('#meta_description').val();
        } else {
            $('.input_lang[data-target-id="meta_description"]').each(function() {
                if($(this).is(':visible')) {
                    meta_description = $(this).val();
                }
            });
        }
        if(meta_description=='') {
            if(window.description_meta_default=='') {
                $('.facebook-preview__description').html('');
            } else {
                $('.facebook-preview__description').html(description_meta_default);
            }
        } else {
            $('.facebook-preview__description').html(meta_description);
        }
    }

    window.save_metadata = function(type,id) {
        var meta_title = $('#meta_title').val();
        var meta_description = $('#meta_description').val();
        var array_lang = {};
        array_lang['meta_title'] = {};
        $('.input_lang[data-target-id="meta_title"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['meta_title'][lang]=value;
        });
        array_lang['meta_description'] = {};
        $('.input_lang[data-target-id="meta_description"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['meta_description'][lang]=value;
        });
        var array_lang_json = JSON.stringify(array_lang);
        $.ajax({
            url: 'ajax/save_metadata.php',
            type: "POST",
            data: {
                type: type,
                id: id,
                meta_title: meta_title,
                meta_description: meta_description,
                meta_image: window.image_meta,
                array_lang: array_lang_json
            },
            async: true,
            success: function (json) {}
        })
    }

    window.set_status_map = function(status) {
        $.ajax({
            url: "ajax/set_status_map.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                status: status
            },
            async: true,
            success: function () {}
        });
    }

    window.open_qr_code_modal = function (link) {
        var qrcode_src = "https://api.qrserver.com/v1/create-qr-code/?size=400x400&data="+encodeURIComponent(link);
        $('#modal_qrcode').modal('show');
        $('#modal_qrcode i').show();
        $('#modal_qrcode img').hide();
        $('#modal_qrcode img').on("load", function() {
            $('#modal_qrcode i').hide();
            $('#modal_qrcode img').show();
        }).attr("src", qrcode_src);
    }

    window.get_current_position = function () {
        if ("geolocation" in navigator){
            $('#btn_get_position').addClass('disabled');
            $('#btn_get_position').html(window.backend_labels.searching+' ...');
            navigator.geolocation.getCurrentPosition(show_location, show_error, {timeout:10000, enableHighAccuracy: true}); //position request
        }
    }

    function show_location(position){
        $('#latitude_edit').val(position.coords.latitude);
        $('#longitude_edit').val(position.coords.longitude);
        $('#btn_get_position').removeClass('disabled');
        $('#btn_get_position').html(window.backend_labels.get_gps_position);
        set_marker_position();
    }

    function show_error(error){
        $('#btn_get_position').removeClass('disabled');
        $('#btn_get_position').html(window.backend_labels.get_gps_position);
        switch(error.code) {
            case error.PERMISSION_DENIED:
                alert("Permission denied by user.");
                break;
            case error.POSITION_UNAVAILABLE:
                alert("Location position unavailable.");
                break;
            case error.TIMEOUT:
                alert("Request timeout.");
                break;
            case error.UNKNOWN_ERROR:
                alert("Unknown error.");
                break;
        }
    }

    window.get_icon_images = function(id_map) {
        $.ajax({
            url: "ajax/get_icon_images.php",
            type: "POST",
            data: {
                id_map: id_map
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if(rsp.length>0) {
                    parse_icon_images(rsp);
                } else {
                    $('#list_images').html("<p>"+window.backend_labels.no_icon_msg+"</p>");
                }
            }
        });
    }

    window.get_media_library_files = function(id_map) {
        $.ajax({
            url: "ajax/get_media_library_files.php",
            type: "POST",
            data: {
                id_map: id_map,
                type: 'all'
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if(rsp.length>0) {
                    parse_media_library_files(rsp);
                } else {
                    $('#list_files').html("<p>"+window.backend_labels.no_files_msg+"</p>");
                }
            }
        });
    }

    function parse_media_library_files(files_array) {
        var html = '';
        window.media_library_files = files_array;
        jQuery.each(files_array, function(index, file_t) {
            var id = parseInt(file_t.id);
            var file = file_t.file;
            var from = file_t.from;
            var count = file_t.count;
            var id_map = file_t.id_map;
            switch(from) {
                case 'media_library':
                    var src = '../viewer/media/'+file;
                    var src_t = '../viewer/media/thumb/'+file;
                    break;
                case 'marker_images':
                    var src = '../viewer/marker_images/'+file;
                    var src_t = '../viewer/marker_images/thumb/'+file;
                    break;
            }
            if(file.includes('.mp4') || file.includes('.mov') || file.includes('.webm')) {
                var icon = '<span class="icon_type"><i class="fa fa-video"></i> '+count+'</span>';
                var html_file = '<video draggable="false" preload="auto" height="100px" src="'+src+'#t=2" playsinline webkit-playsinline autoplay loop muted style="height: 100px;"></video>';
            } else {
                var icon = '<span class="icon_type"><i class="fa fa-image"></i> '+count+'</span>';
                var html_file = '<img draggable="false" style="height: 100px;" src="'+src_t+'" onerror="this.src=\''+src+'\';this.onerror=\'\';" />';
            }
            if(id==0 || count>0 || window.id_map!=id_map) {
                html += '<div style="display:inline-block;position:relative;vertical-align:top;" class="file_media_library mb-2 ml-1 mr-1"><div class="preview_content_btn"><a target="_blank" href="'+src+'"><i class="fas fa-external-link"></i></a></div>'+icon+''+html_file+'</div>';
            } else {
                html += '<div style="display:inline-block;position:relative;vertical-align:top;" class="file_media_library mb-2 ml-1 mr-1">'+icon+'<div class="remove_file_media_library"><i onclick="remove_media_library_file('+id+');" style="font-size: 22px;color: white;cursor: pointer" class="fas fa-trash-alt"></i></div><div class="preview_content_btn"><a target="_blank" href="'+src+'"><i class="fas fa-external-link"></i></a></div>'+html_file+'</div>';
            }
        });
        $('#list_files').html(html).promise().done(function () {
            $("#list_files img").each(function(){
                var image = $(this);
                if(image.context.naturalWidth == 0 || image.readyState == 'uninitialized'){
                    $(image).parent().hide();
                }
            });
        });
    }

    window.open_modal_media_library = function (type) {
        $('#modal_media_library .modal-body').empty();
        $('#modal_media_library').modal('show');
        $.ajax({
            url: "ajax/get_media_library_files.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                type: type
            },
            async: true,
            success: function (json) {
                var html = '';
                var files_array = JSON.parse(json);
                if(files_array.length==0) {
                    html = "<p>"+window.backend_labels.no_files_msg+"</p>";
                } else {
                    jQuery.each(files_array, function(index, file_t) {
                        var file = file_t.file;
                        var from = file_t.from;
                        var id_map = file_t.id_map;
                        switch(from) {
                            case 'media_library':
                                var src = '../viewer/media/'+file;
                                var src_t = '../viewer/media/thumb/'+file;
                                break;
                            case 'marker_images':
                                var src = '../viewer/marker_images/'+file;
                                var src_t = '../viewer/marker_images/thumb/'+file;
                                break;
                        }
                        if(file.includes('.mp4') || file.includes('.mov') || file.includes('.webm')) {
                            var html_file = '<video preload="auto" src="'+src+'#t=2" playsinline webkit-playsinline muted style="height: 100px;"></video>';
                        } else {
                            var html_file = '<img style="height: 100px;" src="'+src_t+'" onerror="this.src=\''+src+'\';this.onerror=\'\';" />';
                        }
                        html += '<div onclick="select_media_library_file(\''+file+'\',\''+type+'\',\''+from+'\',\'\',\''+id_map+'\');" style="display:inline-block;position:relative;vertical-align:top;cursor:pointer;" class="file_media_library mb-2 ml-1 mr-1">'+html_file+'</div>';
                    });
                }
                $('#modal_media_library .modal-body').html(html);
            }
        });
    }

    window.select_media_library_file = function(file,type,from,target,id_map) {
        switch(from) {
            case 'media_library':
                var src = 'media/'+file;
                break;
            case 'marker_images':
                var src = 'marker_images/'+file;
                break;
        }
        marker_images_uploaded++;
        var count_images = $('#image_gallery a[data-main="1"]').length;
        if(count_images==0) {
            var main = '1';
            var icon_main = '<i style="display:block;" class="fas fa-star"></i>';
            $("#image_gallery a i.fa-star").hide();
        } else {
            var main = '0';
            var icon_main = '<i style="display:none;" class="fas fa-star"></i>';
        }
        var icon_gps = '<i style="display:none;" class="fas fa-location"></i>';
        var type = getMediaType(file);
        switch(type) {
            case 'image':
                $('#image_gallery').append("<a data-id='0' data-lat='' data-lon='' data-exclude='0' data-action='insert' data-image='"+file+"' data-main='"+main+"' href='#'><i class=\"fa-solid fa-image\"></i>"+icon_main+icon_gps+"<img src='../viewer/"+src+"'/></a>");
                break;
            case 'video':
                $('#image_gallery').append("<a data-id='0' data-lat='' data-lon='' data-exclude='0' data-action='insert' data-image='"+file+"' data-main='"+main+"' href='#'><i class=\"fa-solid fa-video\"></i>"+icon_main+icon_gps+"<video muted src='../viewer/"+src+"#t=2'/></a>");
                break;
        }
        var el = document.getElementById('image_gallery');
        Sortable.create(el);
        $('#image_gallery a').on('click',function () {
            event.preventDefault();
            select_image($(this));
        });
        window.marker_need_save = true;
        $('#modal_media_library').modal('hide');
    }

    window.add_file_to_media_library = function(id_map,file) {
        $.ajax({
            url: "ajax/add_file_to_media_library.php",
            type: "POST",
            data: {
                id_map: id_map,
                file: file
            },
            async: true,
            success: function (json) {
                get_media_library_files(id_map);
            }
        });
    }

    window.remove_media_library_file = function(id) {
        var retVal = confirm(window.backend_labels.delete_sure_msg);
        if( retVal == true ) {
            $.ajax({
                url: "ajax/delete_file_to_media_library.php",
                type: "POST",
                data: {
                    id: id
                },
                async: false,
                success: function (json) {
                    get_media_library_files(window.id_map);
                }
            });
        } else {
            return false;
        }
    }

    function parse_icon_images(images_array) {
        var html = '';
        jQuery.each(images_array, function(index, image) {
            var id = image.id;
            var id_map = image.id_map;
            var image = image.image;
            if(window.id_map!=id_map) {
                html += '<div data-id="'+id+'" style="position: relative;pointer-events: none;" class="image_icon float-left mb-2 ml-1 mr-1"><img style="height: 100px;" src="../viewer/icons/'+image+'" /></div>';
            } else {
                html += '<div data-id="'+id+'" style="position: relative" class="image_icon float-left mb-2 ml-1 mr-1"><div class="remove_image_icon"><i onclick="remove_image_icon('+id+');" style="font-size: 24px;color: white" class="fas fa-trash-alt"></i></div><img style="height: 100px;" src="../viewer/icons/'+image+'" /></div>';
            }
        });
        $('#list_images').html(html).promise().done(function () {

        });
    }

    window.delete_live_tracking = function(id) {
        var retVal = confirm(window.backend_labels.delete_msg);
        if( retVal == true ) {
            $.ajax({
                url: "ajax/delete_live_tracking.php",
                type: "POST",
                data: {
                    id: id,
                    id_map: window.id_map
                },
                async: false,
                success: function () {
                    location.reload();
                }
            });
        } else {
            return false;
        }
    }

    window.remove_image_icon = function(id) {
        var retVal = confirm(window.backend_labels.delete_msg);
        if( retVal == true ) {
            $.ajax({
                url: "ajax/delete_image_to_icon.php",
                type: "POST",
                data: {
                    id: id
                },
                async: false,
                success: function (json) {
                    get_icon_images(window.id_map);
                }
            });
        } else {
            return false;
        }
    }

    window.add_image_to_icon = function(id_map,image) {
        $.ajax({
            url: "ajax/add_image_to_icon.php",
            type: "POST",
            data: {
                id_map: id_map,
                image: image
            },
            async: true,
            success: function (json) {
                get_icon_images(id_map);
            }
        });
    }

    window.select_icon_library = function(id,image) {
        $('#marker_library_icon').val(id);
        $('#marker_library_icon_preview').attr('src','../viewer/icons/'+image);
        $('#marker_library_icon_preview').show();
        $('#modal_library_icons').modal('hide');
        $('#color_hex').parent().parent().addClass("disabled");
        $('#icon_color_hex').parent().parent().addClass("disabled");
        change_style_marker();
    }

    window.select_icon_library_c = function(id,image) {
        $('#marker_library_icon_c').val(id);
        $('#marker_library_icon_preview_c').attr('src','../viewer/icons/'+image);
        $('#marker_library_icon_preview_c').show();
        $('#modal_library_icons_c').modal('hide');
        $('#color_hex_c').parent().parent().addClass("disabled");
        $('#icon_color_hex_c').parent().parent().addClass("disabled");
    }

    window.select_icon_library_pin = function(id,image) {
        $('#marker_library_icon_pin').val(id);
        $('#marker_library_icon_preview_pin').attr('src','../viewer/icons/'+image);
        $('#marker_library_icon_preview_pin').show();
        $('#modal_library_icons_pin').modal('hide');
    }

    window.remove_icon_library = function() {
        $('#marker_library_icon').val(0);
        $('#marker_library_icon_preview').attr('src','');
        $('#marker_library_icon_preview').hide();
        $('#modal_library_icons').modal('hide');
        $('#color_hex').parent().parent().removeClass("disabled");
        $('#icon_color_hex').parent().parent().removeClass("disabled");
        $('#GetIconPicker').parent().removeClass("disabled");
    }

    window.set_password_map = function() {
        var password = $('#map_password').val();
        $('#btn_protect').addClass('disabled');
        $.ajax({
            url: "ajax/set_password_map.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                password: password
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                $('#btn_protect').removeClass('disabled');
            }
        });
    }

    window.delete_review = function (id) {
        var answer = window.confirm(window.backend_labels.delete_msg);
        if (answer) {
            $.ajax({
                url: "ajax/delete_review.php",
                type: "POST",
                data: {
                    id: id,
                    id_map: window.id_map,
                },
                async: true,
                success: function (json) {
                    $('#reviews_table').DataTable().ajax.reload(null, false);
                }
            });
        }
    }

    window.check_issue_report = function (id) {
        var answer = window.confirm(window.backend_labels.check_msg);
        if (answer) {
            $.ajax({
                url: "ajax/check_issue_report.php",
                type: "POST",
                data: {
                    id: id,
                    id_map: window.id_map,
                },
                async: true,
                success: function (json) {
                    $('#issue_reports_table').DataTable().ajax.reload(null, false);
                }
            });
        }
    }

    window.open_reply_review = function (id) {
        window.id_review_sel = id;
        var comment = $('#comment_'+id).html();
        var reply = $('#reply_'+id).html();
        $('#comment_modal').html(comment);
        $('#reply_modal').val(reply);
        $('#modal_reply').modal('show');
    }

    window.save_reply_review = function () {
        $('#modal_reply button').addClass('disabled');
        var reply = $('#reply_modal').val();
        $.ajax({
            url: "ajax/save_reply_review.php",
            type: "POST",
            data: {
                id: window.id_review_sel,
                id_map: window.id_map,
                reply: reply
            },
            async: true,
            success: function (json) {
                $('#modal_reply').modal('hide');
                $('#modal_reply button').removeClass('disabled');
                $('#reviews_table').DataTable().ajax.reload(null, false);
            },
            error: function() {
                $('#modal_reply button').removeClass('disabled');
            }
        });
    }

    window.get_statistics = function (elem) {
        $.ajax({
            url: "ajax/get_statistics.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                elem: elem
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if($('body').hasClass('dark_mode')) {
                    var label_color = '#FFFFFFA8';
                } else {
                    var label_color = '';
                }
                switch (elem) {
                    case 'map_country':
                        $('#map_country').find('.map-loader').remove();
                        $('#map_country').empty();
                        var rawVisitsData = rsp;
                        let totalVisits = 0;
                        for (let country in rawVisitsData) {
                            totalVisits += rawVisitsData[country];
                        }
                        const percentageData = {};
                        for (let country in rawVisitsData) {
                            percentageData[country] = ((rawVisitsData[country] / totalVisits) * 100).toFixed(1);
                        }
                        let mapColorsData = { ...rawVisitsData };
                        let dataValues = Object.values(mapColorsData);
                        if (dataValues.length > 0) {
                            let maxVal = Math.max(...dataValues);
                            let minVal = Math.min(...dataValues);
                            if (maxVal === minVal) {
                                mapColorsData['FAKE_COUNTRY'] = maxVal === 0 ? 1 : 0;
                            }
                        }
                        let isDark = $('body').hasClass('dark_mode');
                        let regionFill = isDark ? '#DCDFE0' : '#E1E3E5';
                        let regionStroke = isDark ? '#C0C6D1' : '#A1A2A6';
                        let scaleColors = isDark
                            ? ['#60a5fa', '#1e3a8a']
                            : ['#dbeafe', '#2563eb'];
                        new jsVectorMap({
                            selector: '#map_country',
                            map: 'world',
                            backgroundColor: 'transparent',
                            zoomOnScroll: false,
                            regionStyle: {
                                initial: {
                                    fill: regionFill,
                                    stroke: regionStroke,
                                    strokeWidth: 0.1,
                                    fillOpacity: 1
                                },
                                hover: {
                                    fillOpacity: 0.8,
                                    cursor: 'pointer'
                                }
                            },
                            visualizeData: {
                                scale: scaleColors,
                                values: mapColorsData
                            },
                            onRegionTooltipShow(event, tooltip, code) {
                                const percentage = percentageData[code] || 0;
                                const countryName = tooltip.text();
                                const tooltipElement = tooltip.getElement();
                                if (percentage > 0) {
                                    tooltipElement.innerHTML =
                                        `<div style="text-align: center;">
                                            <strong style="display:block; margin-bottom:4px; color:#93c5fd;">${countryName}</strong>
                                            <span style="display:block; font-size:1.25rem; font-weight:bold; color:#ffffff;">${percentage}%</span>
                                        </div>`;
                                } else {
                                    tooltipElement.innerHTML =
                                        `<div style="text-align: center;">
                                            <strong style="display:block; color:#9ca3af;">${countryName}</strong>
                                            <span style="display:block; font-size:0.875rem; margin-top:4px; color:#6b7280;">0%</span>
                                        </div>`;
                                }
                            }
                        });
                        break;
                    case 'chart_visitor_map':
                        var data = rsp.data;
                        if($('body').hasClass('dark_mode')) {
                            Highcharts.stockChart('chart_visitor_map', {
                                tooltip: {
                                    backgroundColor: 'rgba(0, 0, 0, 0.85)',
                                    style: {
                                        color: '#F0F0F0'
                                    },
                                    xDateFormat: '%e %B %Y',
                                    pointFormatter: function() {
                                        var point = this;
                                        return '<span style="color:' + point.color + '">\u25CF</span> <b>' + point.y.toFixed(0) + '</b>';
                                    }
                                },
                                xAxis: {
                                    gridLineColor: '#707073',
                                    labels: {
                                        style: {
                                            color: '#E0E0E3'
                                        }
                                    },
                                    lineColor: '#707073',
                                    minorGridLineColor: '#505053',
                                    tickColor: '#707073',
                                    title: {
                                        style: {
                                            color: '#A0A0A3'
                                        }
                                    },
                                    reversed: (window.rtl==1) ? true : false
                                },
                                yAxis: {
                                    gridLineColor: '#707073',
                                    labels: {
                                        style: {
                                            color: '#E0E0E3'
                                        }
                                    },
                                    lineColor: '#707073',
                                    minorGridLineColor: '#505053',
                                    tickColor: '#707073',
                                    tickWidth: 1,
                                    title: {
                                        style: {
                                            color: '#A0A0A3'
                                        }
                                    },
                                    opposite: (window.rtl==1) ? true : false
                                },
                                chart: {
                                    backgroundColor: {
                                        linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
                                        stops: [
                                            [0, '#2a2a2b'],
                                            [1, '#3e3e40']
                                        ]
                                    },
                                    plotBorderColor: '#606063',
                                    height: 400,
                                    rtl: (window.rtl==1) ? true : false
                                },
                                title: {
                                    text: ''
                                },
                                subtitle: {
                                    text: ''
                                },
                                rangeSelector: {
                                    buttonTheme: {
                                        fill: '#505053',
                                        stroke: '#000000',
                                        style: {
                                            color: '#CCC'
                                        },
                                        states: {
                                            hover: {
                                                fill: '#707073',
                                                stroke: '#000000',
                                                style: {
                                                    color: 'white'
                                                }
                                            },
                                            select: {
                                                fill: '#000003',
                                                stroke: '#000000',
                                                style: {
                                                    color: 'white'
                                                }
                                            }
                                        }
                                    },
                                    inputBoxBorderColor: '#505053',
                                    inputStyle: {
                                        backgroundColor: '#333',
                                        color: 'silver'
                                    },
                                    labelStyle: {
                                        color: 'silver'
                                    },
                                    inputDateFormat: '%d/%m/%Y',
                                    selected: 4,
                                    buttons: [{
                                        type: 'day',
                                        count: 7,
                                        text: '1W',
                                    },{
                                        type: 'month',
                                        count: 1,
                                        text: '1M',
                                    }, {
                                        type: 'month',
                                        count: 3,
                                        text: '3M'
                                    }, {
                                        type: 'month',
                                        count: 6,
                                        text: '6M'
                                    }, {
                                        type: 'year',
                                        count: 1,
                                        text: '1A'
                                    }, {
                                        type: 'all',
                                        text: 'ALL'
                                    }]
                                },
                                credits: {
                                    style: {
                                        color: '#2a2a2b'
                                    }
                                },
                                labels: {
                                    style: {
                                        color: '#707073'
                                    }
                                },
                                drilldown: {
                                    activeAxisLabelStyle: {
                                        color: '#F0F0F3'
                                    },
                                    activeDataLabelStyle: {
                                        color: '#F0F0F3'
                                    }
                                },
                                navigation: {
                                    buttonOptions: {
                                        symbolStroke: '#DDDDDD',
                                        theme: {
                                            fill: '#505053'
                                        }
                                    }
                                },
                                navigator: {
                                    handles: {
                                        backgroundColor: '#666',
                                        borderColor: '#AAA'
                                    },
                                    outlineColor: '#CCC',
                                    maskFill: 'rgba(255,255,255,0.1)',
                                    series: {
                                        color: '#7798BF',
                                        lineColor: '#A6C7ED'
                                    },
                                    xAxis: {
                                        gridLineColor: '#505053'
                                    }
                                },
                                scrollbar: {
                                    barBackgroundColor: '#808083',
                                    barBorderColor: '#808083',
                                    buttonArrowColor: '#CCC',
                                    buttonBackgroundColor: '#606063',
                                    buttonBorderColor: '#606063',
                                    rifleColor: '#FFF',
                                    trackBackgroundColor: '#404043',
                                    trackBorderColor: '#404043'
                                },
                                plotOptions: {
                                    series: {
                                        color: window.theme_color,
                                        dataGrouping: {
                                            approximation: "sum",
                                            units: [
                                                ['day', [1]],
                                                ['week', [1]],
                                                ['month', [1]],
                                            ],
                                            groupPixelWidth: 100
                                        }
                                    }
                                },
                                series: [{
                                    name: '',
                                    data: data,
                                    type: 'areaspline',
                                    threshold: null,
                                    tooltip: {
                                        valueDecimals: 0
                                    }
                                }],
                                responsive: {
                                    rules: [{
                                        condition: {
                                            maxWidth: 500
                                        },
                                        chartOptions: {
                                            chart: {
                                                height: 300
                                            },
                                            subtitle: {
                                                text: null
                                            },
                                            navigator: {
                                                enabled: false
                                            }
                                        }
                                    }]
                                }
                            });
                        } else {
                            Highcharts.stockChart('chart_visitor_map', {
                                tooltip: {
                                    xDateFormat: '%e %B %Y',
                                    pointFormatter: function() {
                                        var point = this;
                                        return '<span style="color:' + point.color + '">\u25CF</span> <b>' + point.y.toFixed(0) + '</b>';
                                    }
                                },
                                xAxis: {
                                    reversed: (window.rtl==1) ? true : false
                                },
                                yAxis: {
                                    opposite: (window.rtl==1) ? true : false
                                },
                                chart: {
                                    height: 400,
                                    rtl: (window.rtl==1) ? true : false
                                },
                                title: {
                                    text: ''
                                },
                                subtitle: {
                                    text: ''
                                },
                                rangeSelector: {
                                    inputDateFormat: '%d/%m/%Y',
                                    selected: 4,
                                    buttons: [{
                                        type: 'day',
                                        count: 7,
                                        text: '1W',
                                    },{
                                        type: 'month',
                                        count: 1,
                                        text: '1M',
                                    }, {
                                        type: 'month',
                                        count: 3,
                                        text: '3M'
                                    }, {
                                        type: 'month',
                                        count: 6,
                                        text: '6M'
                                    }, {
                                        type: 'year',
                                        count: 1,
                                        text: '1A'
                                    }, {
                                        type: 'all',
                                        text: 'ALL'
                                    }]
                                },
                                plotOptions: {
                                    series: {
                                        color: window.theme_color,
                                        dataGrouping: {
                                            approximation: "sum",
                                            units: [
                                                ['day', [1]],
                                                ['week', [1]],
                                                ['month', [1]],
                                            ],
                                            groupPixelWidth: 100
                                        }
                                    }
                                },
                                series: [{
                                    name: '',
                                    data: data,
                                    type: 'areaspline',
                                    threshold: null,
                                    tooltip: {
                                        valueDecimals: 0
                                    }
                                }],
                                responsive: {
                                    rules: [{
                                        condition: {
                                            maxWidth: 500
                                        },
                                        chartOptions: {
                                            chart: {
                                                height: 300
                                            },
                                            subtitle: {
                                                text: null
                                            },
                                            navigator: {
                                                enabled: false
                                            }
                                        }
                                    }]
                                }
                            });
                        }
                        break;
                    case 'chart_marker_views':
                        var total_access = rsp.total_markers;
                        var html_markers = '';
                        jQuery.each(rsp.markers, function(index, marker) {
                            var name = marker.name;
                            if(window.id_map=='all') {
                                name = marker.map_name+" - "+name;
                            }
                            var count = marker.access_count;
                            var perc = count / total_access * 100;
                            perc = Math.round(perc);
                            html_markers += '<h4 style="margin-bottom:1px;" class="small font-weight-bold">'+name+' <span class="float-right"><b>'+count+'</b>/'+total_access+'</span></h4>\n' +
                                '                <div class="progress mb-2">\n' +
                                '                    <div class="progress-bar bg-primary" role="progressbar" style="width: '+perc+'%" aria-valuenow="'+perc+'" aria-valuemin="0" aria-valuemax="100"></div>\n' +
                                '                </div>';
                        });
                        $('#chart_marker_views').html(html_markers);
                        break;
                }
            }
        });
    }

    window.delete_b_bg = function () {
        window.b_background_image = '';
        window.settings_need_save = true;
        $('#div_delete_bg').hide();
        $('#div_image_bg').hide();
        $('#div_upload_bg').show();
        $('#div_image_bg img').attr('src','');
    }

    window.delete_b_logo = function () {
        window.b_logo_image = '';
        window.settings_need_save = true;
        $('#div_delete_logo').hide();
        $('#div_image_logo').hide();
        $('#div_upload_logo').show();
        $('#div_image_logo img').attr('src','');
    }

    window.set_session_theme_color = function(theme_color,sidebar_color_1,sidebar_color_2,theme_color_dark,sidebar_color_1_dark,sidebar_color_2_dark) {
        if(theme_color!='') {
            $.ajax({
                url: "ajax/set_session_theme_color.php",
                type: "POST",
                data: {
                    theme_color: theme_color,
                    sidebar_color_1: sidebar_color_1,
                    sidebar_color_2: sidebar_color_2,
                    theme_color_dark: theme_color_dark,
                    sidebar_color_1_dark: sidebar_color_1_dark,
                    sidebar_color_2_dark: sidebar_color_2_dark
                },
                async: true,
                success: function (json) {
                    var current_href = $('#css_theme').attr("href").split('?')[0];
                    $('#css_theme').attr("href", current_href + "?v=" + new Date().getMilliseconds());
                    var current_href = $('#css_theme_dark').attr("href").split('?')[0];
                    $('#css_theme_dark').attr("href", current_href + "?v=" + new Date().getMilliseconds());
                }
            });
        }
    }

    window.switch_language = function (lang) {
        $.ajax({
            url: "ajax/switch_language.php",
            type: "POST",
            data: {
                lang: lang
            },
            async: false,
            success: function () {
                location.reload();
            }
        });
    }

    window.save_settings = function (validate_mail) {
        var complete = true;
        var name = $('#name').val();
        var theme_color = $('#theme_color').val();
        var sidebar = $('#sidebar option:selected').attr('id');
        var font_provider = $('#font_provider option:selected').attr('id');
        var sidebar_color_1 = $('#sidebar_color_1').val();
        var sidebar_color_2 = $('#sidebar_color_2').val();
        var theme_color_dark = $('#theme_color_dark').val();
        var dark_mode = parseInt($('#dark_mode option:selected').attr('id'));
        var sidebar_color_1_dark = $('#sidebar_color_1_dark').val();
        var sidebar_color_2_dark = $('#sidebar_color_2_dark').val();
        if(font_provider=='systems') {
            var font_backend = $('#font_backend_system option:selected').attr('id');
        } else {
            var font_backend = $('#font_backend').val();
        }
        var welcome_msg = window.welcome_msg_editor.root.innerHTML;
        var timezone = $('#timezone').val();
        var language = $('#language option:selected').attr('id');
        var language_domain = $('#language_domain option:selected').attr('id');
        var languages_enabled_t = $('#languages_enabled option');
        var languages_enabled = {};
        $(languages_enabled_t).each(function(index, elem){
            var id = $(this).attr('id').replace('ls_','');
            if($(this).is(':selected')) {
                languages_enabled[id]=1;
            } else {
                languages_enabled[id]=0;
            }
        });
        var languages_enabled_json = JSON.stringify(languages_enabled);
        var css_array = {};
        $(".editors_css").each(function() {
            var id = $(this).attr('id');
            css_array[id]=window.editors_css[id].getValue();
        });
        var js_array = {};
        $(".editors_js").each(function() {
            var id = $(this).attr('id');
            js_array[id.replace("_js","")]=window.editors_js[id].getValue();
        });
        var head_array = {};
        $(".editors_head").each(function() {
            var id = $(this).attr('id');
            head_array[id.replace("_head","")]=window.editors_head[id].getValue();
        });
        var css_array_json = JSON.stringify(css_array);
        var js_array_json = JSON.stringify(js_array);
        var head_array_json = JSON.stringify(head_array);
        var footer_link_1 = $('#footer_link_1').val();
        var footer_link_2 = $('#footer_link_2').val();
        var footer_link_3 = $('#footer_link_3').val();
        var footer_value_1 = window.footer_value_1.root.innerHTML;
        var footer_value_2 = window.footer_value_2.root.innerHTML;
        var footer_value_3 = window.footer_value_3.root.innerHTML;
        var style_login = $('#style_login option:selected').attr('id');
        var openrouteservice_api_key = $('#openrouteservice_api_key').val();
        var share_providers_t = $('#share_providers option');
        var share_providers = '';
        $(share_providers_t).each(function(index, elem){
            var id = $(this).attr('id');
            if(id !== undefined) {
                id = id.replace('provider_','');
                if($(this).is(':selected')) {
                    share_providers = share_providers+id+',';
                }
            }
        });
        if(share_providers!='') {
            share_providers = share_providers.substring(0,share_providers.length-1);
        }
        var terms_and_conditions = window.terms_and_conditions_editor.root.innerHTML;
        var privacy_policy = window.privacy_policy_editor.root.innerHTML;
        var cookie_policy = window.cookie_policy_editor.root.innerHTML;
        var cookie_consent = ($('#cookie_consent').is(':checked')) ? 1 : 0;
        var ga_tracking_id = $('#ga_tracking_id').val();
        var furl_blacklist = $('#furl_blacklist').val();
        var id_map_template = $('#id_map_template option:selected').attr('id');
        var geocoding_provider = $('#geocoding_provider option:selected').attr('id');
        var google_api_key = $('#google_api_key').val();
        var tripadvisor_api_key = $('#tripadvisor_api_key').val();
        var pwa_enable = ($('#pwa_enable').is(':checked')) ? 1 : 0;
        var enable_deepl = ($('#enable_deepl').is(':checked')) ? 1 : 0;
        var deepl_api_key = $('#deepl_api_key').val();
        var smtp_server = $('#smtp_server').val();
        var smtp_port = $('#smtp_port').val();
        var smtp_auth = ($('#smtp_auth').is(':checked')) ? 1 : 0;
        var smtp_secure = $('#smtp_secure option:selected').attr('id');
        var smtp_username = $('#smtp_username').val();
        var smtp_password = $('#smtp_password').val();
        var smtp_from_email = $('#smtp_from_email').val();
        var smtp_from_name = $('#smtp_from_name').val();
        var mail_forgot_subject = $('#mail_forgot_subject').val();
        var mail_forgot_body = window.mail_forgot_body_editor.root.innerHTML;
        var notify_email = $('#notify_email').val();
        var notify_marker_to_validate = ($('#notify_marker_to_validate').is(':checked') && !$('#notify_marker_to_validate').is(':disabled')) ? 1 : 0;
        var notify_review = ($('#notify_review').is(':checked') && !$('#notify_review').is(':disabled')) ? 1 : 0;
        var notify_issue_report = ($('#notify_issue_report').is(':checked') && !$('#notify_issue_report').is(':disabled')) ? 1 : 0;
        var notify_photo_to_validate = ($('#notify_photo_to_validate').is(':checked') && !$('#notify_photo_to_validate').is(':disabled')) ? 1 : 0;
        var validate_email = ($('#validate_email').is(':checked') && !$('#validate_email').is(':disabled')) ? 1 : 0;
        var mail_activate_subject = $('#mail_activate_subject').val();
        var mail_activate_body = window.mail_activate_body_editor.root.innerHTML;
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        if((!mail_forgot_body.includes('%LINK%')) || (!mail_forgot_body.includes('%VERIFICATION_CODE%'))) {
            complete = false;
            $('#mail_forgot_body').addClass("error-highlight");
        } else {
            $('#mail_forgot_body').removeClass("error-highlight");
        }
        if(!mail_activate_body.includes('%LINK%')) {
            complete = false;
            $('#mail_activate_body').addClass("error-highlight");
        } else {
            $('#mail_activate_body').removeClass("error-highlight");
        }
        if(complete) {
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            $.ajax({
                url: "ajax/save_settings.php",
                type: "POST",
                data: {
                    name: name,
                    theme_color: theme_color,
                    theme_color_dark: theme_color_dark,
                    dark_mode: dark_mode,
                    sidebar: sidebar,
                    sidebar_color_1: sidebar_color_1,
                    sidebar_color_2: sidebar_color_2,
                    sidebar_color_1_dark: sidebar_color_1_dark,
                    sidebar_color_2_dark: sidebar_color_2_dark,
                    font_provider: font_provider,
                    font_backend: font_backend,
                    welcome_msg: welcome_msg,
                    logo: window.b_logo_image,
                    background: window.b_background_image,
                    background_reg: window.b_background_reg_image,
                    timezone: timezone,
                    language: language,
                    language_domain: language_domain,
                    languages_enabled: languages_enabled_json,
                    css_array: css_array_json,
                    js_array: js_array_json,
                    head_array: head_array_json,
                    footer_link_1: footer_link_1,
                    footer_link_2: footer_link_2,
                    footer_link_3: footer_link_3,
                    footer_value_1: footer_value_1,
                    footer_value_2: footer_value_2,
                    footer_value_3: footer_value_3,
                    style_login: style_login,
                    openrouteservice_api_key: openrouteservice_api_key,
                    share_providers: share_providers,
                    terms_and_conditions: terms_and_conditions,
                    privacy_policy: privacy_policy,
                    ga_tracking_id: ga_tracking_id,
                    cookie_policy: cookie_policy,
                    cookie_consent: cookie_consent,
                    furl_blacklist: furl_blacklist,
                    id_map_template: id_map_template,
                    geocoding_provider: geocoding_provider,
                    google_api_key: google_api_key,
                    tripadvisor_api_key: tripadvisor_api_key,
                    pwa_enable: pwa_enable,
                    enable_deepl: enable_deepl,
                    deepl_api_key: deepl_api_key,
                    smtp_server: smtp_server,
                    smtp_port: smtp_port,
                    smtp_secure: smtp_secure,
                    smtp_auth: smtp_auth,
                    smtp_username: smtp_username,
                    smtp_password: smtp_password,
                    smtp_from_email: smtp_from_email,
                    smtp_from_name: smtp_from_name,
                    mail_forgot_subject: mail_forgot_subject,
                    mail_forgot_body: mail_forgot_body,
                    notify_email: notify_email,
                    notify_marker_to_validate: notify_marker_to_validate,
                    notify_review: notify_review,
                    notify_issue_report: notify_issue_report,
                    notify_photo_to_validate: notify_photo_to_validate,
                    validate_email: validate_email,
                    mail_activate_subject: mail_activate_subject,
                    mail_activate_body: mail_activate_body
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        if(rsp.favicon!=1) {
                            generate_favicons(rsp.favicon);
                        }
                        edit_all_categories();
                        window.settings_need_save = false;
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                            $('#save_btn').removeClass("disabled");
                        }, 1000);
                        if(window.current_language!=language) {
                            location.reload();
                        }
                        if(validate_mail) {
                            $('#btn_validate_mail').addClass("disabled");
                            $.ajax({
                                url: "ajax/send_email.php",
                                type: "POST",
                                data: {
                                    type: 'validate',
                                    email: smtp_from_email
                                },
                                async: true,
                                success: function (json) {
                                    var rsp = JSON.parse(json);
                                    if (rsp.status == "ok") {
                                        $('#validate_mail').html('<i style="color: green" class="fas fa-circle"></i> Valid');
                                        $('#notify_marker_to_validate,#notify_review,#notify_issue_report,#notify_photo_to_validate,#validate_email').prop('disabled',false);
                                    } else {
                                        $('#validate_mail').html('<i style="color: red" class="fas fa-circle"></i> Invalid');
                                        $('#notify_marker_to_validate,#notify_review,#notify_issue_report,#notify_photo_to_validate,#validate_email').prop('checked',false).prop('disabled',true);
                                        alert(rsp.msg);
                                    }
                                    $('#btn_validate_mail').removeClass("disabled");
                                },
                                error: function(){
                                    $('#validate_mail').html('<i style="color: red" class="fas fa-circle"></i> Invalid');
                                    $('#notify_marker_to_validate,#notify_review,#notify_issue_report,#notify_photo_to_validate,#validate_email').prop('checked',false).prop('disabled',true);
                                    $('#btn_validate_mail').removeClass("disabled");
                                }
                            });
                        }
                    } else {
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        }, 1000);
                    }
                }
            });
        }
    }

    window.save_profile = function(id_user_edit,complete_profile) {
        var complete = true;
        var username = $('#username').val();
        var email = $('#email').val();
        var language = $('#language option:selected').attr('id');
        if(username=='') {
            complete = false;
            $('#username').addClass("error-highlight");
        } else {
            $('#username').removeClass("error-highlight");
        }
        if(complete) {
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            $('#btn_save_continue_profile').addClass('disabled');
            $.ajax({
                url: "ajax/save_profile.php",
                type: "POST",
                data: {
                    id: id_user_edit,
                    username: username,
                    email: email,
                    language: language
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        window.user_need_save = false;
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                            $('#save_btn').removeClass("disabled");
                            if(rsp.reload_page==1) {
                                location.href = 'index.php?p=edit_profile';
                            }
                        },200);
                    } else {
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        }, 1000);
                    }
                }
            });
        }
    }

    window.change_markers_size = function () {
        var markers_size = $('#markers_size').val();
        $('#markers_size_value').html(markers_size);
    }

    window.change_pin_marker_size = function () {
        var marker_size = $('#pin_marker_size').val();
        $('#pin_marker_size_value').html(marker_size);
    }

    window.change_search_radius_m = function () {
        var radius = $('#search_radius_m').val();
        var unit = $('#unit_map option:selected').attr('id');
        if(radius<=0) {
            radius='<i class="fa-solid fa-infinity"></i>';
        } else {
            if(unit=='miles') {
                radius=((radius/1000)/1.609).toFixed(2)+" ml";
            } else {
                radius=(radius/1000)+" km";
            }
        }
        $('#search_radius_m_value').html(radius);
    }

    window.change_marker_size = function () {
        var marker_size = $('#marker_size').val();
        if(window.default_marker_size==marker_size) {
            $('#marker_size_value').html(marker_size+' default');
        } else {
            $('#marker_size_value').html(marker_size);
        }
        change_style_marker();
    }

    window.add_markers_connections = function () {
        var marker_source = $('#marker_source option:selected').attr('id');
        var marker_dest = $('#marker_dest option:selected').attr('id');
        var color = $('#color').val();
        var width = $('#width').val();
        var title = $('#title_mc').val();
        var description = window.editor_html_description.getValue();
        var array_lang = {};
        array_lang['title'] = {};
        $('.input_lang[data-target-id="title_mc"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['title'][lang]=value;
        });
        array_lang['description'] = {};
        $('.input_lang[data-target-id="description_mc"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_description_langs[lang].getValue();
            array_lang['description'][lang]=value;
        });
        if(marker_source!=undefined && marker_dest!=undefined && marker_source!=marker_dest) {
            $('#modal_add_markers_connections button').addClass("disabled");
            var array_lang_json = JSON.stringify(array_lang);
            $.ajax({
                url: "ajax/add_markers_connections.php",
                type: "POST",
                data: {
                    marker_source: marker_source,
                    marker_dest: marker_dest,
                    color: color,
                    width: width,
                    title: title,
                    description: description,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#modal_add_markers_connections button').removeClass("disabled");
                        $('#modal_add_markers_connections').modal("hide");
                        $('#markers_connections_table').DataTable().ajax.reload();
                        $('#title_mc').val('');
                        $('.input_lang[data-target-id="title_mc"]').each(function() {
                            $(this).val('');
                        });
                        window.editor_html_description.getSession().setValue('');
                        $('.input_lang[data-target-id="description_mc"]').each(function() {
                            var lang = $(this).attr('data-lang');
                            window.editor_html_description_langs[lang].getSession().setValue('');
                        });
                    } else {
                        $('#modal_add_markers_connections button').removeClass("disabled");
                    }
                }, error: function() {
                    $('#modal_add_markers_connections button').removeClass("disabled");
                }
            });
        }
    };

    window.add_markers_story = function () {
        var id_marker = $('#marker_story_add option:selected').attr('id');
        var zoom = $('#zoom_story_add option:selected').attr('id');
        var description = window.editor_html_description.getValue();
        var array_lang = {};
        array_lang['description'] = {};
        $('.input_lang[data-target-id="description_story"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_description_langs[lang].getValue();
            array_lang['description'][lang]=value;
        });
        if(id_marker!=undefined) {
            $('#modal_add_markers_story button').addClass("disabled");
            var array_lang_json = JSON.stringify(array_lang);
            $.ajax({
                url: "ajax/add_markers_story.php",
                type: "POST",
                data: {
                    id_map: window.id_map,
                    id_marker: id_marker,
                    zoom: zoom,
                    description: description,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#modal_add_markers_story button').removeClass("disabled");
                        $('#modal_add_markers_story').modal("hide");
                        $('#markers_story_table').DataTable().ajax.reload();
                        window.editor_html_description.getSession().setValue('');
                        $('.input_lang[data-target-id="description_story"]').each(function() {
                            var lang = $(this).attr('data-lang');
                            window.editor_html_description_langs[lang].getSession().setValue('');
                        });
                        get_markers_story_add();
                    } else {
                        $('#modal_add_markers_story button').removeClass("disabled");
                    }
                }, error: function() {
                    $('#modal_add_markers_story button').removeClass("disabled");
                }
            });
        }
    };

    window.delete_markers_connections = function (id) {
        var answer = window.confirm(window.backend_labels.delete_msg);
        if (answer) {
            $.ajax({
                url: "ajax/delete_markers_connections.php",
                type: "POST",
                data: {
                    id: id,
                    id_map: window.id_map,
                },
                async: true,
                success: function (json) {
                    $('#modal_edit_markers_connections button').removeClass("disabled");
                    $('#modal_edit_markers_connections').modal("hide");
                    $('#markers_connections_table').DataTable().ajax.reload();
                }
            });
        }
    }

    window.save_markers_connections = function (id) {
        var marker_source = $('#marker_source_edit option:selected').attr('id');
        var marker_dest = $('#marker_dest_edit option:selected').attr('id');
        var color = $('#color_edit').val();
        var width = $('#width_edit').val();
        var title = $('#title_mc_edit').val();
        var description = window.editor_html_description_edit.getValue();
        var array_lang = {};
        array_lang['title'] = {};
        $('.input_lang[data-target-id="title_mc_edit"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['title'][lang]=value;
        });
        array_lang['description'] = {};
        $('.input_lang[data-target-id="description_mc_edit"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_description_edit_langs[lang].getValue();
            array_lang['description'][lang]=value;
        });
        if(marker_source!=undefined && marker_dest!=undefined && marker_source!=marker_dest) {
            $('#modal_edit_markers_connections button').addClass("disabled");
            var array_lang_json = JSON.stringify(array_lang);
            $.ajax({
                url: "ajax/save_markers_connections.php",
                type: "POST",
                data: {
                    id: id,
                    marker_source: marker_source,
                    marker_dest: marker_dest,
                    color: color,
                    width: width,
                    title: title,
                    description: description,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#modal_edit_markers_connections button').removeClass("disabled");
                        $('#modal_edit_markers_connections').modal("hide");
                        $('#markers_connections_table').DataTable().ajax.reload();
                    } else {
                        $('#modal_edit_markers_connections button').removeClass("disabled");
                    }
                }, error: function() {
                    $('#modal_edit_markers_connections button').removeClass("disabled");
                }
            });
        }
    };

    window.get_markers_connection = function (id) {
        $('#modal_edit_markers_connections').modal('show');
        $.ajax({
            url: "ajax/get_markers_connection.php",
            type: "POST",
            data: {
                id: id,
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var id_marker_source = rsp.id_marker_source;
                var id_marker_dest = rsp.id_marker_dest;
                var color = rsp.color;
                var width = rsp.width;
                var title = rsp.title;
                var description = rsp.description;
                if(description==null) description="";
                $('#marker_source_edit option').prop('selected',false);
                $('#marker_source_edit option[id='+id_marker_source+']').prop('selected',true);
                $('#marker_source_edit').selectpicker('refresh');
                $('#marker_dest_edit option').prop('selected',false);
                $('#marker_dest_edit option[id='+id_marker_dest+']').prop('selected',true);
                $('#marker_dest_edit').selectpicker('refresh');
                $('#color_edit').val(color);
                $('#width_edit').val(width);
                $('#title_mc_edit').val(title);
                window.editor_html_description_edit.setValue(description,-1);
                $.each(rsp.array_lang,function(lang,array_lang) {
                    var title = array_lang['title'];
                    var description = array_lang['description'];
                    if(description==null) description="";
                    $('.input_lang[data-target-id="title_mc_edit"][data-lang="'+lang+'"]').val(title);
                    window.editor_html_description_edit_langs[lang].setValue(description,-1);
                });
                window.color_edit_spectrum = $('#color_edit').spectrum({
                    type: "text",
                    preferredFormat: "hex",
                    showAlpha: false,
                    showButtons: false,
                    allowEmpty: false
                });
                $('#btn_edit_markers_connections').attr('onclick','save_markers_connections('+id+')');
                $('#btn_delete_markers_connections').attr('onclick','delete_markers_connections('+id+')');
            }, error: function() {
                $('#modal_edit_markers_connections').modal('hide');
            }
        });
    };

    window.get_story = function(id) {
        $('#modal_edit_markers_story').modal('show');
        $.ajax({
            url: "ajax/get_story.php",
            type: "POST",
            data: {
                id: id,
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var zoom = rsp.zoom;
                var description = rsp.description;
                if(description==null) description="";
                $('#zoom_story_edit option').prop('selected', false);
                $('#zoom_story_edit option[id=' + zoom + ']').prop('selected', true);
                window.editor_html_description_edit.setValue(description, -1);
                $.each(rsp.array_lang,function(lang,array_lang) {
                    var description = array_lang['description'];
                    if(description==null) description="";
                    window.editor_html_description_edit_langs[lang].setValue(description,-1);
                });
                $('#btn_edit_markers_story').attr('onclick', 'save_markers_story('+id+')');
                $('#btn_delete_markers_story').attr('onclick', 'delete_markers_story('+id+')');
            }, error: function() {
                $('#modal_edit_markers_story').modal('hide');
            }
        });
    }

    window.delete_markers_story = function (id) {
        var answer = window.confirm(window.backend_labels.delete_msg);
        if (answer) {
            $.ajax({
                url: "ajax/delete_marker_story.php",
                type: "POST",
                data: {
                    id_map: window.id_map,
                    id: id
                },
                async: true,
                success: function (json) {
                    $('#modal_edit_markers_story button').removeClass("disabled");
                    $('#modal_edit_markers_story').modal("hide");
                    $('#markers_story_table').DataTable().ajax.reload();
                    get_markers_story_add();
                }
            });
        }
    };

    window.save_markers_story = function (id) {
        $('#modal_edit_markers_story button').addClass("disabled");
        var zoom = $('#zoom_story_edit option:selected').attr('id');
        var description = window.editor_html_description_edit.getValue();
        var array_lang = {};
        array_lang['description'] = {};
        $('.input_lang[data-target-id="description_story_edit"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_description_edit_langs[lang].getValue();
            array_lang['description'][lang]=value;
        });
        var array_lang_json = JSON.stringify(array_lang);
        $.ajax({
            url: "ajax/save_markers_story.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id: id,
                zoom: zoom,
                description: description,
                array_lang: array_lang_json
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_edit_markers_story button').removeClass("disabled");
                    $('#modal_edit_markers_story').modal("hide");
                    $('#markers_story_table').DataTable().ajax.reload();
                } else {
                    $('#modal_edit_markers_story button').removeClass("disabled");
                }
            }
        });
    };

    window.save_geodata_content = function (id) {
        $('#modal_geodata_content button').addClass("disabled");
        var content = window.geodata_content_editor.root.innerHTML;
        var array_lang = {};
        array_lang['content'] = {};
        $('.input_lang[data-target-id="geodata_content"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.geodata_content_editor_lang[lang].root.innerHTML;
            array_lang['content'][lang]=value;
        });
        var array_lang_json = JSON.stringify(array_lang);
        $.ajax({
            url: "ajax/save_geodata_content.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id: id,
                content: content,
                array_lang: array_lang_json
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_geodata_content button').removeClass("disabled");
                    $('#modal_geodata_content').modal("hide");
                    $('#geodata_table').DataTable().ajax.reload();
                } else {
                    $('#modal_geodata_content button').removeClass("disabled");
                }
            }
        });
    };

    window.check_license = function() {
        $('#btn_check_license').addClass("disabled");
        var purchase_code = $('#purchase_code').val();
        $.ajax({
            url: 'https://simpledemo.it/check_license_sml.php',
            type: "POST",
            data: {
                server_name: window.server_name,
                server_ip: window.server_ip,
                purchase_code: purchase_code
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                switch (rsp.status) {
                    case 'ok':
                        $('#license_status').html("<i style='color: green;' class=\"fas fa-circle\"></i> "+rsp.msg);
                        var license = rsp.license;
                        if(rsp.msg.indexOf('Extended') >= 0){
                            $('#registration_li').removeClass('d-none');
                            $('#payments_li').removeClass('d-none');
                        }
                        break;
                    case 'error':
                        $('#license_status').html("<i style='color: red;' class=\"fas fa-circle\"></i> "+rsp.msg);
                        var license = '';
                        break;
                }
                $('#btn_check_license').removeClass("disabled");
                $.ajax({
                    url: "ajax/save_lic.php",
                    type: "POST",
                    data: {
                        purchase_code: purchase_code,
                        license: license
                    },
                    async: true,
                    success: function () {
                        if(window.input_license==1 && license!='') {
                            window.settings_need_save=false;
                            location.href='index.php';
                        }
                    }
                });
            }
        });
    }

    window.change_icon_type = function () {
        var icon_type = parseInt($('#icon_type option:selected').attr('id'));
        switch (icon_type) {
            case 0:
                $('#icon_type_1').addClass('d-none');
                $('#icon_type_2').addClass('d-none');
                $('#color_hex').parent().parent().removeClass("disabled");
                $('#icon_color_hex').parent().parent().addClass("disabled");
                $('#color_hex_hover').parent().parent().removeClass("disabled");
                $('#icon_color_hex_hover').parent().parent().addClass("disabled");
                break;
            case 1:
                $('#icon_type_1').removeClass('d-none');
                $('#icon_type_2').addClass('d-none');
                $('#color_hex').parent().parent().removeClass("disabled");
                $('#icon_color_hex').parent().parent().removeClass("disabled");
                $('#color_hex_hover').parent().parent().removeClass("disabled");
                $('#icon_color_hex_hover').parent().parent().removeClass("disabled");
                break;
            case 2:
                $('#icon_type_1').addClass('d-none');
                $('#icon_type_2').removeClass('d-none');
                $('#color_hex').parent().parent().addClass("disabled");
                $('#icon_color_hex').parent().parent().addClass("disabled");
                $('#color_hex_hover').parent().parent().addClass("disabled");
                $('#icon_color_hex_hover').parent().parent().addClass("disabled");
                break;
        }
        change_style_marker();
    }

    window.change_icon_type_c = function () {
        var icon_type = parseInt($('#icon_type_c option:selected').attr('id'));
        switch (icon_type) {
            case 0:
                $('#icon_type_c_1').addClass('d-none');
                $('#icon_type_c_2').addClass('d-none');
                $('#color_hex_c').parent().parent().removeClass("disabled");
                $('#icon_color_hex_c').parent().parent().addClass("disabled");
                break;
            case 1:
                $('#icon_type_c_1').removeClass('d-none');
                $('#icon_type_c_2').addClass('d-none');
                $('#color_hex_c').parent().parent().removeClass("disabled");
                $('#icon_color_hex_c').parent().parent().removeClass("disabled");
                break;
            case 2:
                $('#icon_type_c_1').addClass('d-none');
                $('#icon_type_c_2').removeClass('d-none');
                $('#color_hex_c').parent().parent().addClass("disabled");
                $('#icon_color_hex_c').parent().parent().addClass("disabled");
                break;
        }
    }

    window.change_pin_icon_type = function () {
        var icon_type = parseInt($('#pin_icon_type option:selected').attr('id'));
        switch (icon_type) {
            case 0:
                $('#pin_icon_type_1').addClass('d-none');
                $('#pin_icon_type_2').addClass('d-none');
                $('#pin_color_hex').parent().parent().removeClass("disabled");
                $('#pin_icon_color_hex').parent().parent().addClass("disabled");
                break;
            case 1:
                $('#pin_icon_type_1').removeClass('d-none');
                $('#pin_icon_type_2').addClass('d-none');
                $('#pin_color_hex').parent().parent().removeClass("disabled");
                $('#pin_icon_color_hex').parent().parent().removeClass("disabled");
                break;
            case 2:
                $('#pin_icon_type_1').addClass('d-none');
                $('#pin_icon_type_2').removeClass('d-none');
                $('#pin_color_hex').parent().parent().addClass("disabled");
                $('#pin_icon_color_hex').parent().parent().addClass("disabled");
                break;
        }
    }

    window.assign_map_editor = function (id,checked) {
        $.ajax({
            url: "ajax/assign_map_editor.php",
            type: "POST",
            data: {
                id_map: id,
                id_user: window.id_user_edit,
                checked: checked
            },
            async: false,
            success: function() {
                if(checked==1) {
                    $('#assign_map_table').DataTable().ajax.reload();
                }
            }
        });
    }

    window.set_permission_map_editor = function (id,field,checked) {
        $.ajax({
            url: "ajax/set_permission_map_editor.php",
            type: "POST",
            data: {
                id_map: id,
                id_user: window.id_user_edit,
                field: field,
                checked: checked
            },
            async: true,
            success: function() {}
        });
    }

    window.change_map = function() {
        var id = $('#map_selector option:selected').attr('id');
        $.ajax({
            url: "ajax/set_session_m.php",
            type: "POST",
            data: {
                id_map: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    var url = window.location.href;
                    location.href = url;
                }
            }
        });
    }

    window.change_order = function(id_marker,direction) {
        $.ajax({
            url: "ajax/change_order.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id_marker: id_marker,
                direction: direction
            },
            async: false,
            success: function (json) {
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.change_order_c = function(id_category,direction) {
        $.ajax({
            url: "ajax/change_order_c.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id_category: id_category,
                direction: direction
            },
            async: false,
            success: function (json) {
                $('#categories_table').DataTable().ajax.reload();
            }
        });
    }

    window.change_order_story = function(id_marker,direction) {
        $.ajax({
            url: "ajax/change_order_story.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id_marker: id_marker,
                direction: direction
            },
            async: false,
            success: function (json) {
                $('#markers_story_table').DataTable().ajax.reload();
            }
        });
    }

    window.get_markers_story_add = function () {
        $('#btn_add_markers_story').addClass('disabled');
        $.ajax({
            url: "ajax/get_markers_story_add.php",
            type: "POST",
            data: {
                id_map: window.id_map
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var markers = rsp.markers;
                var options = '';
                if(markers.length>0) {
                    jQuery.each(markers, function(index, marker) {
                        options += '<option id="'+marker.id+'">'+marker.name+'</option>';
                    });
                    $('#btn_add_markers_story').removeClass('disabled');
                }
                $('#marker_story_add').html(options).promise().done(function () {
                    $('#marker_story_add').selectpicker('refresh');
                    $('#marker_story_add').selectpicker('render');
                });
            }
        });
    }

    window.add_geoimage = function(image) {
        $('.gi_add_msg_div').show();
        $('.gi_upload_div').hide();
        var params = {};
        params['rotate']=0;
        params['scale']=1;
        params['x']=window.center_add_coords[0];
        params['y']=window.center_add_coords[1];
        params['opacity']=0.5;
        var params_json = JSON.stringify(params);
        $.ajax({
            url: "ajax/add_geoimage.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                image: image,
                params: params_json
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if(rsp.status=='ok') {
                    location.reload();
                } else {
                    $('.gi_upload_div').show();
                    $('.gi_add_msg_div').hide();
                }
            },
            error: function () {
                $('.gi_upload_div').show();
                $('.gi_add_msg_div').hide();
            }
        });
    }

    window.add_geodata = function() {
        var file = $('#file_url').val();
        $.ajax({
            url: "ajax/add_geodata.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                file: file
            },
            async: true,
            success: function (json) {
                $('#geodata_table').DataTable().ajax.reload();
                $('#file_url').val('');
                $('#btn_add_geodata').addClass('disabled');
            },
            error: function () {

            }
        });
    }

    window.delete_geodata = function(id) {
        var retVal = confirm(window.backend_labels.delete_msg);
        if( retVal == true ) {
            $.ajax({
                url: "ajax/delete_geodata.php",
                type: "POST",
                data: {
                    id_map: window.id_map,
                    id: id
                },
                async: true,
                success: function (json) {
                    $('#geodata_table').DataTable().ajax.reload();
                }
            });
        }
    }

    window.get_geoimages = function (id_map) {
        $.ajax({
            url: "ajax/get_geoimages.php",
            type: "POST",
            data: {
                id_map: id_map
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var geoimages = rsp.geoimages;
                var images = 0;
                var images_loaded = 0;
                $.each(geoimages,function(index,geoimage) {
                    try {
                        var id = parseInt(geoimage.id);
                        var params = JSON.parse(geoimage.params);
                        var x = parseFloat(params.x);
                        var y = parseFloat(params.y);
                        var scale = parseFloat(params.scale);
                        var rotate = parseFloat(params.rotate);
                        var opacity = parseFloat(params.opacity);
                        var img = new Image();
                        img.src = '../viewer/geoimages/' + geoimage.image;
                        img.crossOrigin = 'anonymous';
                        images++;
                        img.onload = function() {
                            var geoimg = new ol.layer.GeoImage({
                                name: "geoimage"+id,
                                image_width: img.width,
                                image_height: img.height,
                                opacity: opacity,
                                source: new ol.source.GeoImage({
                                    url: '../viewer/geoimages/'+geoimage.image,
                                    imageCenter: [x,y],
                                    imageScale: [scale,scale],
                                    imageRotate: rotate,
                                    projection: 'EPSG:3857',
                                })
                            });
                            geoimg.setZIndex(10);
                            initTransformationLayer(geoimg,id,img);
                            map.addLayer(geoimg);
                            images_loaded++;
                        };
                    } catch (e) {
                        console.log(e);
                    }
                });
                var interval_check_il = setInterval(function() {
                    if(images_loaded>=images) {
                        initialize_transform_geoimages();
                        clearInterval(interval_check_il);
                        var extent = undefined;
                        map.getLayers().forEach(function(layer) {
                            if (layer.getVisible() && layer.getSource) {
                                var source = layer.getSource();
                                if (source && source.getFeatures) {
                                    var sourceExtent = source.getExtent();
                                    if (sourceExtent) {
                                        if (!extent) {
                                            extent = sourceExtent;
                                        } else {
                                            ol.extent.extend(extent, sourceExtent);
                                        }
                                    }
                                }
                            }
                        });
                        if (extent) {
                            map.getView().fit(extent, { padding: [200, 200, 200, 200] });
                        } else {
                            console.warn("No features found to fit the map view.");
                        }
                    }
                },500);
            }
        });
    }

    window.open_add_geoimage = function() {
        $('.gi_add_msg_div').hide();
        $('.gi_opacity_div').hide();
        $('.gi_add_div').show();
        $('.gi_upload_div').hide();
        transformInteraction.setActive(false);
    }

    window.cancel_add_geoimage = function() {
        $('.gi_opacity_div').hide();
        $('.gi_add_div').hide();
        $('.gi_upload_div').hide();
        transformInteraction.setActive(true);
        $('#map canvas').css('pointer-events','initial');
    }

    window.confirm_add_geoimage = function() {
        $('.gi_opacity_div').hide();
        $('.gi_add_div').hide();
        $('.gi_upload_div').show();
        $('#map canvas').css('pointer-events','none');
        center_add_coords = map.getView().getCenter();
    }

    window.delete_geoimage = function() {
        var retVal = confirm(window.backend_labels.delete_msg);
        if( retVal == true ) {
            $('.gi_opacity_div').hide();
            var id = window.selected_geoimage.values_.name.replace("geoimage","");
            $.ajax({
                url: "ajax/delete_geoimage.php",
                type: "POST",
                data: {
                    id_map: window.id_map,
                    id: id
                },
                async: true,
                success: function (json) {
                    location.reload();
                }
            });
        }
    }

    var timeout_save = null;
    window.change_gi_opacity = function() {
        var opacity = parseFloat($('#gi_opacity').val());
        $('#gi_opacity_value').html(opacity);
        window.selected_geoimage.setOpacity(opacity);
        clearTimeout(timeout_save);
        timeout_save = setTimeout(function() {
            save_geoimage(window.selected_geoimage.values_.name);
        },1000);
    }

    function getPolygonfromImage(layer,img) {
        var source = layer.getSource();
        var center = source.getCenter();
        var scale = source.getScale();
        var width = img.width * scale[0];
        var height = img.height * scale[1];
        var p1 = [center[0] - width / 2, center[1] - height / 2];
        var p2 = [center[0] + width / 2, center[1] + height / 2];
        var extent = ol.extent.boundingExtent([p1, p2]);
        var polygon = ol.geom.Polygon.fromExtent(extent);
        polygon.rotate(-source.getRotation(), center);
        return polygon;
    }
    window.getTransformLayerStyle = function() {
        return [
            new ol.style.Style({
                fill: new ol.style.Fill({ color: [0, 0, 0, 0] }),
                stroke: new ol.style.Stroke({ color: [0, 0, 0, 1], width: 2 })
            })
        ];
    }

    function getLayerByName(map, layerName) {
        var layers = map.getLayers().getArray();
        for (var i = 0; i < layers.length; i++) {
            if (layers[i].get('name') === layerName) {
                return layers[i];
            }
        }
        return null;
    }

    var transformInteraction = null;
    function initialize_transform_geoimages() {
        let transformLayer = new ol.layer.Vector({
            source: vector_geoimages.getSource(),
            style: getTransformLayerStyle
        });
        map.getLayers().extend([transformLayer]);
        transformInteraction = new ol.interaction.Transform({
            translate: true,
            translateFeature: false,
            translateBBox: true,
            scale: true,
            rotate: true,
            stretch: false,
            keepAspectRatio: ol.events.condition.always
        });
        map.addInteraction(transformInteraction);
        transformInteraction.on (['select'], function(e) {
            var feature = e.feature;
            if(feature===undefined) {
                $('.gi_opacity_div').hide();
            } else {
                var target_id = feature.values_.attributes.target_id;
                var geoimg = getLayerByName(map,"geoimage"+target_id);
                window.selected_geoimage = geoimg;
                var opacity = parseFloat(geoimg.values_.opacity);
                $('#gi_opacity').val(opacity);
                $('#gi_opacity_value').html(opacity);
                $('.gi_opacity_div').show();
            }
        });
        transformInteraction.on(['scaling','rotating','translating'], function(e) {
            var c = ol.extent.getCenter(e.feature.getGeometry().getExtent());
            var feature = e.feature;
            var target_id = feature.values_.attributes.target_id;
            var geoimg = getLayerByName(map,"geoimage"+target_id);
            var geom = feature.getGeometry();
            var coord = geom.getCoordinates();
            var p0 = coord[0][0];
            var p1 = coord[0][1];
            var dp = [p0[0]-p1[0], p0[1]-p1[1]];
            var r = Math.atan2(-dp[1], dp[0]) - Math.PI/2;
            var sy = ((p0[0] - c[0]) * Math.sin(r) + (p0[1] - c[1]) * Math.cos(r)) / ( (geoimg.values_.image_height/2) * (Math.sin(r)*Math.sin(r) + Math.cos(r)* Math.cos(r)) );
            var sx = ((p0[0] - c[0]) * Math.cos(r) - (p0[1] - c[1]) * Math.sin(r)) / ( (geoimg.values_.image_width/2) * (Math.sin(r)*Math.sin(r) + Math.cos(r)* Math.cos(r)) );
            geoimg.getSource().setCenter(c);
            geoimg.getSource().setRotation(r);
            geoimg.getSource().setScale([sx,sy]);
        });
        transformInteraction.on(['rotateend','translateend','scaleend'], function(e) {
            var feature = e.feature;
            var target_id = feature.values_.attributes.target_id;
            save_geoimage("geoimage"+target_id);
        })
    }

    function initTransformationLayer(geoimg,id,img) {
        let poly = getPolygonfromImage(geoimg,img);
        vector_geoimages.getSource().addFeature(
            new ol.Feature({
                geometry: poly,
                attributes: { target_id: id}
            })
        );
    }

    window.save_geoimage = function(target_id) {
        var geoimg = getLayerByName(map,target_id);
        var rotation = geoimg.getSource().getRotation();
        var scale = geoimg.getSource().getScale();
        scale[0]=scale[0]*-1;
        scale[1]=scale[1]*-1;
        var center = geoimg.getSource().getCenter();
        var params = {};
        params['rotate']=rotation;
        params['scale']=scale[0];
        params['x']=center[0];
        params['y']=center[1];
        params['opacity']=geoimg.values_.opacity;
        var params_json = JSON.stringify(params);
        $.ajax({
            url: "ajax/save_geoimage.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                id: target_id.replace('geoimage',''),
                params: params_json
            },
            async: true,
            success: function (json) {
                alertify.set('notifier','position', 'bottom-right');
                alertify.set('notifier','delay', 2);
                alertify.success(window.backend_labels.save_ok).dismissOthers();
            },
            error: function () {
                alertify.set('notifier','position', 'bottom-right');
                alertify.set('notifier','delay', 2);
                alertify.error(window.backend_labels.save_error).dismissOthers();
            }
        });
    }

    window.set_show_in_first_page = function(show_in_first_page,w) {
        switch(w) {
            case 'map':
                var id = window.id_map;
                break;
            case 'showcase':
                var id = window.id_showcase;
                break;
        }
        $.ajax({
            url: "ajax/set_show_in_first_page.php",
            type: "POST",
            data: {
                id: id,
                show_in_first_page: show_in_first_page,
                w: w
            },
            async: false,
            success: function (json) {}
        });
    }

    window.bulk_select = function () {
        window.bulk_select_mode = true;
        $('.marker_add_bar').hide();
        $('.marker_bulk_select_bar').show();
        $('#markers_table').DataTable().draw();
    }

    window.exit_bulk_select = function () {
        window.bulk_select_mode = false;
        $('.marker_add_bar').show();
        $('.marker_bulk_select_bar').hide();
        $('#markers_table').DataTable().draw();
        $('#bulk_action option:first').prop('selected',true);
    }

    window.execute_bulk_action = function() {
        var bulk_action = $('#bulk_action option:selected').attr('id');
        switch (bulk_action) {
            case 'delete':
                exec_bulk_delete();
                break;
            case 'activate':
                exec_bulk_activate();
                break;
            case 'disable':
                exec_bulk_disable();
                break;
            case 'validate':
                exec_bulk_validate();
                break;
            case 'add_featured':
                exec_bulk_add_featured();
                break;
            case 'remove_featured':
                exec_bulk_remove_featured();
                break;
            case 'visible_map':
                exec_bulk_visible_map();
                break;
            case 'hide_map':
                exec_bulk_hide_map();
                break;
            case 'visible_search':
                exec_bulk_visible_search();
                break;
            case 'hide_search':
                exec_bulk_hide_search();
                break;
            case 'categories':
                exec_bulk_category();
                break;
        }
    }

    window.exec_bulk_category = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        var categories_t = $('#category option');
        var categories = [];
        $(categories_t).each(function(index, elem){
            var id = $(this).attr('id');
            if($(this).is(':selected') && !$(this).is(':disabled')) {
                categories.push(id);
                $(this).prop('selected',false);
            }
        });
        $.ajax({
            url: "ajax/bulk_category_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids,
                categories: categories
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                change_bulk_action();
                $('#markers_table').DataTable().ajax.reload();
                $('#category').selectpicker('refresh');
            }
        });
    }

    window.exec_bulk_delete = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_delete_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_activate = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_activate_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_visible_map = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_visible_map_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_hide_map = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_hide_map_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_visible_search = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_visible_search_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_hide_search = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_hide_search_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_disable = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_disable_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_validate = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_validate_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_add_featured = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_add_featured_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.exec_bulk_remove_featured = function () {
        var ids = '';
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                ids += $(this).attr('id').replace("marker_","")+",";
            }
        });
        var lastChar = ids.slice(-1);
        if (lastChar == ',') {
            ids = ids.slice(0, -1);
        }
        $.ajax({
            url: "ajax/bulk_remove_featured_markers.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                ids: ids
            },
            async: false,
            success: function (json) {
                $('#bulk_action option:first').prop('selected',true);
                $('#markers_table').DataTable().ajax.reload();
            }
        });
    }

    window.change_bulk_action = function() {
        var num = 0;
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                num++;
            }
        });
        var bulk_action = $('#bulk_action option:selected').attr('id');
        if(num!=0 && bulk_action!='0') {
            $('.btn_bulk_action').removeClass('disabled');
        } else {
            $('.btn_bulk_action').addClass('disabled');
        }
        if(bulk_action=='categories') {
            $('#div_bulk_cat').show();
            $('#div_bulk_info').removeClass('col-md-6').addClass('col-md-4');
        } else {
            $('#div_bulk_cat').hide();
            $('#div_bulk_info').removeClass('col-md-4').addClass('col-md-6');
        }
    }

    window.select_all_markers = function () {
        $('.check_bulk_marker').prop('checked',true);
        var num = 0;
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                num++;
            }
        });
        $('#markers_selected').html(num);
        var bulk_action = $('#bulk_action option:selected').attr('id');
        if(num!=0 && bulk_action!='0') {
            $('.btn_bulk_action').removeClass('disabled');
        } else {
            $('.btn_bulk_action').addClass('disabled');
        }
    }

    window.deselect_all_markers = function () {
        $('.check_bulk_marker').prop('checked',false);
        var num = 0;
        $('.check_bulk_marker').each(function() {
            if ($(this).is(':checked')) {
                num++;
            }
        });
        $('#markers_selected').html(num);
        var bulk_action = $('#bulk_action option:selected').attr('id');
        if(num!=0 && bulk_action!='0') {
            $('.btn_bulk_action').removeClass('disabled');
        } else {
            $('.btn_bulk_action').addClass('disabled');
        }
    }

    window.save_draw_geometries = function(draw_geometries) {
        $.ajax({
            url: "ajax/save_draw_geometries.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                draw_geometries: draw_geometries
            },
            async: true,
            success: function (json) {
                alertify.set('notifier','position', 'bottom-right');
                alertify.set('notifier','delay', 2);
                alertify.success(window.backend_labels.save_ok).dismissOthers();
            },
            error: function() {
                alertify.set('notifier','position', 'bottom-right');
                alertify.set('notifier','delay', 2);
                alertify.error(window.backend_labels.save_error).dismissOthers();
            }
        });
    }

    window.save_boundaries = function(extent) {
        $.ajax({
            url: "ajax/save_boundaries.php",
            type: "POST",
            data: {
                id_map: window.id_map,
                extent: extent
            },
            async: true,
            success: function (json) {
                alertify.set('notifier','position', 'bottom-right');
                alertify.set('notifier','delay', 2);
                alertify.success(window.backend_labels.save_ok).dismissOthers();
            },
            error: function() {
                alertify.set('notifier','position', 'bottom-right');
                alertify.set('notifier','delay', 2);
                alertify.error(window.backend_labels.save_error).dismissOthers();
            }
        });
    }

    window.open_modal_content = function(target,type) {
        switch(type) {
            case 'embed_link':
                $('#content_embed_link').val('');
                $('#modal_content_embed_link').modal('show');
                $('#modal_content_embed_link .btn-success').attr('onclick','insert_content_embed_link();');
                break;
            case 'link2':
                $('#content_link2').val('');
                $('#modal_content_link2').modal('show');
                $('#modal_content_link2 .btn-success').attr('onclick','insert_content_link2();');
                break;
            case 'link':
                $('#content_link').val('');
                $('#content_link_name').val('');
                $('#modal_content_link').modal('show');
                $('#modal_content_link .btn-success').attr('onclick','insert_content_link(\''+target+'\');');
                break;
            case 'text':
                window.content_text_editor.root.innerHTML = '';
                $('#modal_content_text').modal('show');
                $('#modal_content_text .btn-success').attr('onclick','insert_content_text(\''+target+'\');');
                break;
            case 'download':
                $('#content_download_link').val('');
                $('#content_download_name').val('');
                $('#modal_content_download').modal('show');
                $('#modal_content_download .btn-success').attr('onclick','insert_content_download(\''+target+'\');');
                break;
        }
    }

    window.insert_content_link = function(target) {
        var link = $('#content_link').val();
        var name = $('#content_link_name').val();
        if(link!='') {
            if(name=='') name = link;
            var content = '<a target="_blank" href="'+link+'">'+name+'</a>';
            if($('.input_lang[data-target-id="extra_field_value_'+target+'"]:visible').length==1) {
                var lang = $('.input_lang[data-target-id="extra_field_value_'+target+'"]:visible').attr('data-lang');
                window.editor_html_extra_fields_langs[target][lang].setValue(content,-1);
            } else {
                window.editor_html_extra_fields[target].setValue(content,-1);
            }
            $('#modal_content_link').modal('hide');
        }
    }

    window.insert_content_link2 = function() {
        var link = $('#content_link2').val();
        if(link!='') {
            if($('.input_lang[data-target-id="extra_button_value_1"]:visible').length==1) {
                var lang = $('.input_lang[data-target-id="extra_button_value_1"]:visible').attr('data-lang');
                window.editor_html_extra_button_1_langs[lang].setValue(link,-1);
            } else {
                window.editor_html_extra_button_1.setValue(link,-1);
            }
            $('#modal_content_link2').modal('hide');
        }
    }

    window.insert_content_text = function(target) {
        var content = window.content_text_editor.root.innerHTML;
        if(content!='<p><br></p>') {
            if(target=='extra_button_value_1') {
                if($('.input_lang[data-target-id="extra_button_value_1"]:visible').length==1) {
                    var lang = $('.input_lang[data-target-id="extra_button_value_1"]:visible').attr('data-lang');
                    window.editor_html_extra_button_1_langs[lang].setValue(content,-1);
                } else {
                    window.editor_html_extra_button_1.setValue(content,-1);
                }
            } else {
                if($('.input_lang[data-target-id="extra_field_value_'+target+'"]:visible').length==1) {
                    var lang = $('.input_lang[data-target-id="extra_field_value_'+target+'"]:visible').attr('data-lang');
                    window.editor_html_extra_fields_langs[target][lang].setValue(content,-1);
                } else {
                    window.editor_html_extra_fields[target].setValue(content,-1);
                }
            }
            $('#modal_content_text').modal('hide');
        }
    }

    window.insert_content_embed_link = function() {
        var link = $('#content_embed_link').val();
        if(link!='') {
            var content = '<iframe allowfullscreen allow="*" width="100%" height="100%" frameborder="0" scrolling="yes" marginheight="0" marginwidth="0" src="'+link+'"></iframe>';
            if($('.input_lang[data-target-id="extra_button_value_1"]:visible').length==1) {
                var lang = $('.input_lang[data-target-id="extra_button_value_1"]:visible').attr('data-lang');
                window.editor_html_extra_button_1_langs[lang].setValue(content,-1);
            } else {
                window.editor_html_extra_button_1.setValue(content,-1);
            }
            $('#modal_content_embed_link').modal('hide');
        }
    }

    window.insert_content_download = function(target) {
        var link = $('#content_download_link').val();
        var name = $('#content_download_name').val();
        if(link!='' && name !='') {
            var content = '<a download href="'+link+'">'+name+'</a>';
            if($('.input_lang[data-target-id="extra_field_value_'+target+'"]:visible').length==1) {
                var lang = $('.input_lang[data-target-id="extra_field_value_'+target+'"]:visible').attr('data-lang');
                window.editor_html_extra_fields_langs[target][lang].setValue(content,-1);
            } else {
                window.editor_html_extra_fields[target].setValue(content,-1);
            }
            $('#modal_content_download').modal('hide');
        }
    }

    window.change_open_sheet_marker = function() {
        var open_sheet = $('#open_sheet').is(':checked');
        if(open_sheet) {
            $('#sheet_details_settings').removeClass('disabled');
        } else {
            $('#sheet_details_settings').addClass('disabled');
        }
    }

    window.change_popup_marker = function() {
        var view_popup = $('#view_popup').is(':checked');
        if(view_popup) {
            $('#popup_settings').removeClass('disabled');
        } else {
            $('#popup_settings').addClass('disabled');
        }
    }

    window.switch_custom_mode = function(mode) {
        switch(mode) {
            case 'backend':
                $('#btn_custom_backend').removeClass('btn-outline-primary').addClass('btn-primary');
                $('#btn_custom_viewer').addClass('btn-outline-primary').removeClass('btn-primary');
                $('#custom_viewer_div').addClass('d-none');
                $('#custom_backend_div').removeClass('d-none');
                break;
            case 'viewer':
                $('#btn_custom_viewer').removeClass('btn-outline-primary').addClass('btn-primary');
                $('#btn_custom_backend').addClass('btn-outline-primary').removeClass('btn-primary');
                $('#custom_viewer_div').removeClass('d-none');
                $('#custom_backend_div').addClass('d-none');
                break;
        }
    }

    window.change_editor_css = function () {
        var id = $('#css_name option:selected').attr('id').replace('css_','');
        $('.editors_css').hide();
        $('#custom_b').show();
        $('#'+id).show();
    }

    window.change_editor_js = function () {
        var id = $('#js_name option:selected').attr('id').replace('js_custom','custom_js');
        $('.editors_js').hide();
        $('#custom_b_js').show();
        $('#'+id).show();
    }

    window.change_editor_head = function () {
        var id = $('#head_name option:selected').attr('id').replace('head_custom','custom_head');
        $('.editors_head').hide();
        $('#custom_b_head').show();
        $('#'+id).show();
    }

    window.change_font_provider = function() {
        var font_provider = $('#font_provider option:selected').attr('id');
        switch(font_provider) {
            case 'systems':
                $('.font-picker').addClass('d-none');
                $('#font_backend_system').removeClass('d-none');
                apply_system_font();
                break;
            case 'google':
                $('.font-picker').removeClass('d-none');
                $('#font_backend_system').addClass('d-none');
                var font_family = $('#font_backend').val();
                $('#font_backend_link').attr('href','https://fonts.googleapis.com/css?family='+font_family);
                $('#style_css').html("* { font-family:'"+font_family+"',sans-serif; }");
                break;
            case 'collabs':
                $('.font-picker').removeClass('d-none');
                $('#font_backend_system').addClass('d-none');
                var font_family = $('#font_backend').val();
                $('#font_backend_link').attr('href','https://api.fonts.coollabs.io/css2?family='+font_family+'&display=swap');
                $('#style_css').html("* { font-family:'"+font_family+"',sans-serif; }");
                break;
        }
    }

    window.apply_system_font = function() {
        var font_family = $('#font_backend_system option:selected').attr('id');
        $('#style_css').html("* { font-family:'"+font_family+"',sans-serif; }");
    }

    window.start_batch_geocode = async function() {
        $('#modal_batch_geocode button').addClass('disabled');
        try {
            if($('#checkbox_address_position').is(':checked')) {
                $('#batch_geocode_progress .progress-bar').addClass('progress-bar-animated');
                const missing_markers_coord = JSON.parse(window.missing_markers_coord_json);
                await geocodeAddresses(missing_markers_coord);
            }
            if($('#checkbox_position_address').is(':checked')) {
                $('#batch_geocode_progress_reverse .progress-bar').addClass('progress-bar-animated');
                const missing_markers_address = JSON.parse(window.missing_markers_address_json);
                await geocodeAddresses_reverse(missing_markers_address);
            }
        } catch (e) {
            console.log(e);
        }
        setTimeout(function() {
            $('#batch_geocode_progress .progress-bar').removeClass('progress-bar-animated');
            $('#batch_geocode_progress_reverse .progress-bar').removeClass('progress-bar-animated');
            $('#modal_batch_geocode button').removeClass('disabled');
            $('#modal_batch_geocode').modal('hide');
            location.reload();
        },1500);
    }

    async function geocodeAddresses(missing_markers_coord) {
        var count = 0;
        for (const marker of missing_markers_coord) {
            try {
                const { id, street, city, postal_code, country, county, state } = marker;
                var coords = await window.marker_geocode(id, street, city, postal_code, country, county, state);
                if(coords!=null) {
                    await window.save_marker_geocode_coords(id, coords);
                }
                await new Promise((resolve) => setTimeout(resolve, 1000));
                count++;
                var percentage = calculatePercentage(count,missing_markers_coord.length);
                $('#batch_geocode_progress .progress-bar').css('width',percentage+'%');
                $('#batch_geocode_progress .progress-bar').html(count + ' / ' + missing_markers_coord.length);
            } catch (error) {
                await new Promise((resolve) => setTimeout(resolve, 1000));
                count++;
                var percentage = calculatePercentage(count,missing_markers_coord.length);
                $('#batch_geocode_progress .progress-bar').css('width',percentage+'%');
                $('#batch_geocode_progress .progress-bar').html(count + ' / ' + missing_markers_coord.length);
            }
        }
    }

    async function geocodeAddresses_reverse(missing_markers_coord) {
        var count = 0;
        for (const marker of missing_markers_coord) {
            try {
                const { id, lat, lon } = marker;
                var address = await window.marker_geocode_reverse(id, lat, lon);
                if(address!=null) {
                    await window.save_marker_geocode_address(id, address);
                }
                await new Promise((resolve) => setTimeout(resolve, 1000));
                count++;
                var percentage = calculatePercentage(count,missing_markers_coord.length);
                $('#batch_geocode_progress_reverse .progress-bar').css('width',percentage+'%');
                $('#batch_geocode_progress_reverse .progress-bar').html(count + ' / ' + missing_markers_coord.length);
            } catch (error) {
                await new Promise((resolve) => setTimeout(resolve, 1000));
                count++;
                var percentage = calculatePercentage(count,missing_markers_coord.length);
                $('#batch_geocode_progress_reverse .progress-bar').css('width',percentage+'%');
                $('#batch_geocode_progress_reverse .progress-bar').html(count + ' / ' + missing_markers_coord.length);
            }
        }
    }

    function calculatePercentage(numerator, denominator) {
        if (denominator === 0) {
            return 0;
        }
        return (numerator / denominator) * 100;
    }

    window.save_marker_geocode_coords = function(id,coords) {
        return new Promise((resolve, reject) => {
            $.ajax({
                url: "ajax/save_marker_coords.php",
                type: "POST",
                data: {
                    id_marker: id,
                    lat: coords.lat,
                    lon: coords.lon
                },
                async: true,
                success: function (json) {
                    resolve(true);
                },
                error: function () {
                    resolve(false);
                }
            });
        });
    }

    window.save_marker_geocode_address = function(id,address) {
        return new Promise((resolve, reject) => {
            $.ajax({
                url: "ajax/save_marker_address.php",
                type: "POST",
                data: {
                    id_marker: id,
                    address: JSON.stringify(address)
                },
                async: true,
                success: function (json) {
                    resolve(true);
                },
                error: function () {
                    resolve(false);
                }
            });
        });
    }

    window.delete_im = function () {
        window.intro_image = '';
        window.map_need_save = true;
        $('#div_delete_im').hide();
        $('#div_image_im').hide();
        $('#div_upload_im').show();
        $('#div_image_im img').attr('src','');
    }

    window.delete_bg = function () {
        window.background_image = '';
        window.map_need_save = true;
        $('#div_delete_bg').hide();
        $('#div_image_bg').hide();
        $('#div_upload_bg').show();
        $('#div_image_bg img').attr('src','');
    }

    window.delete_bg_m = function () {
        window.background_image_mobile = '';
        window.map_need_save = true;
        $('#div_delete_bg_m').hide();
        $('#div_image_bg_m').hide();
        $('#div_upload_bg_m').show();
        $('#div_image_bg_m img').attr('src','');
    }

    window.add_marker = function () {
        var complete = true;
        var name = $('#name').val();
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        if(complete) {
            $('#modal_add_marker button').addClass("disabled");
            $.ajax({
                url: "ajax/add_marker.php",
                type: "POST",
                data: {
                    id_map: id_map,
                    name: name
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        location.href='index.php?p=edit_marker&id='+rsp.id;
                    } else {
                        alert(rsp.msg);
                        $('#modal_add_marker button').removeClass("disabled");
                    }
                },
                error: function() {
                    $('#modal_add_marker button').removeClass("disabled");
                }
            });
        }
    }

    window.add_showcase = function () {
        var complete = true;
        var name = $('#name').val();
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        if(complete) {
            $('#modal_new_showcase button').addClass("disabled");
            $.ajax({
                url: "ajax/add_showcase.php",
                type: "POST",
                data: {
                    name: name
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        location.href='index.php?p=edit_showcase&id='+rsp.id;
                    } else {
                        alert(rsp.msg);
                        $('#modal_new_showcase button').removeClass("disabled");
                    }
                }, error: function () {
                    $('#modal_new_showcase button').removeClass("disabled");
                }
            });
        }
    };

    window.save_showcase = function(id_showcase,reload) {
        $('#friendly_url').removeClass("error-highlight");
        var complete = true;
        var array_lang = {};
        var name = $('#name').val();
        array_lang['name'] = {};
        $('.input_lang[data-target-id="name"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['name'][lang]=value;
        });
        var bg_color = $('#bg_color').val();
        var header_html = window.editor_html_h.getValue();
        array_lang['header_html'] = {};
        $('.input_lang[data-target-id="header_html"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_h_langs[lang].getValue();
            array_lang['header_html'][lang]=value;
        });
        var footer_html = window.editor_html_f.getValue();
        array_lang['footer_html'] = {};
        $('.input_lang[data-target-id="footer_html"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = window.editor_html_f_langs[lang].getValue();
            array_lang['footer_html'][lang]=value;
        });
        var custom_css = window.editor_css.getValue();
        if(name=='') {
            complete = false;
            $('#name').addClass("error-highlight");
        } else {
            $('#name').removeClass("error-highlight");
        }
        var list_s_map = [];
        var list_s_type = [];
        var list_s_priority = [];
        $('.list_s_map input[type=checkbox]').each(function () {
            var id = this.id;
            if(this.checked) {
                list_s_map.push(id);
                list_s_type.push($('#t_'+id+' option:selected').attr('id'));
                list_s_priority.push($('#p_'+id).val());
            }
        });
        var sort_settings_t = $('#sort_settings option');
        var sort_settings = {};
        $(sort_settings_t).each(function(index, elem){
            var id = $(this).attr('id');
            if(id !== undefined) {
                if($(this).is(':selected')) {
                    sort_settings[id]=1;
                } else {
                    sort_settings[id]=0;
                }
            }
        });
        var sort_default = $('#sort_default option:selected').attr('id');
        sort_settings['default'] = sort_default;
        var sort_settings_json = JSON.stringify(sort_settings);
        var open_target = $('#open_target option:selected').attr('id');
        var ga_tracking_id = $('#ga_tracking_id').val();
        var language = $('#language option:selected').attr('id');
        var languages_enabled_t = $('#languages_enabled option');
        var languages_enabled = {};
        $(languages_enabled_t).each(function(index, elem){
            var id = $(this).attr('id').replace('ls_','');
            if($(this).is(':selected')) {
                languages_enabled[id]=1;
            } else {
                languages_enabled[id]=0;
            }
        });
        var languages_enabled_json = JSON.stringify(languages_enabled);
        var cookie_consent = ($('#cookie_consent').is(':checked')) ? 1 : 0;
        var pwa_enable = ($('#pwa_enable').is(':checked')) ? 1 : 0;
        if(complete) {
            if(reload) $('#modal_change_languages').modal('hide');
            $('#save_btn .icon i').removeClass('far fa-circle').addClass('fas fa-circle-notch fa-spin');
            $('#save_btn').addClass("disabled");
            var array_lang_json = JSON.stringify(array_lang);
            $.ajax({
                url: "ajax/save_showcase.php",
                type: "POST",
                data: {
                    id: id_showcase,
                    name: name,
                    bg_color: bg_color,
                    logo: window.s_logo_image,
                    banner: window.s_banner_image,
                    list_s_map: list_s_map,
                    list_s_type: list_s_type,
                    list_s_priority: list_s_priority,
                    header_html: header_html,
                    footer_html: footer_html,
                    custom_css: custom_css,
                    sort_settings: sort_settings_json,
                    open_target: open_target,
                    ga_tracking_id: ga_tracking_id,
                    cookie_consent: cookie_consent,
                    language: language,
                    languages_enabled: languages_enabled_json,
                    array_lang: array_lang_json,
                    pwa_enable: pwa_enable
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if(rsp.status=="ok") {
                        if(rsp.favicon!=1) {
                            generate_favicons(rsp.favicon);
                        }
                        window.showcase_need_save = false;
                        if(reload) location.reload();
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-check');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-check').addClass('far fa-circle');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                    } else {
                        if(rsp.status=='error_furl') {
                            $('#friendly_url').addClass("error-highlight");
                        }
                        $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                        $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                        setTimeout(function () {
                            $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                            $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                            $('#save_btn').removeClass("disabled");
                        },1000);
                    }
                },
                error: function() {
                    $('#save_btn .icon i').removeClass('fas fa-circle-notch fa-spin').addClass('fas fa-times');
                    $('#save_btn').removeClass('btn-success').addClass('btn-danger');
                    setTimeout(function () {
                        $('#save_btn .icon i').removeClass('fas fa-times').addClass('far fa-circle');
                        $('#save_btn').removeClass('btn-danger').addClass('btn-success');
                        $('#save_btn').removeClass("disabled");
                    },1000);
                }
            });
        }
    }

    window.delete_s_logo = function () {
        window.s_logo_image = '';
        window.showcase_need_save = true;
        $('#div_delete_logo').hide();
        $('#div_image_logo').hide();
        $('#div_upload_logo').show();
        $('#div_image_logo img').attr('src','');
    }

    window.delete_s_banner = function () {
        window.s_banner_image = '';
        window.showcase_need_save = true;
        $('#div_delete_banner').hide();
        $('#div_image_banner').hide();
        $('#div_upload_banner').show();
        $('#div_image_banner img').attr('src','');
    }

    window.changeTimezone = function() {
        var selectedTimezone = $('#timezone').val();
        $.ajax({
            type: 'POST',
            url: 'ajax/preview_timezone.php',
            data: { timezone: selectedTimezone },
            success: function(response) {
                $('#preview_timezone').html(response);
            }
        });
    }

    window.modal_delete_showcase = function(id) {
        $('#btn_delete_showcase').attr('onclick','delete_showcase(\''+id+'\');');
        $('#modal_delete_showcase').modal("show");
    }

    window.delete_showcase = function (id) {
        $('#modal_delete_showcase button').addClass("disabled");
        $.ajax({
            url: "ajax/delete_showcase.php",
            type: "POST",
            data: {
                id_showcase: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_delete_showcase button').removeClass("disabled");
                    $('#modal_delete_showcase').modal("hide");
                    location.href = 'index.php?p=showcases';
                } else {
                    $('#modal_delete_showcase button').removeClass("disabled");
                }
            }
        });
    };

    window.change_lazy_loading = function(mark_changed) {
        var lazy_loading_mode = parseInt($('#lazy_loading option:selected').attr('id'));
        var viewport_loading = lazy_loading_mode===2;
        var asynchronous_loading = lazy_loading_mode===1 || lazy_loading_mode===2;
        $('#lazy_loading_max_markers')
            .prop('disabled',!viewport_loading)
            .attr('aria-disabled',viewport_loading ? 'false' : 'true');
        $('#loading_visible')
            .prop('disabled',asynchronous_loading)
            .attr('aria-disabled',asynchronous_loading ? 'true' : 'false');
        if(mark_changed) window.map_need_save = true;
    }

    window.change_enable_intro = function() {
        var enable_intro = $('#enable_intro').is(':checked');
        if(enable_intro) {
            $('.intro_body').removeClass('disabled');
        } else {
            $('.intro_body').addClass('disabled');
        }
    }

    window.change_enable_street = function() {
        var enable_street = $('#enable_map_street').is(':checked');
        var enable_satellite = $('#enable_map_satellite').is(':checked');
        if(!enable_satellite && !enable_street) return;
        if(enable_street) {
            $('.street_body').removeClass('disabled');
        } else {
            $('.street_body').addClass('disabled');
        }
    }

    window.change_enable_satellite = function() {
        var enable_street = $('#enable_map_street').is(':checked');
        var enable_satellite = $('#enable_map_satellite').is(':checked');
        if(!enable_satellite && !enable_street) return;
        if(enable_satellite) {
            $('.satellite_body').removeClass('disabled');
        } else {
            $('.satellite_body').addClass('disabled');
        }
    }

    window.change_street_style = function(style,only_attr) {
        window.map_style_sel=style;
        if(!only_attr) {
            $('.map_style#'+window.map_style.replaceAll('.','_p_')).trigger('click');
            var map_style = window.map_style;
        } else {
            window.map_need_save = true;
            var map_style = $('#map_default_tab .map_style img.style-highlight').parent().attr('id');
        }
        $('#use_street_attributions').prop('disabled',false);
        $('#street_maxzoom').prop('disabled',false);
        $('#street_minzoom').prop('disabled',false);
        switch(style) {
            case 'default':
                switch(map_style) {
                    case 'osm_free':
                        $('#street_attributions_d').val(osm_attributions);
                        break;
                    case 'arcgis_street':
                    case 'arcgis_topo':
                        $('#street_attributions_d').val(arcgis_attributions);
                        break;
                }
                if(!$('#map_default_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_default_tab .map_style:first-child').trigger('click');
                }
                break;
            case 'custom':
                $('#street_attributions_d').val(osm_attributions);
                break;
            case 'maptiler':
                $('#street_attributions_d').val(maptiler_attributions);
                if(!$('#map_maptiler_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_maptiler_tab .map_style:first-child').trigger('click');
                }
                break;
            case 'carto':
                $('#street_attributions_d').val(carto_attributions);
                if(!$('#map_carto_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_carto_tab .map_style:first-child').trigger('click');
                }
                break;
            case 'stadia':
                $('#street_attributions_d').val(stadia_attributions);
                if(!$('#map_stadia_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_stadia_tab .map_style:first-child').trigger('click');
                }
                break;
            case 'here':
                $('#street_attributions_d').val(here_attributions);
                if(!$('#map_here_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_here_tab .map_style:first-child').trigger('click');
                }
                break;
            case 'google':
                $('#street_attributions_d').val(google_attributions);
                if(!$('#map_google_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_google_tab .map_style:first-child').trigger('click');
                }
                break;
            case 'openfreemap':
                $('#use_street_attributions').prop('disabled',true);
                $('#street_maxzoom').prop('disabled',true);
                $('#street_minzoom').prop('disabled',true);
                $('#street_attributions_d').val(openfreemap_attributions);
                if(!$('#map_openfreemap_tab .map_style img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_openfreemap_tab .map_style:first-child').trigger('click');
                }
                break;
        }
    }

    window.change_satellite_style = function(style,only_attr) {
        window.map_style_satellite_sel=style;
        if(!only_attr) {
            $('.map_style_satellite#'+window.map_style_satellite.replaceAll('.','_p_')).trigger('click');
        } else {
            window.map_need_save = true;
        }
        switch(style) {
            case 'default':
                $('#satellite_attributions_d').val(arcgis_attributions);
                if(!$('#map_default_sat_tab .map_style_satellite img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_default_sat_tab .map_style_satellite:first-child').trigger('click');
                }
                break;
            case 'custom':
                $('#satellite_attributions_d').val(arcgis_attributions);
                break;
            case 'maptiler':
                $('#satellite_attributions_d').val(maptiler_attributions);
                if(!$('#map_maptiler_sat_tab .map_style_satellite img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_maptiler_sat_tab .map_style_satellite:first-child').trigger('click');
                }
                break;
            case 'here':
                $('#satellite_attributions_d').val(here_attributions);
                if(!$('#map_here_sat_tab .map_style_satellite img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_here_sat_tab .map_style_satellite:first-child').trigger('click');
                }
                break;
            case 'google':
                $('#satellite_attributions_d').val(google_attributions);
                if(!$('#map_google_sat_tab .map_style_satellite img').hasClass('style-highlight')) {
                    if(!only_attr) $('#map_google_sat_tab .map_style_satellite:first-child').trigger('click');
                }
                break;
        }
    }

    window.change_use_street_attributions = function() {
        if($('#use_street_attributions').is(':checked')) {
            $('#street_attributions').prop('disabled',false);
        } else {
            $('#street_attributions').prop('disabled',true);
        }
    }

    window.change_use_satellite_attributions = function() {
        if($('#use_satellite_attributions').is(':checked')) {
            $('#satellite_attributions').prop('disabled',false);
        } else {
            $('#satellite_attributions').prop('disabled',true);
        }
    }

    window.switch_dark_mode = function() {
        if(window.localStorage.getItem("dark_mode")=='1') {
            var dark_mode = 1;
        } else {
            var dark_mode = 0;
        }
        if(dark_mode==0) {
            window.localStorage.setItem("dark_mode",'1');
            $('.btn_mode_switcher').attr('id','btn_dark_mode');
            $('.btn_mode_switcher').removeClass('fa-sun').addClass('fa-moon');
            document.body.classList.add("dark_mode");
            document.documentElement.classList.add('cc--darkmode');
        } else {
            window.localStorage.setItem("dark_mode",'0');
            $('.btn_mode_switcher').attr('id','btn_light_mode');
            $('.btn_mode_switcher').removeClass('fa-moon').addClass('fa-sun');
            document.body.classList.remove("dark_mode");
            document.documentElement.classList.remove('cc--darkmode');
        }
    }

    window.change_marker_type = function() {
        var type = $('#type option:selected').attr('id');
        if(type=='default') {
            $('#link_t').prop('disabled',true);
        } else {
            $('#link_t').prop('disabled',false);
        }
    }

    window.open_modal_geodata_categories = function(id_geodata,id_categories) {
        $('#btn_save_geodata_category').attr('onclick','save_geodata_categories('+id_geodata+');');
        $('#category option').prop('selected',false);
        var array_categories = id_categories.split(",");
        $.each(array_categories,function(index,id_category) {
            if(id_category!='') {
                $('#category option[id='+id_category+']').prop('selected',true);
            }
        });
        $('#modal_geodata_categories').modal('show');
        $('#category').selectpicker('render');
    }

    window.open_modal_geodata_content = function(id_geodata) {
        $('#modal_geodata_content').modal('show');
        $.ajax({
            url: "ajax/get_geodata_content.php",
            type: "POST",
            data: {
                id: id_geodata,
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                var content = rsp.content;
                window.geodata_content_editor.root.innerHTML = content;
                $.each(rsp.array_lang,function(lang,array_lang) {
                    var content_l = array_lang['content'];
                    window.geodata_content_editor_lang[lang].root.innerHTML = content_l;
                });
                $('#btn_save_geodata_content').attr('onclick','save_geodata_content('+id_geodata+');');
            }, error: function() {
                $('#modal_geodata_content').modal('hide');
            }
        });
    }

    window.open_modal_geodata_style = function(id_geodata,style_json,file) {
        $('#btn_save_geodata_style').attr('onclick','save_geodata_style('+id_geodata+');');
        if(file.toLowerCase().split('.').pop()=='kml' || file.toLowerCase().split('.').pop()=='kmz') {
            $('#use_kml_style').parent().show();
        } else {
            $('#use_kml_style').parent().hide();
        }
        var json = null;
        if(style_json!=='' && style_json!==null && style_json!==undefined) {
            try {
                json = JSON.parse(style_json);
            } catch (e) {
                json = null;
            }
        }
        if(json===null) {
            style_json = '{' +
                '"use_kml_style": 1,' +
                '  "Point": {' +
                '    "type": "Point",' +
                '    "style": {' +
                '      "fill": {' +
                '        "color": "rgba(255, 255, 0, 0.4)"' +
                '      },' +
                '      "radius": 5,' +
                '      "stroke": {' +
                '        "color": "rgb(255, 255, 0)",' +
                '        "width": 1' +
                '      }' +
                '    }' +
                '  },' +
                '  "LineString": {' +
                '    "type": "LineString",' +
                '    "style": {' +
                '      "stroke": {' +
                '        "color": "rgb(0, 0, 255)",' +
                '        "width": 3' +
                '      }' +
                '    }' +
                '  },' +
                '  "MultiLineString": {' +
                '    "type": "MultiLineString",' +
                '    "style": {' +
                '      "stroke": {' +
                '        "color": "rgb(0, 255, 0)",' +
                '        "width": 3' +
                '      }' +
                '    }' +
                '  },' +
                '  "Polygon": {' +
                '    "type": "Polygon",' +
                '    "style": {' +
                '      "stroke": {' +
                '        "color": "rgb(255, 0, 0)",' +
                '        "width": 3' +
                '      },' +
                '      "fill": {' +
                '        "color": "rgba(255, 0, 0, 0.1)"' +
                '      }' +
                '    }' +
                '  },' +
                '  "MultiPolygon": {' +
                '    "type": "MultiPolygon",' +
                '    "style": {' +
                '      "stroke": {' +
                '        "color": "rgb(255, 0, 0)",' +
                '        "width": 3' +
                '      },' +
                '      "fill": {' +
                '        "color": "rgba(255, 0, 0, 0.1)"' +
                '      }' +
                '    }' +
                '  }' +
                '}';
            json = JSON.parse(style_json);
        }
        geodata_json_to_data(json);
        $('#modal_geodata_style').modal('show');
    }

    window.save_geodata_style = function(id_geodata) {
        var style = geodata_data_to_json();
        $('#modal_geodata_style button').addClass('disabled');
        $.ajax({
            url: "ajax/save_geodata_style.php",
            type: "POST",
            data: {
                id_geodata: id_geodata,
                style: style
            },
            async: true,
            success: function (json) {
                $('#geodata_table').DataTable().ajax.reload();
                $('#modal_geodata_style').modal('hide');
                $('#modal_geodata_style button').removeClass('disabled');
            },
            error: function() {
                $('#modal_geodata_style button').removeClass('disabled');
            }
        });
    }

    function geodata_json_to_data(styleJson) {
        for (const type in styleJson) {
            const data = styleJson[type].style;
            switch (type) {
                case "Point":
                    document.getElementById('pointFillColor').value = data.fill.color;
                    document.getElementById('pointRadius').value = data.radius;
                    document.getElementById('pointStrokeColor').value = data.stroke.color;
                    document.getElementById('pointStrokeWidth').value = data.stroke.width;
                    break;
                case "LineString":
                    document.getElementById('lineStringStrokeColor').value = data.stroke.color;
                    document.getElementById('lineStringStrokeWidth').value = data.stroke.width;
                    break;
                case "MultiLineString":
                    document.getElementById('multiLineStringStrokeColor').value = data.stroke.color;
                    document.getElementById('multiLineStringStrokeWidth').value = data.stroke.width;
                    break;
                case "Polygon":
                    document.getElementById('polygonStrokeColor').value = data.stroke.color;
                    document.getElementById('polygonStrokeWidth').value = data.stroke.width;
                    document.getElementById('polygonFillColor').value = data.fill.color;
                    break;
                case "MultiPolygon":
                    document.getElementById('multiPolygonStrokeColor').value = data.stroke.color;
                    document.getElementById('multiPolygonStrokeWidth').value = data.stroke.width;
                    document.getElementById('multiPolygonFillColor').value = data.fill.color;
                    break;
                case 'use_kml_style':
                    if(parseInt(styleJson[type])==1) {
                        $('#use_kml_style').prop('checked',true);
                    } else {
                        $('#use_kml_style').prop('checked',false);
                    }
                    break;
                default:
                    console.warn(`Unknown type: ${type}`);
            }
        }
        $('#pointFillColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#pointStrokeColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#lineStringStrokeColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#multiLineStringStrokeColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#polygonStrokeColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#polygonFillColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#multiPolygonStrokeColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
        $('#multiPolygonFillColor').spectrum({
            type: "text",
            preferredFormat: "rgb",
            showAlpha: true,
            showButtons: false,
            allowEmpty: false
        });
    }

    function geodata_data_to_json() {
        const styleJson = {
            'use_kml_style': $('#use_kml_style').is(':checked') ? 1 : 0,
            "Point": {
                "type": "Point",
                "style": {
                    "fill": {
                        "color": document.getElementById('pointFillColor').value
                    },
                    "radius": parseFloat(document.getElementById('pointRadius').value),
                    "stroke": {
                        "color": document.getElementById('pointStrokeColor').value,
                        "width": parseFloat(document.getElementById('pointStrokeWidth').value)
                    }
                }
            },
            "LineString": {
                "type": "LineString",
                "style": {
                    "stroke": {
                        "color": document.getElementById('lineStringStrokeColor').value,
                        "width": parseFloat(document.getElementById('lineStringStrokeWidth').value)
                    }
                }
            },
            "MultiLineString": {
                "type": "MultiLineString",
                "style": {
                    "stroke": {
                        "color": document.getElementById('multiLineStringStrokeColor').value,
                        "width": parseFloat(document.getElementById('multiLineStringStrokeWidth').value)
                    }
                }
            },
            "Polygon": {
                "type": "Polygon",
                "style": {
                    "stroke": {
                        "color": document.getElementById('polygonStrokeColor').value,
                        "width": parseFloat(document.getElementById('polygonStrokeWidth').value)
                    },
                    "fill": {
                        "color": document.getElementById('polygonFillColor').value
                    }
                }
            },
            "MultiPolygon": {
                "type": "MultiPolygon",
                "style": {
                    "stroke": {
                        "color": document.getElementById('multiPolygonStrokeColor').value,
                        "width": parseFloat(document.getElementById('multiPolygonStrokeWidth').value)
                    },
                    "fill": {
                        "color": document.getElementById('multiPolygonFillColor').value
                    }
                }
            }
        };
        return JSON.stringify(styleJson, null, 2);
    }

    window.save_geodata_categories = function(id_geodata) {
        $('#modal_geodata_categories button').addClass('disabled');
        var categories_t = $('#category option');
        var categories = [];
        $(categories_t).each(function(index, elem){
            var id = $(this).attr('id');
            if($(this).is(':selected') && !$(this).is(':disabled')) {
                categories.push(id);
            }
        });
        $.ajax({
            url: "ajax/save_geodata_categories.php",
            type: "POST",
            data: {
                id_geodata: id_geodata,
                id_categories: categories
            },
            async: true,
            success: function (json) {
                $('#geodata_table').DataTable().ajax.reload();
                $('#modal_geodata_categories').modal('hide');
                $('#modal_geodata_categories button').removeClass('disabled');
            },
            error: function() {
                $('#modal_geodata_categories button').removeClass('disabled');
            }
        });
    }

    window.generate_favicons = function(url) {
        if(url=='manual') {
            var url_ajax = '../services/generate_favicons.php?what=all';
            $('#modal_pwa').modal('show');
        } else {
            var url_ajax = url;
        }
        $.ajax({
            url: url_ajax,
            type: "POST",
            async: true,
            success: function() {
                if(url=='manual') {
                    $('#modal_pwa').modal('hide');
                }
            },
            error: function() {
                if(url=='manual') {
                    $('#modal_pwa').modal('hide');
                }
            }
        })
    }

    window.delete_song = function() {
        window.song = '';
        window.map_need_save = true;
        $('#div_delete_song').hide();
        $('#div_player_song').hide();
        $('#div_upload_song').show();
        $('#div_player_song audio').attr('src','');
    }

    window.change_song_bg_volume = function() {
        var volume = $('#song_bg_volume').val();
        $('#song_bg_volume_value').html(volume*100+'%');
    }

    window.change_song_volume = function() {
        var volume = $('#song_volume').val();
        $('#song_volume_value').html(volume*100+'%');
    }

    window.delete_marker_song = function() {
        window.song = '';
        window.marker_need_save = true;
        $('#div_delete_song').hide();
        $('#div_player_song').hide();
        $('#div_upload_song').show();
        $('#div_player_song audio').attr('src','');
    }

    window.check_set_address_position = function() {
        if($('#street').val()!=='' || $('#city').val()!=='' || $('#postal_code').val()!=='' || $('#country').val()!=='' || $('#county').val()!=='' || $('#state').val()!=='') {
            $('#btn_address_position').removeClass('disabled');
        } else {
            $('#btn_address_position').addClass('disabled');
        }
    }

    window.check_set_position = function() {
        if($('#latitude_edit').val()!=='' && $('#longitude_edit').val()!=='') {
            $('#btn_set_position').removeClass('disabled');
            $('#btn_position_address').removeClass('disabled');
        } else {
            $('#btn_set_position').addClass('disabled');
            $('#btn_position_address').addClass('disabled');
        }
    }

    window.change_geocoding_provider = function() {
        if($('#geocoding_provider option:selected').attr('id')=='google') {
            $('#google_api_key').prop('disabled',false);
        } else {
            $('#google_api_key').prop('disabled',true);
        }
    }

    function edit_all_categories() {
        $('.cat_tr').each(function() {
            var id = $(this).data('id');
            edit_category(id);
        })
    }

    window.remove_cat_icon = function(id) {
        $('#cat_tr_'+id+' #cat_'+id+'_icon').val('');
        $('#cat_tr_'+id+' #cat_'+id+'_icon_preview').removeClass();
        $('#cat_tr_'+id+' .btn_delete_cat_icon').addClass('disabled');
    }

    window.edit_category = function(id) {
        var name = $('#cat_tr_'+id+' .name').val();
        var icon = $('#cat_tr_'+id+' #cat_'+id+'_icon').val();
        var background = $('#cat_tr_'+id+' .background').val();
        var color = $('#cat_tr_'+id+' .color').val();
        var position = $('#cat_tr_'+id+' .position').val();
        var array_lang = {};
        array_lang['name'] = {};
        $('.input_lang[data-target-id="cat_name_'+id+'"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['name'][lang]=value;
        });
        if(name!='') {
            var array_lang_json = JSON.stringify(array_lang);
            $.ajax({
                url: "ajax/edit_category.php",
                type: "POST",
                data: {
                    id: id,
                    name: name,
                    icon: icon,
                    background: background,
                    color: color,
                    position: position,
                    array_lang: array_lang_json
                },
                async: false,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#cat_tr_'+id+' .name').addClass('success-highlight');
                        setTimeout(function() {
                            $('#cat_tr_'+id+' .name').removeClass('success-highlight');
                        },500);
                    } else {
                        $('#cat_tr_'+id+' .name').addClass('error-highlight');
                        setTimeout(function() {
                            $('#cat_tr_'+id+' .name').removeClass('error-highlight');
                        },500);
                    }
                }
            });
        }
    }

    window.modal_delete_category_map = function(id) {
        $('#btn_delete_category').attr('onclick','delete_category_map('+id+');');
        $('#modal_delete_category').modal("show");
    }

    window.delete_category_map = function (id) {
        $('#modal_delete_category button').addClass("disabled");
        $.ajax({
            url: "ajax/delete_category_map.php",
            type: "POST",
            data: {
                id: id
            },
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#modal_delete_category button').removeClass("disabled");
                    $('#modal_delete_category').modal("hide");
                    $('#cat_tr_'+id).remove();
                } else {
                    $('#modal_delete_category button').removeClass("disabled");
                }
            }
        });
    };

    window.add_category = function () {
        var name = $('#category_name').val();
        var array_lang = {};
        array_lang['name'] = {};
        $('.input_lang[data-target-id="name"]').each(function() {
            var lang = $(this).attr('data-lang');
            var value = $(this).val();
            array_lang['name'][lang]=value;
        });
        if(name!='') {
            var array_lang_json = JSON.stringify(array_lang);
            $('#modal_add_category button').addClass("disabled");
            $.ajax({
                url: "ajax/add_category.php",
                type: "POST",
                data: {
                    name: name,
                    array_lang: array_lang_json
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#modal_add_category button').removeClass("disabled");
                        $('#modal_add_category').modal("hide");
                        var id = rsp.id;
                        $('#category').append("<option id='"+id+"' selected>"+name+"</option>");
                        $('#category').selectpicker('refresh');
                        var val = $('#category').selectpicker('val');
                        $('#category').selectpicker('val', val);
                    } else {
                        $('#modal_add_category button').removeClass("disabled");
                    }
                }
            });
        }
    }

    window.add_category_s = function () {
        var name = $('#cat_tr_new .name').val();
        var icon = $('#cat_tr_new #cat_new_icon').val();
        var background = $('#cat_tr_new .background').val();
        var color = $('#cat_tr_new .color').val();
        var position = $('#cat_tr_new .position').val();
        if(name!='') {
            $('#btn_add_category').addClass("disabled");
            $.ajax({
                url: "ajax/add_category.php",
                type: "POST",
                data: {
                    name: name,
                    icon: icon,
                    background: background,
                    color: color,
                    position: position
                },
                async: true,
                success: function (json) {
                    var rsp = JSON.parse(json);
                    if (rsp.status == "ok") {
                        $('#btn_add_category').removeClass("disabled");
                        $('#cat_tr_new .name').val('');
                        $('#cat_tr_new .background').val('#f8f9fa');
                        $('#cat_tr_new .color').val('#000000');
                        $('#cat_tr_new #cat_new_icon').val('');
                        $('#cat_new_icon_preview').removeClass();
                        get_categories();
                    } else {
                        $('#cat_tr_new .name').addClass('error-highlight');
                        setTimeout(function() {
                            $('#cat_tr_new .name').removeClass('error-highlight');
                        },500);
                    }
                }
            });
        } else {
            $('#cat_tr_new .name').addClass('error-highlight');
            setTimeout(function() {
                $('#cat_tr_new .name').removeClass('error-highlight');
            },500);
            $('#cat_tr_new .name').focus();
        }
    }

    window.get_categories = function() {
        $.ajax({
            url: "ajax/get_categories_map.php",
            type: "POST",
            async: true,
            success: function (json) {
                var rsp = JSON.parse(json);
                if (rsp.status == "ok") {
                    $('#table_categories tbody').html(rsp.html).promise().done(function() {
                        $('.icon_picker_cat').each(function() {
                            var id = $(this).attr('id');
                            IconPicker.Run('#'+id, function(){
                                var id_cat = id.replace('GetIconPicker_cat_','');
                                $('#cat_tr_'+id_cat+' .btn_delete_cat_icon').removeClass('disabled');
                            });
                        });
                        $('.cat_tr .background').each(function() {
                            $(this).spectrum({
                                type: "text",
                                preferredFormat: "hex",
                                showAlpha: false,
                                showButtons: true,
                                allowEmpty: false,
                                cancelText: window.backend_labels.cancel,
                                chooseText: window.backend_labels.choose,
                            });
                        });
                        $('.cat_tr .color').each(function() {
                            $(this).spectrum({
                                type: "text",
                                preferredFormat: "hex",
                                showAlpha: false,
                                showButtons: true,
                                allowEmpty: false,
                                cancelText: window.backend_labels.cancel,
                                chooseText: window.backend_labels.choose,
                            });
                        });
                    });
                }
            }
        });
    }

    window.change_checkbox_geolocate = function() {
        if($('#checkbox_address_position').is(':checked') || $('#checkbox_position_address').is(':checked')) {
            $('#btn_batch_geocode').removeClass('disabled');
        } else {
            $('#btn_batch_geocode').addClass('disabled');
        }
    }

    window.gpsToDecimal = function(gpsData, hem) {
        const d = gpsData[0];
        const m = gpsData[1];
        const s = gpsData[2];
        const toFloat = v => (v.numerator || v[0]) / (v.denominator || v[1]);
        const deg = toFloat(d);
        const min = toFloat(m);
        const sec = toFloat(s);
        const decimal = deg + (min / 60) + (sec / 3600);
        return (hem === "S" || hem === "W") ? -decimal : decimal;
    }

    window.tripadvisor_search = function() {
        const resultsList = document.getElementById('tripadvisor_results');
        const formData = new FormData();
        const query = document.getElementById('tripadvisor_query').value.trim();
        formData.set('query', query);
        const lat = document.getElementById('tripadvisor_lat').value.trim();
        const lng = document.getElementById('tripadvisor_lng').value.trim();
        formData.set('lat', lat);
        formData.set('lng', lng);
        resultsList.innerHTML = '<li class="list-group-item">'+window.backend_labels.loading+'</li>';
        fetch('ajax/tripadvisor_search.php', {
            method: 'POST',
            body: formData
        })
            .then(res => res.json())
            .then(data => {
                resultsList.innerHTML = '';
                if (data.error) {
                    resultsList.innerHTML = '<li class="list-group-item">'+data.error+'</li>';
                    return;
                }
                if (!data.data || data.data.length === 0) {
                    resultsList.innerHTML = '<li class="list-group-item">'+window.backend_labels.no_results+'</li>';
                    return;
                }
                data.data.forEach(item => {
                    const li = document.createElement('li');
                    li.className = 'list-group-item list-group-item-action';
                    li.style.cursor = 'pointer';
                    li.innerHTML = `<strong>${item.name}</strong><br><small>${item.address_obj.address_string}</small>`;
                    li.onclick = () => {
                        document.getElementById('tripadvisor_location_id').value = item.location_id;
                        $('#tripadvisor_modal').modal('hide');
                    };
                    resultsList.appendChild(li);
                });
            })
            .catch(err => {
                resultsList.innerHTML = '<li class="list-group-item text-danger">'+err+'</li>';
            });
    }

    window.tripadvisor_info = function() {
        const locationId = document.getElementById('tripadvisor_location_id').value.trim();
        const errorBox = document.getElementById('tripadvisor_info_error');
        const wrapper = document.getElementById('tripadvisor_info_wrapper');
        errorBox.classList.add('d-none');
        wrapper.style.display = 'block';
        ['name', 'rating', 'reviews', 'link', 'address'].forEach(field => {
            document.getElementById(`tripadvisor_info_${field}`).innerHTML = '<i class="fas fa-circle-notch fa-spin"></i>';
        });
        fetch('ajax/tripadvisor_info.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({ location_id: locationId })
        })
            .then(res => res.json())
            .then(data => {
                if (data.error) {
                    errorBox.classList.remove('d-none');
                    errorBox.innerHTML = data.error;
                    wrapper.style.display = 'none';
                } else {
                    document.getElementById('tripadvisor_info_name').innerHTML = data.name || '-';
                    document.getElementById('tripadvisor_info_address').innerHTML = data.address_obj.address_string || '-';
                    document.getElementById('tripadvisor_info_rating').innerHTML = data.rating || '-';
                    document.getElementById('tripadvisor_info_reviews').innerHTML = data.num_reviews || '-';
                    document.getElementById('tripadvisor_info_link').innerHTML = '<a target="_blank" href="'+data.web_url+'">'+data.web_url+'</a>' || '-';
                }
            })
            .catch(err => {
                errorBox.classList.remove('d-none');
                errorBox.innerHTML = 'Error fetching info';
                wrapper.style.display = 'none';
                console.error(err);
            });

        $('#tripadvisor_info_modal').modal('show');
    }

    window.rotate_image = function(image,id,angle) {
        $.ajax({
            url: "ajax/rotate_image.php",
            type: "POST",
            data: {
                id_image: id,
                filename: image,
                rotate: angle
            },
            async: false,
            success: function (rsp) {
                if(rsp && rsp.startsWith("image_")) {
                    var new_image_name = rsp;
                    $('#image_gallery a[data-id="'+id+'"]').attr('data-image',new_image_name);
                    $('#image_gallery a[data-id="'+id+'"] img').attr('src','../viewer/marker_images/thumb/'+new_image_name);
                }
            }
        });
    }

    window.switch_input_language = function (lang,default_lang,elem,bulk=true) {
        var orig_elem = elem;
        window.selected_language=lang;
        var url = new URL(location.href);
        var url_params = new URLSearchParams(url.search);
        var page_section = url_params.get('p');
        sessionStorage.setItem('lang_'+window.id_map+'_'+page_section,lang);
        $('#dropdown_lang_'+elem+' img').attr("src","img/flags_lang/"+lang+'.png?v=3');
        switch(elem) {
            case 'cat_name':
                $('.cat_name_lang').hide();
                if(lang!=default_lang) {
                    $('.cat_name').hide();
                    $('.cat_name_lang[data-lang="'+lang+'"]').show();
                } else {
                    $('.cat_name').show();
                }
                break;
            case 'default_am_placeholders':
                $('.am_placeholder_lang').hide();
                if(lang!=default_lang) {
                    $('.am_placeholder').hide();
                    $('.am_placeholder_lang[data-lang="'+lang+'"]').show();
                } else {
                    $('.am_placeholder').show();
                }
                break;
            case 'info_content':
            case 'hours_div':
            case 'description_div':
            case 'geodata_content':
            case 'extra_button_value_1':
            case 'extra_field_value_1':
            case 'extra_field_value_2':
            case 'extra_field_value_3':
            case 'extra_field_value_4':
            case 'extra_field_value_5':
            case 'extra_field_value_6':
            case 'extra_field_value_7':
            case 'extra_field_value_8':
            case 'extra_field_value_9':
            case 'extra_field_value_10':
            case 'extra_field_value_11':
            case 'extra_field_value_12':
            case 'extra_field_value_13':
            case 'extra_field_value_14':
            case 'extra_field_value_15':
            case 'extra_field_value_16':
            case 'extra_field_value_17':
            case 'extra_field_value_18':
            case 'extra_field_value_19':
            case 'extra_field_value_20':
                $('.input_lang[data-target-id="'+elem+'"]').parent().hide();
                if(lang!=default_lang) {
                    $('#'+elem).parent().hide();
                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').parent().show();
                    if(!bulk) $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').focus();
                } else {
                    $('#'+elem).parent().show();
                    if(!bulk) $('#'+elem).focus();
                }
                break;
            case 'meta_title':
            case 'meta_description':
                $('.input_lang[data-target-id="'+elem+'"]').hide();
                if(lang!=default_lang) {
                    $('#'+elem).hide();
                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').show();
                    if(!bulk) $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').focus();
                } else {
                    $('#'+elem).show();
                    if(!bulk) $('#'+elem).focus();
                }
                change_meta_title();
                change_meta_description();
                break;
            case 'link':
                $('.input_lang[data-target-id="'+elem+'"]').hide();
                $('.input_lang[data-target-id="open_link"]').hide();
                $('.input_lang[data-target-id="copy_link"]').hide();
                $('.input_lang[data-target-id="qrcode_link"]').hide();
                $('.input_lang[data-target-id="share_link"]').hide();
                if(lang!=default_lang) {
                    $('#'+elem).hide();
                    $('#open_link').hide();
                    $('#copy_link').hide();
                    $('#qrcode_link').hide();
                    $('#share_link').hide();
                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="open_link"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="copy_link"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="qrcode_link"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="share_link"][data-lang="'+lang+'"]').show();
                } else {
                    $('#'+elem).show();
                    $('#open_link').show();
                    $('#copy_link').show();
                    $('#qrcode_link').show();
                    $('#share_link').show();
                }
                break;
            case 'link_f':
                $('.input_lang[data-target-id="'+elem+'"]').hide();
                $('.input_lang[data-target-id="open_link_f"]').hide();
                $('.input_lang[data-target-id="copy_link_f"]').hide();
                $('.input_lang[data-target-id="qrcode_link_f"]').hide();
                if(lang!=default_lang) {
                    $('#'+elem).hide();
                    $('#open_link_f').hide();
                    $('#copy_link_f').hide();
                    $('#qrcode_link_f').hide();
                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="open_link_f"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="copy_link_f"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="qrcode_link_f"][data-lang="'+lang+'"]').show();
                } else {
                    $('#'+elem).show();
                    $('#open_link_f').show();
                    $('#copy_link_f').show();
                    $('#qrcode_link_f').show();
                }
                break;
            case 'code':
                $('.input_lang[data-target-id="'+elem+'"]').hide();
                $('.input_lang[data-target-id="copy_code"]').hide();
                if(lang!=default_lang) {
                    $('#'+elem).hide();
                    $('#copy_code').hide();
                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').show();
                    $('.input_lang[data-target-id="copy_code"][data-lang="'+lang+'"]').show();
                } else {
                    $('#'+elem).show();
                    $('#copy_code').show();
                }
                break;
            default:
                $('.input_lang[data-target-id="'+elem+'"]').hide();
                if(lang!=default_lang) {
                    $('#'+elem).hide();
                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').show();
                    if(!bulk) $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').focus();
                } else {
                    $('#'+elem).show();
                    if(!bulk) $('#'+elem).focus();
                }
                break;
        }
        try {
            if(lang!=default_lang) {
                if(!bulk) {
                    var value = $('.input_lang[data-target-id="' + elem + '"][data-lang="' + lang + '"]').val();
                    $('.input_lang[data-target-id="' + elem + '"][data-lang="' + lang + '"]').val('');
                    $('.input_lang[data-target-id="' + elem + '"][data-lang="' + lang + '"]').val(value);
                }
                switch (orig_elem) {
                    case 'default_am_placeholders':
                        $('.am_placeholder_lang').each(function() {
                            var elem = $(this).attr('data-target-id');
                            $(this).attr('placeholder',$('#'+elem).val());
                        });
                        break;
                    case 'cat_name':
                        $('.cat_name_lang').each(function() {
                            var elem = $(this).attr('data-target-id');
                            $(this).attr('placeholder',$('#'+elem).val());
                        });
                        break;
                    case 'hours_div':
                        window.hours_editor_lang[lang].root.dataset.placeholder = truncateString(window.hours_editor.getText(),100);
                        break;
                    case 'description_div':
                        window.description_editor_lang[lang].root.dataset.placeholder = truncateString(window.description_editor.getText(),100);
                        break;
                    case 'geodata_content':
                        window.geodata_content_editor_lang[lang].root.dataset.placeholder = truncateString(window.geodata_content_editor.getText(),100);
                        break;
                    default:
                        $('.input_lang[data-target-id="'+elem+'"][data-lang="'+lang+'"]').attr('placeholder',$('#'+elem).val());
                        break;
                }
            } else {
                if(!bulk) {
                    var value = $('#' + elem).val();
                    $('#' + elem).val('');
                    $('#' + elem).val(value);
                }
            }
        } catch (e) {}
        $('.lang_input_switcher[data-elem="'+orig_elem+'"] .translate_deepl_btn').hide();
        if (window.deepl===1 && (($('#'+elem).is(':input:not([readonly]):not(#link):not(#link_f):not(#code)')) || (orig_elem.startsWith("extra_field_value_")) || (orig_elem === 'extra_button_value_1') || (orig_elem === 'hours_div') || (orig_elem === 'description_div') || (orig_elem === 'geodata_content') || (orig_elem === 'default_am_placeholders') || (orig_elem === 'cat_name') || (orig_elem=='info_content') || (orig_elem=='description_mc') || (orig_elem=='description_mc_edit') || (orig_elem=='description_story') || (orig_elem=='description_story_edit'))) {
            if(lang!=default_lang) {
                var value_check = '';
                if (orig_elem.startsWith("extra_field_value_")) {
                    var i = orig_elem.replace("extra_field_value_","");
                    value_check = (window.editor_html_extra_fields && window.editor_html_extra_fields[i]) ? window.editor_html_extra_fields[i].getValue() : $('#'+orig_elem).text();
                } else {
                    switch (orig_elem) {
                        case 'default_am_placeholders':
                            value_check = '';
                            $('.am_placeholder').each(function() {
                                var value = $(this).val();
                                if(value!='') value_check = value;
                            });
                            break;
                        case 'cat_name':
                            value_check = '';
                            $('.cat_name').each(function() {
                                var value = $(this).val();
                                if(value!='') value_check = value;
                            });
                            break;
                        case 'description_mc':
                        case 'description_story':
                            value_check = window.editor_html_description ? window.editor_html_description.getValue() : $('#'+orig_elem).text();
                            break;
                        case 'description_mc_edit':
                        case 'description_story_edit':
                            value_check = window.editor_html_description_edit ? window.editor_html_description_edit.getValue() : $('#'+orig_elem).text();
                            break;
                        case 'extra_button_value_1':
                            value_check = window.editor_html_extra_button_1 ? window.editor_html_extra_button_1.getValue() : $('#'+orig_elem).text();
                            break;
                        case 'info_content':
                            try { value_check = $('#'+orig_elem).summernote('code'); } catch (e) { value_check = $('#'+orig_elem).html(); }
                            break;
                        case 'hours_div':
                            value_check = window.hours_editor ? window.hours_editor.root.innerHTML : $('#'+orig_elem).html();
                            break;
                        case 'description_div':
                            value_check = window.description_editor ? window.description_editor.root.innerHTML : $('#'+orig_elem).html();
                            break;
                        case 'geodata_content':
                            value_check = window.geodata_content_editor ? window.geodata_content_editor.root.innerHTML : $('#'+orig_elem).html();
                            break;
                        default:
                            try {
                                value_check = $('#'+orig_elem).val();
                            } catch (e) {}
                            break;
                    }
                }
                if(value_check==='<p><br></p>') value_check='';
                if(value_check!='') {
                    $('.lang_input_switcher[data-elem="'+orig_elem+'"] .translate_deepl_btn').removeClass('disabled');
                    $('.lang_input_switcher[data-elem="'+orig_elem+'"] .translate_deepl_btn').css('display','inline-block');
                } else {
                    $('.lang_input_switcher[data-elem="'+orig_elem+'"] .translate_deepl_btn').addClass('disabled');
                    $('.lang_input_switcher[data-elem="'+orig_elem+'"] .translate_deepl_btn').css('display','inline-block');
                }
            }
        }
        if(!bulk) {
            $('.lang_input_switcher:not([data-elem="'+orig_elem+'"])').each(function() {
                var elem_d = $(this).attr('data-elem');
                switch_input_language(lang,default_lang,elem_d,true);
            });
        }
    }

    function truncateString(str, num) {
        if (str.length <= num) {
            return str;
        }
        return str.slice(0, num) + '...';
    }

    window.translate_deepl_cats = function() {
        $('.cat_name').each(function() {
            var elem = $(this).attr('id');
            translate_deepl(elem);
        });
    }

    window.translate_deepl_default_am_placeholders = function() {
        $('.am_placeholder').each(function() {
            var elem = $(this).attr('id');
            translate_deepl(elem);
        });
    }

    window.translate_deepl = function (elem) {
        if (elem.startsWith("extra_field_value_")) {
            var i = elem.replace("extra_field_value_","");
            var text = window.editor_html_extra_fields[i].getValue();
        } else {
            switch (elem) {
                case 'description_mc':
                case 'description_story':
                    var text = window.editor_html_description.getValue();
                    break;
                case 'description_mc_edit':
                case 'description_story_edit':
                    var text = window.editor_html_description_edit.getValue();
                    break;
                case 'extra_button_value_1':
                    var text = window.editor_html_extra_button_1.getValue();
                    break;
                case 'info_content':
                    var text = $('#'+elem).summernote('code');
                    break;
                case 'hours_div':
                    var text = window.hours_editor.root.innerHTML;
                    break;
                case 'description_div':
                    var text = window.description_editor.root.innerHTML;
                    break;
                case 'geodata_content':
                    var text = window.geodata_content_editor.root.innerHTML;
                    break;
                default:
                    var text = $('#'+elem).val();
                    break;
            }
        }
        if(text==='<p><br></p>') text='';
        if(text!='') {
            $('.lang_input_switcher[data-elem="'+elem+'"] .translate_deepl_btn').addClass('disabled');
            $('.lang_input_switcher[data-elem="'+elem+'"] .translate_deepl_btn i').removeClass('fa-globe').addClass('fa-circle-notch').addClass('fa-spin');
            $.ajax({
                url: "ajax/translate_deepl.php",
                type: "POST",
                async: true,
                data: {
                    language: window.selected_language,
                    text: text
                },
                success: function (rsp) {
                    $('.lang_input_switcher[data-elem="'+elem+'"] .translate_deepl_btn').removeClass('disabled');
                    $('.lang_input_switcher[data-elem="'+elem+'"] .translate_deepl_btn i').addClass('fa-globe').removeClass('fa-circle-notch').removeClass('fa-spin');
                    if(rsp!='') {
                        rsp = rsp.replace(/^\s+|\s+$/g, '');
                        if (elem.startsWith("extra_field_value_")) {
                            var i = elem.replace("extra_field_value_","");
                            if(window.editor_html_extra_fields_langs[i] && window.editor_html_extra_fields_langs[i][window.selected_language]) {
                                window.editor_html_extra_fields_langs[i][window.selected_language].setValue(rsp);
                            } else {
                                $('.input_lang[data-target-id="'+elem+'"][data-lang="'+window.selected_language+'"]').text(rsp);
                            }
                        } else {
                            switch (elem) {
                                case 'description_mc':
                                case 'description_story':
                                    if(window.editor_html_description_langs[window.selected_language]) window.editor_html_description_langs[window.selected_language].setValue(rsp);
                                    break;
                                case 'description_mc_edit':
                                case 'description_story_edit':
                                    if(window.editor_html_description_edit_langs[window.selected_language]) window.editor_html_description_edit_langs[window.selected_language].setValue(rsp);
                                    break;
                                case 'extra_button_value_1':
                                    if(window.editor_html_extra_button_1_langs[window.selected_language]) {
                                        window.editor_html_extra_button_1_langs[window.selected_language].setValue(rsp);
                                    } else {
                                        $('.input_lang[data-target-id="'+elem+'"][data-lang="'+window.selected_language+'"]').text(rsp);
                                    }
                                    break;
                                case 'info_content':
                                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+window.selected_language+'"]').summernote('code',rsp);
                                    break;
                                case 'hours_div':
                                    if(window.hours_editor_lang[window.selected_language]) window.hours_editor_lang[window.selected_language].root.innerHTML=rsp;
                                    else $('.input_lang[data-target-id="'+elem+'"][data-lang="'+window.selected_language+'"]').html(rsp);
                                    break;
                                case 'description_div':
                                    if(window.description_editor_lang[window.selected_language]) window.description_editor_lang[window.selected_language].root.innerHTML=rsp;
                                    else $('.input_lang[data-target-id="'+elem+'"][data-lang="'+window.selected_language+'"]').html(rsp);
                                    break;
                                case 'geodata_content':
                                    if(window.geodata_content_editor_lang[window.selected_language]) window.geodata_content_editor_lang[window.selected_language].root.innerHTML=rsp;
                                    break;
                                default:
                                    $('.input_lang[data-target-id="'+elem+'"][data-lang="'+window.selected_language+'"]').val(rsp);
                                    break;
                            }
                        }
                        if(elem=='meta_title') {
                            $('.input_lang[data-target-id="meta_title"][data-lang="'+window.selected_language+'"]').trigger('input');
                            change_meta_title();
                        }
                        if(elem=='meta_description') {
                            $('.input_lang[data-target-id="meta_description"][data-lang="'+window.selected_language+'"]').trigger('input');
                            change_meta_description();
                        }
                    }
                }, error: function() {
                    $('.lang_input_switcher[data-elem="'+elem+'"] .translate_deepl_btn').removeClass('disabled');
                    $('.lang_input_switcher[data-elem="'+elem+'"] .translate_deepl_btn i').addClass('fa-globe').removeClass('fa-circle-notch').removeClass('fa-spin');
                }
            });
        }
    }

    window.open_preview_global_viewer = function () {
        var code_map = $('#map_selector option:selected').attr('data-code');
        $('#modal_preview_global .modal-body').append('<iframe style="width:100%;height:80vh;" allowfullscreen allow="gyroscope; accelerometer; xr; microphone *" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="../viewer/index.php?code='+code_map+'&nostat=1&ignore_embedded=1"></iframe>');
        $('#modal_preview_global').modal('show');
    }

    window.close_preview_global_viewer = function () {
        $('#modal_preview_global .modal-body').html('');
    }

    window.session_library = function (w) {
        $.ajax({
            url: "ajax/set_session_library.php",
            type: "POST",
            async: true,
            data: {
                w: w
            },
            success: function (json) {
                location.reload();
            }
        });
    }

    window.set_session_tab = function(page,tab) {
        $.ajax({
            url: "ajax/set_session_tab.php",
            type: "POST",
            data: {
                page: page,
                tab: tab
            },
            async: true,
            success: function (json) {}
        });
    }

    window.setTooltip = function(btn, message) {
        $(btn).tooltip('hide')
            .attr('data-original-title', message)
            .tooltip('show');
    }
    window.hideTooltip = function(btn) {
        setTimeout(function() {
            $(btn).tooltip('hide');
        }, 1000);
    }

    window.init_lazy_editor = function (elem, lang, id) {
        if (elem.startsWith('extra_field_value_')) {
            var i = elem.replace('extra_field_value_', '');
            if (!window.editor_html_extra_fields_langs[i]) window.editor_html_extra_fields_langs[i] = [];
            if (!window.editor_html_extra_fields_langs[i][lang]) {
                var editor = ace.edit(id);
                editor.session.setMode("ace/mode/html");
                editor.session.setUseWrapMode(true);
                editor.session.setOption('indentedSoftWrap', false);
                editor.setOption('enableLiveAutocompletion', true);
                editor.setShowPrintMargin(false);
                if ($('body').hasClass('dark_mode')) editor.setTheme("ace/theme/one_dark");
                if (window.rtl == 1) editor.setOption("rtl", true);
                window.editor_html_extra_fields_langs[i][lang] = editor;
                editor.focus();
            }
        } else if (elem === 'extra_button_value_1') {
            if (!window.editor_html_extra_button_1_langs[lang]) {
                var editor = ace.edit(id);
                editor.session.setMode("ace/mode/html");
                editor.session.setUseWrapMode(true);
                editor.session.setOption('indentedSoftWrap', false);
                editor.setOption('enableLiveAutocompletion', true);
                editor.setShowPrintMargin(false);
                if ($('body').hasClass('dark_mode')) editor.setTheme("ace/theme/one_dark");
                if (window.rtl == 1) editor.setOption("rtl", true);
                window.editor_html_extra_button_1_langs[lang] = editor;
                editor.focus();
            }
        } else if (elem === 'hours_div') {
            if (!window.hours_editor_lang[lang]) {
                var q = new Quill('#' + id, {
                    modules: { toolbar: window.quillToolbarOptions }, theme: 'snow'
                });
                window.hours_editor_lang[lang] = q;
                q.focus();
            }
        } else if (elem === 'description_div') {
            if (!window.description_editor_lang[lang]) {
                var q = new Quill('#' + id, {
                    modules: { toolbar: window.quillToolbarOptions }, theme: 'snow'
                });
                window.description_editor_lang[lang] = q;
                q.focus();
            }
        }
    };
})(jQuery);
