WME KeepMyLayers

(Beta) Resets WME layers to your preferred state plus other fancy stuff. — Note: Script was briefly broken for new users, but should now be fully operational!

目前為 2016-01-29 提交的版本,檢視 最新版本

// ==UserScript==
// @name            WME KeepMyLayers
// @namespace       https://greasyfork.org/users/11629-TheLastTaterTot
// @version         0.4.3.1
// @description     (Beta) Resets WME layers to your preferred state plus other fancy stuff. — Note: Script was briefly broken for new users, but should now be fully operational!
// @author          TheLastTaterTot
// @include         https://editor-beta.waze.com/*editor/*
// @include         https://www.waze.com/*editor/*
// @exclude         https://www.waze.com/*user/editor/*
// @grant           GM_getValue
// @grant           GM_setValue
// @grant           GM_deleteValue
// @grant           GM_setClipboard
// @run-at          document-start
// @icon            data:image/png;base64,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
// ==/UserScript==

//TODO: provide a sync between beta and production editor
//      make adding and removing layer sets easier
//      add an option to only auto-reset layers for PLs with layers
//      allow setting of other layers that don't show up in the WME Layers menu
//      show a summary of visible layers for each layer set
//      create a welcome msg for first time users and a (?) in pref pane to see it again

// ################################## DEBUG #####################################
/*
// Quiet log outputs from other scripts:
(function() {
    console.__log = console.log;
    console.log = function() {
        var args = arguments;
        //argArray = Object.keys(args).map(function (key) { return args[key] });

        if (!!(args['0'].substr(0, 8).indexOf('WMEKML') + 1)) {
            console.__log.apply(console, args);
        }
    };

    console.__debug = console.debug;
    console.debug = function() {
        var args = arguments;
        //argArray = Object.keys(args).map(function (key) { return args[key] });

        if (!!(args['0'].substr(0, 8).indexOf('WMEKML') + 1)) {
            console.__debug.apply(console, args);
        }
    };
})();
*/
function kmllog() {
    var args = arguments,
        argArray = Object.keys(args).map(function(key) {
            return args[key]
        }),
        kmllogCss = 'background: #444; color: #F75566';
    if (argArray.last == '/') argArray = argArray.splice(-1);
    console.debug('%cWMEKMLayers: %s', kmllogCss, argArray.join(' '));
}

// ################################## DEBUG #####################################

var kmlPLlayers = '',
    kmlPLlayerFilters,
    kmlPLhref = false,
    kmlPLhost = false,
    kmlPLpath = false,
    kmlayersBetaChk,
    kmlayersLangChk,
    kmlPLhrefLast20 = location.href.substr(-20);

if (localStorage.WME_KMLSettings) {

    var kmlayersStartupChk = [(localStorage.WME_KMLSettings.indexOf('&x') !== -1), (
        localStorage.WME_KMLSettings.indexOf('&b') !== -1), (localStorage.WME_KMLSettings
        .indexOf('&l') !== -1)];

    if (kmlPLhrefLast20.lastIndexOf('&kmlayers') === -1) { //not a layers-removal redirect
        if (!kmlayersStartupChk[0]) { // allow autocheck layers at startup
            kmlPLhref = location.href.match(/&layers=(\d+)/);
            if (kmlPLhref && kmlPLhref[1]) {
                kmlPLlayers = ('&kmlayers=' + kmlPLhref[1]);
                kmlPLhref = location.href.replace(kmlPLhref[0], '');

                if (localStorage.WME_KeepMyLayers_lF) {
                    kmlPLlayerFilters = JSON.parse(localStorage.WME_KeepMyLayers_lF);

                    kmlPLlayers = '&mapProblemFilter=' + kmlPLlayerFilters.mapProblem +
                        '&mapUpdateRequestFilter=' + kmlPLlayerFilters.mapUpdateRequest +
                        '&venueFilter=' + kmlPLlayerFilters.venue +
                        kmlPLlayers;
                }
            } // else PL has no layers

            requestAnimationFrame(function() {
                if (localStorage.WME_KeepMyLayers_lV) {
                    localStorage.layerVisibility = localStorage.WME_KeepMyLayers_lV;
                } // children
                if (localStorage.WME_KeepMyLayers_lF) {
                    localStorage.layerFilters = localStorage.WME_KeepMyLayers_lF;
                }
            });
        }
    }

    if (kmlayersStartupChk[1] && kmlPLhrefLast20.indexOf('&b') === -1) { // beta toggle check //&&
        kmlayersBetaChk = GM_getValue("WMEKMLayers_Beta");

        if (kmlayersBetaChk === true && //if set to beta-editor
            location.host.indexOf('editor-b') === -1) { //if PL is not editor-beta.waze.com
            kmlPLhost = 'https://editor-beta.waze.com';
        } else if (kmlayersBetaChk === false && //if set to production editor
            location.host.indexOf('www.waze') === -1) { //if PL is not www.waze.com
            kmlPLhost = 'http://www.waze.com';
        }
    }

    if (kmlayersStartupChk[2] && kmlPLhrefLast20.indexOf('&l') === -1) { // language check
        kmlayersLangChk = GM_getValue("WMEKMLayers_Lang");
        //kmllog('kmlayersLangChk', kmlayersLangChk);

        if (kmlayersLangChk === true || kmlayersLangChk === "true") { //if set to filter out language
            if ( location.pathname !== '/editor/') {
                kmlPLpath = '/editor/';
                kmlPLlayers = '&l' + kmlPLlayers;
            }
        } else if (kmlayersLangChk) { //is truthy
            var kmlPLpath_exemplar = '/' + kmlayersLangChk + '/editor/';
            if (location.pathname !== kmlPLpath_exemplar) {
                kmlPLpath = kmlPLpath_exemplar;
                kmlPLlayers = '&l' + kmlPLlayers;
            }
        }
    }

} else { //no save preferences yet... first time running on this (sub)domain

    if (kmlPLhrefLast20.indexOf('&b') === -1) { //beta-check not temporarily disabled
        kmlayersBetaChk = GM_getValue("WMEKMLayers_Beta");

        if (kmlayersBetaChk === true && //if set to beta-editor
            location.host.indexOf('editor-b') === -1) { //if PL is not editor-beta.waze.com
            kmlPLhost = 'https://editor-beta.waze.com';
        } else if (kmlayersBetaChk === false && //if set to production editor
            location.host.indexOf('www.waze') === -1) { //if PL is not www.waze.com
            kmlPLhost = 'http://www.waze.com';
        }
    }

    if (kmlPLhrefLast20.indexOf('&l') === -1) { //prevents accidental looping in case a locale page isn't found
        kmlayersLangChk = GM_getValue("WMEKMLayers_Lang");

        if (kmlayersLangChk === true || kmlayersLangChk === "true") { //if set to filter out language
            if ( location.pathname !== '/editor/') {
                kmlPLpath = '/editor/';
                kmlPLlayers = '&l' + kmlPLlayers;
            }
        } else if (kmlayersLangChk) { //is truthy
            var kmlPLpath_exemplar = '/' + kmlayersLangChk + '/editor/';
            if (location.pathname !== kmlPLpath_exemplar) {
                kmlPLpath = kmlPLpath_exemplar;
                kmlPLlayers = '&l' + kmlPLlayers;
            }
        }
    }
}

switch (true) {
    case (!kmlPLhost && !kmlPLpath && !kmlPLhref): //no modifications are necessary
        break;
    default:
        if (!kmlPLhost) kmlPLhost = location.origin;
        if (!kmlPLpath) kmlPLpath = location.pathname;
        if (!kmlPLhref) kmlPLhref = location.href;

        //mllog(location.origin, '/');
        //kmllog(location.pathname, '/');
        var kmlPLhref_temp = kmlPLhref.match(/editor\/(.*)/);
        //kmllog(kmlPLhost, kmlPLpath, kmlPLhref_temp[1], kmlPLlayers);

        location.replace(kmlPLhost + kmlPLpath + kmlPLhref_temp[1] + kmlPLlayers);
}

//==========================================================================
var resetLocalWithKMLayers = function() {
    if (localStorage.WME_KeepMyLayers_lV) {
        //sessionStorage.layerVisibility_orig = localStorage.layerVisibility; // save a duplicate as backup
        localStorage.layerVisibility = localStorage.WME_KeepMyLayers_lV;
    } // children
    if (localStorage.WME_KeepMyLayers_lF) {
        sessionStorage.layerFilters_orig = localStorage.layerFilters; // save a duplicate as backup
        localStorage.layerFilters = localStorage.WME_KeepMyLayers_lF;
    }
};

//==========================================================================
var KeepMyLayers = function() {
    var kml = Array(10), //counter
        kml_W_map_layers = unsafeWindow.Waze.map.layers,
        $ = unsafeWindow.$,
        myKMLayers, kmlVersion = '0.4';

    for (var kmli = 10; kmli--;) {
        kml[kmli] = 0;
    }
    // ---------------------------------------------------------------------
    var getSavedKMLayers = function() {
        var myKMLayers;

        if (typeof myKMLayers !== "undefined") {
            if (myKMLayers.visibleInLayersMenu !== undefined) {
                //kmllog('Replaced myKMLayers in memory with saved from disk.', '/');
                myKMLayers = JSON.parse(localStorage.WME_KeepMyLayers);
                myKMLayers.reset = false;
                return myKMLayers;
            } else {
                return false;
            }
        } else if (localStorage.WME_KeepMyLayers) {
            //kmllog('Found some saved settings to load!','/');
            myKMLayers = JSON.parse(localStorage.WME_KeepMyLayers);
            myKMLayers.reset = false;

            if (myKMLayers.visibleInLayersMenu !== undefined) { //check that required object key is present
                /* ~~~~~~ TEMP ~~~~~~~ */
                if (myKMLayers.visibleInLayersMenu.constructor !== Array) {
                    var tempHoldingVar = JSON.parse(JSON.stringify(myKMLayers.visibleInLayersMenu));
                    myKMLayers.visibleInLayersMenu = [tempHoldingVar];
                    myKMLayers.layerSetNames = ['My default layers'];
                    myKMLayers.idx = 0;
                }
                if (myKMLayers.visibleInLayersMenuRealName === undefined) {
                    myKMLayers.visibleInLayersMenuRealName = Array(myKMLayers.layerSetNames.length);
                    localStorage.WME_KeepMyLayers = JSON.stringify(myKMLayers);
                }
                /* ~~~~~~ TEMP ~~~~~~~ */
                return myKMLayers;
            } else {
                return false;
            }
        } else { // myKMLayers has not been saved yet
            /* TODO: Call to popup of instructions for saving default layers set will maybe go here */
            return false;
        }
    };

    //--------------------------------------------------------------------------
    // W.map.layers.forEach(function(a,i){console.debug('[' + i + ']', a["name"] + ':', a["visibility"])});

    var getWazeMapLayersFromSwitcher = function(wazeMapLayers) { // get OL layers that show up under the WME Layer switcher panel
        var kml_layIdx = wazeMapLayers.length,
            kml_layerName, kml_layerUniqName, kml_layerHumanReadableName,
            kml_layerSwitcher = {
                accelerator: {},
                uniqueName: {},
                name: {}
            };

        while (kml_layIdx--) {
            kml_layerName = wazeMapLayers[kml_layIdx].accelerator;
            kml_layerUniqName = wazeMapLayers[kml_layIdx].uniqueName;
            kml_layerHumanReadableName = wazeMapLayers[kml_layIdx].name;
            if (kml_layerName !== undefined) { //  accelerator is a marker with high specificity and selectivity of whether the layer appears in the layer switcher menu
                if (kml_layerUniqName !== undefined) { // uniqueName is used by WME for resetting layers to last PL
                    kml_layerSwitcher.uniqueName[kml_layerUniqName] = kml_layIdx;
                    kml_layerSwitcher.accelerator[kml_layerName] = kml_layIdx;
                    kml_layerSwitcher.name[kml_layerName] = kml_layerHumanReadableName;
                } else {
                    kml_layerSwitcher.accelerator[kml_layerName] = kml_layIdx;
                    kml_layerSwitcher.name[kml_layerName] = kml_layerHumanReadableName;
                }
            }
        }
        return kml_layerSwitcher;
    };

    //--------------------------------------------------------------------------
    var saveKMLayers = function() {
        //kmllog('saveKMLayers()', '/');
        var kml_j, kml_lname, kml_realname,
            kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map_layers),
            kml_layerNames = Object.keys(kml_layerSwitcher.accelerator),
            kml_numLayers = kml_layerNames.length,
            visibleInLayersMenu = {},
            visibleInLayersMenuRealName = [];


        // Get names of visible menu layers
        for (kml_j = kml_numLayers; kml_j--;) {
            kml_lname = kml_layerNames[kml_j];
            kml_realname = kml_layerSwitcher.name[kml_lname];
            if (kml_W_map_layers[kml_layerSwitcher.accelerator[kml_lname]].getVisibility()) {
                visibleInLayersMenu[kml_lname] = true;
                visibleInLayersMenuRealName.push(kml_realname);
            }
        }

        myKMLayers = getSavedKMLayers();

        if (!myKMLayers) {
            myKMLayers = {
                idx: 0,
                layerSetNames: ["My default layers"],
                visibleInLayersMenu: [],
                visibleInLayersMenuRealName: []
            };
        }
        if (myKMLayers.idx === 0) {
            // Save to localStorage
            localStorage.WME_KeepMyLayers_lV = localStorage.layerVisibility;
            if (localStorage.layerFilters) {
                localStorage.WME_KeepMyLayers_lF = localStorage.layerFilters;
            } else {
                localStorage.WME_KeepMyLayers_lF =
                    '{"update_requests":' + kml_W_map_layers[kml_layerSwitcher.accelerator.toggleUpdateRequests]
                    .visibility + ',"problems":' +
                    kml_W_map_layers[kml_layerSwitcher.accelerator.toggleMapProblems].visibility +
                    ',"mapProblem":0,"mapUpdateRequest":0,"venue":1}';
            }
        }

        myKMLayers.visibleInLayersMenu[myKMLayers.idx] = visibleInLayersMenu; //save only visible
        myKMLayers.visibleInLayersMenuRealName[myKMLayers.idx] = visibleInLayersMenuRealName;

        localStorage.WME_KeepMyLayers = JSON.stringify(myKMLayers);

        var kmlSaved = document.createElement("div");
        kmlSaved.id = "KMLpopup";
        kmlSaved.style.fontWeight = "bold";
        kmlSaved.style.color = "#DD3300";
        kmlSaved.style.position = "absolute";
        kmlSaved.style.display = "block";
        kmlSaved.style.bottom = "-30px";
        kmlSaved.style.right = "14px";
        kmlSaved.innerHTML = "Saved <";
        document.getElementById("layer-switcher-list").appendChild(kmlSaved)

        document.getElementById('iKMLsaveLayers').classList.remove("kml-icn-nsave");

        setTimeout(function() {
            kmlSaved.remove();
            //document.getElementById('KMLpopup').remove();
        }, 800);

        requestAnimationFrame(function() {
            updateKMLayersMenu(myKMLayers, kml_layerSwitcher);
        });
    };

    //--------------------------------------------------------------------------
    var getLayersFromPL = function() {
        var kmlayers = location.href.match(/&kmlayers=(\d*)/),
            wazelayers = location.href.match(/&layers=(\d*)/);
        if (kmlayers && kmlayers[1]) {
            return kmlayers[1];
        } else if (wazelayers && wazelayers[1]) {
            return wazelayers[1];
        } else {
            return false
        }
    };

    var convertLayersToObj = function() {
        var kml_layerVisibility_orig = {},
            uniqueLayerVal = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048],
            kml_uniqueName = ['satellite_imagery', 'cities', 'roads', 'gps_points',
                'area_managers', 'landmarks', 'speed_cameras', 'problems',
                'update_requests', 'editable_areas', 'live_users', 'place_updates'
            ],
            kml_layValIdx = uniqueLayerVal.length,
            kmlayers = getLayersFromPL();

        if (kmlayers !== undefined && kmlayers !== null && kmlayers !== false) {
            while (kml_layValIdx--) {
                if (kmlayers >= uniqueLayerVal[kml_layValIdx]) {
                    kmlayers -= uniqueLayerVal[kml_layValIdx];
                    kml_layerVisibility_orig[kml_uniqueName[kml_layValIdx]] = true;
                } else {
                    kml_layerVisibility_orig[kml_uniqueName[kml_layValIdx]] = false;
                }
            }
            sessionStorage.layerVisibility_orig = JSON.stringify(kml_layerVisibility_orig);

            return kml_layerVisibility_orig;
        } else {
            return false;
        }
    };

    var enableTogglingOfLayersFromPL = function(kml_toggledLayers) {
        document.getElementById('iKMLtempUndo').onclick = function() {
            var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map_layers),
                kml_accelNames = Object.keys(kml_layerSwitcher.accelerator),
                kml_layerVisibility_kmlayers = myKMLayers.visibleInLayersMenu[myKMLayers.idx],
                num_kml_tog = kml_accelNames.length,
                kml_tog,
                W_map_layers_idx, toggleLayerStatus;

            for (kml_tog = num_kml_tog; kml_tog--;) {
                W_map_layers_idx = kml_layerSwitcher.accelerator[kml_accelNames[kml_tog]];

                //kmllog(kml_accelNames[kml_tog], ': ', !kml_toggledLayers[kml_accelNames[kml_tog]])
                if (kml_toggledLayers[kml_accelNames[kml_tog]] !== null && kml_toggledLayers[kml_accelNames[kml_tog]] !== undefined) {

                    kml_toggledLayers[kml_accelNames[kml_tog]] = !kml_toggledLayers[kml_accelNames[kml_tog]];
                    toggleKMLayerVisibility(W_map_layers_idx, kml_toggledLayers[kml_accelNames[kml_tog]], kml_tog);
                }
            }
        };
    }
    var enableUndoBit = false;
    var enableUndoKMLayersReset = function() {
        //kmllog('enableUndoKMLayersReset()');

        if (document.getElementById('iKMLtempUndo') !== null && !enableUndoBit) {
            kml[2] = 0; //reset counter
            enableUndoBit = true;

            if (typeof myKMLayers !== "undefined" &&
                myKMLayers.reset !== undefined && myKMLayers.reset === true) {

                var kml_layerVisibility_orig = convertLayersToObj(),
                    kml_layerVisibility_kmlayers = myKMLayers.visibleInLayersMenu[myKMLayers.idx],
                    kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map_layers),
                    kml_layeraccelerators = Object.keys(kml_layerSwitcher.accelerator), // kml_layeruniqueNames = Object.keys(kml_layerSwitcher.uniqueName),
                    num_kml_an = kml_layeraccelerators.length,
                    kml_an,
                    kml_toggledLayers = {},
                    nToggled = 0,
                    W_map_layers_idx, accel2uniqueName, accelName, currentVisibility; //uniqueName2accel,

                if (kml_layerVisibility_orig) {

                    for (kml_an = 0; kml_an < num_kml_an; kml_an++) {
                        //uniqueName2accel = kml_W_map_layers[W_map_layers_idx].accelerator;
                        accelName = kml_layeraccelerators[kml_an];
                        W_map_layers_idx = kml_layerSwitcher.accelerator[accelName];
                        accel2uniqueName = kml_W_map_layers[W_map_layers_idx].uniqueName;

                        if (kml_layerVisibility_kmlayers[accelName] === undefined &&
                            kml_layerVisibility_orig[accel2uniqueName] === undefined) {

                            currentVisibility = kml_W_map_layers[W_map_layers_idx].getVisibility();

                            if (currentVisibility) {
                                kml_toggledLayers[accelName] = true;
                                nToggled++;
                            } else {
                                kml_toggledLayers[accelName] = null; //leave it alone
                            }

                            // allow for falsey and truthy matches:
                        } else if (kml_layerVisibility_orig[accel2uniqueName] !=
                            kml_layerVisibility_kmlayers[accelName]
                        ) {

                            kml_toggledLayers[accelName] = !!kml_layerVisibility_kmlayers[accelName];
                            nToggled++;

                        } else {
                            kml_toggledLayers[accelName] = null; //leave it alone

                        }
                    }

                    // var kmlayersQueryCode = !!(location.href.search(/&kmlayers=(\d*)/)+1);
                    if (nToggled !== 0) {
                        //kmllog('Layer visibilities were reset to preferred default setting.', '/');
                        //myKMLayers.reset = true;
                        //requestAnimationFrame(function(){localStorage_WME_KeepMyLayers = JSON.parse(myKMLayers)});
                        var kmlUndoBtnEl = document.getElementById('iKMLtempUndo');
                        kmlUndoBtnEl.classList.remove('kml-icn-off');
                        //kmlUndoBtnEl.parentNode.classList.remove('kml-icn-off');
                        //kmlUndoBtnEl.parentNode.setAttribute('href','javascript:void(0)');
                        //kmlUndoBtnEl.outerHTML =
                        //    '<a href="javascript:void(0)" class="kml-icn">' + kmlUndoBtnEl.outerHTML + '</a>';
                        enableTogglingOfLayersFromPL(kml_toggledLayers);

                    } // else do nothing, as there is nothing to undo bc layers were not reset
                } // else do nothing, as there is nothing to undo bc layers were not reset
            }
        } else if (enableUndoBit) {
            kml[2] = 0;
            return true; //button already enabled
        } else if (kml[2]++ < 30) {
            var waitTime = 300 + (kml[2] * 50);
            //kmllog(waitTime, 'ms');

            setTimeout(enableUndoKMLayersReset, waitTime);
        } else {
            console.warn('WMEKMLayers:',
                'Unable to activate "Undo KMLayers Reset".',
                'Element #iKMLtempUndo not found on page.');
        }
    };

    //----------------------------------------------------------------------
    var checkForReqLayers = function(permalink) {
        //kmllog('checkForReqLayers()');
        switch (true) {
            case permalink.indexOf('&mapUp') !== -1:
                return "toggleUpdateRequests";
            case permalink.indexOf('&ven') !== -1:
                return "togglePlaces";
            case permalink.indexOf('&mapPr') !== -1:
                return "toggleMapProblems";
            case permalink.indexOf('&bigJ') !== -1:
                return "toggleJunctionboxes";
            case permalink.indexOf('&cam') !== -1:
                return "toggleSpeedcameras";
            default:
                return false;
        }
    };

    //----------------------------------------------------------------------
    function toggleKMLayerVisibility(layerIdx, visibilityStatus, loadOrder) {
        // Add an offset to spread out the requests
        setTimeout(function() {
            kml_W_map_layers[layerIdx].setVisibility(visibilityStatus);
        }, 10 * loadOrder);
    }

    //----------------------------------------------------------------------

    var waitForMissedLayers = function(waitForThis, visibleMyKMLayersAccelObj, kml_wait) {
        //kmllog('waitForMissedLayers()');
        //kmllog(waitForThis);

        var maxWait = 10, //~11 seconds
            numLayersLeftToLoad = waitForThis.length;

        //kmllog('start kml_m = ' + kml_m);
        //kmllog('kml_wait = ' + kml_wait);
        if (numLayersLeftToLoad !== 0) {
            var kml_layerSwitcher_m = getWazeMapLayersFromSwitcher(kml_W_map_layers),
                switcherAccelObj_m = kml_layerSwitcher_m.accelerator,
                kmlWaitAccelName_m = [],
                kml_m_length = waitForThis.length,
                kml_m;

            for (kml_m = 0; kml_m < kml_m_length; kml_m++) {
                if (switcherAccelObj_m[waitForThis[kml_m]] !== undefined) {

                    toggleKMLayerVisibility(switcherAccelObj_m[waitForThis[kml_m]], visibleMyKMLayersAccelObj[waitForThis[kml_m]], kml_m);

                    /*kmllog(kmlWaitAccelName[kml_m] + 'visibility set to ' +
                        visibleMyKMLayersAccelObj[kmlWaitAccelName[kml_m]],
                        '/');*/
                } else {
                    kmlWaitAccelName_m.push(waitForThis[kml_m]);
                }
            } //for-loop
        }

        if (kml_wait++ < maxWait && numLayersLeftToLoad !== 0) {
            var kmlWaitTime = 200 * kml_wait;
            setTimeout(function() {
                waitForMissedLayers(kmlWaitAccelName_m, visibleMyKMLayersAccelObj, kml_wait)
            }, kmlWaitTime);
        } else {
            enableUndoKMLayersReset();
        }
    };

    var findMissingLayers = function(switcherAccelObj, visibleMyKMLayersAccelName) {
        //kmllog('findMissingLayers()');
        // check if any W.map.layers are missing compared to saved set
        var kml_m = visibleMyKMLayersAccelName.length,
            kmlWaitAccelName = [];

        while (kml_m--) {
            // Identify missing layers due to slower loading time
            if (switcherAccelObj[visibleMyKMLayersAccelName[kml_m]] === undefined) {
                kmlWaitAccelName.push(visibleMyKMLayersAccelName[kml_m]);
            }
        }

        return kmlWaitAccelName;
        //kmllog('Missed setting layers for ' + kmlWaitAccelName);
    };

    function adjustOpacityOfAMLayer(){
        for(var resetOp = 11; resetOp--;) {
            setTimeout(function(){
                if ( kml_W_map_layers[5].opacity === 1) {
                     kml_W_map_layers[5].setOpacity(0.6);
                }
            }, 100+(5*resetOp*resetOp));
        }
    }
    function checkAMLayerVisibility () {
        if (localStorage.WME_KMLSettings.indexOf('&5') !== -1) {
            if (kml_W_map_layers[5].getVisibility()) {
                kml_W_map_layers[5].setOpacity(0.6);
                unsafeWindow.Waze.map.events.register("moveend", unsafeWindow.Waze.map, adjustOpacityOfAMLayer);

                kmllog('Opacity of AM layer decreased.');
            } else {
                kml_W_map_layers[5].setOpacity(1);
                unsafeWindow.Waze.map.events.unregister("moveend", unsafeWindow.Waze.map, adjustOpacityOfAMLayer);
                kmllog('Opacity of AM layer returned to normal.');
            }
        }
    }


    var resetLayersToSavedKMLayers = function(kml_exclude) {
        //kmllog('resetLayersToSavedKMLayers(' + kml_exclude + ')');

        if (typeof myKMLayers !== "undefined" && myKMLayers) {
            var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map_layers),
                switcherAccelObj = kml_layerSwitcher.accelerator,
                switcherAccelNames = Object.keys(switcherAccelObj),
                kml_sw_length = switcherAccelNames.length,
                kml_sw, kml_lname,
                visibleMyKMLayersAccelObj = myKMLayers.visibleInLayersMenu[myKMLayers.idx],
                visibleMyKMLayersAccelName = Object.keys(visibleMyKMLayersAccelObj),
                togglePlacesAndPURs = false;

            // Adjust layer visibility if necessary
            if (kml_exclude) visibleMyKMLayersAccelObj[kml_exclude] = true;

            for (kml_sw = 0; kml_sw < kml_sw_length; kml_sw++) {
                kml_lname = switcherAccelNames[kml_sw];

                toggleKMLayerVisibility(switcherAccelObj[kml_lname], !!visibleMyKMLayersAccelObj[kml_lname], kml_sw);

            }

            myKMLayers.reset = true;
            requestAnimationFrame(function() {
                localStorage.WME_KeepMyLayers = JSON.stringify(myKMLayers)
            });

            var waitForThis = findMissingLayers(switcherAccelObj, visibleMyKMLayersAccelName);
            waitForMissedLayers(waitForThis, visibleMyKMLayersAccelObj, 1);

            checkAMLayerVisibility();
        }
    };


    // ---------------------------------------------------------------------
    var applyAdditionalKMLSettings = function() {
        //kmllog('applyAdditionalKMLSettings()', '/');
        // ['&x', '&b', '&l', '&1', '&5', '&2']; //disable, beta, lang, city, am, roads
        if (localStorage.WME_KMLSettings.indexOf('&1') !== -1) {
            kml_W_map_layers[1].setOpacity(1);
            kmllog('Opacity of Cities layer increased.');
        } else {
            kml_W_map_layers[1].setOpacity(0.5);
            //kmllog('Opacity of Cities layer at default.', '/');
        }

        setTimeout(checkAMLayerVisibility, 3000);

        if (localStorage.WME_KMLSettings.indexOf('&2') !== -1) {
            kml_W_map_layers[2].setOpacity(0.8);
            kmllog('Opacity of Roads layer decreased.');
        } else {
            kml_W_map_layers[2].setOpacity(1);
            //kmllog('Opacity of Roads layer at default.', '/');
        }
    };

    // ---------------------------------------------------------------------
    var runSecondaryKMLayersCheck = function() {
        //kmllog('runSecondaryKMLayersCheck()', '/');
        if (localStorage.WME_KMLSettings === undefined) {
            localStorage.WME_KMLSettings = ':';
        }

        if (localStorage.WME_KMLSettings.indexOf('&x') !== -1) { // user has set WMEKMLayers to be disabled
            console.log('WMEKMLayers:',
                'Autocheck of KeepMyLayers at startup is disabled (2).');
            return false;
        } else {
            var myKMLayers = getSavedKMLayers();
            //kmllog('Secondary check completed. Any saved layers will be applied (2).', '/');
            if (myKMLayers) {
                return myKMLayers;
            } else {
                return false;
            }
        }
    };

    //======================================================================
    //======================================================================
    myKMLayers = runSecondaryKMLayersCheck();
    //KML = myKMLayers;
    if (myKMLayers) {
        resetLayersToSavedKMLayers(checkForReqLayers(location.href));
    } else {
        myKMLayers = getSavedKMLayers();
    }
    applyAdditionalKMLSettings();

    var kmlayersBetaChk = GM_getValue("WMEKMLayers_Beta"),
        kmlayersLangChk = GM_getValue("WMEKMLayers_Lang");
    //======================================================================
    //======================================================================
    var userResetOfLayersToSavedKMLayers = function(myKMLayersStatus) {
        //kmllog('userResetOfLayersToSavedKMLayers()', '/');
        if (myKMLayersStatus === undefined) {
            myKMLayersStatus = !!getSavedKMLayers();
        }

        if (myKMLayersStatus) {
            resetLayersToSavedKMLayers(false);
        } else {
            //kmllog('Nothing to reset.', '/');
            return false;
        }
    };

    //----------------------------------------------------------------------
    // Dropdown menu for selecting layers
    var updateKMLayersMenu = function(myKMLayers, kml_layerSwitcher) {
        var numKMLsets = myKMLayers.layerSetNames.length,
            htmlText = '',
            findRealNames, missingLayerNames = false,
            layersInTooltipArray, numLayersInTooltip, layerTooltip, ltt, layerRealName,
            selStatus, kmlset;

        kmlset = -1
        while (++kmlset < numKMLsets) {
            findRealNames = false;

            if (myKMLayers.visibleInLayersMenuRealName[kmlset] === null) {
                myKMLayers.visibleInLayersMenuRealName[kmlset] = []; //start with an empty array
                findRealNames = true;
            } else if (myKMLayers.visibleInLayersMenuRealName[kmlset].length !== Object.keys(myKMLayers.visibleInLayersMenu[kmlset]).length) {
                myKMLayers.visibleInLayersMenuRealName[kmlset] = []; //start with an empty array
                findRealNames = true;
            }

            if (findRealNames) {
                layersInTooltipArray = Object.keys(myKMLayers.visibleInLayersMenu[kmlset]).map(function(layerKey) {
                    return layerKey;
                });
                numLayersInTooltip = layersInTooltipArray.length;

                if (numLayersInTooltip === 0) {
                    layerTooltip = '<ul style="margin: 15px 5px 15px -15px;"><li style="text-align: left;">none</li></ul>';
                } else {
                    layerTooltip = '<ul style="margin: 15px 5px 15px -15px;">';
                    for (ltt = 0; ltt < numLayersInTooltip; ltt++) {
                        layerRealName = kml_layerSwitcher.name[layersInTooltipArray[ltt]];
                        if (layerRealName !== undefined) {
                            myKMLayers.visibleInLayersMenuRealName[kmlset].push(layerRealName);
                            layerTooltip += '<li style="text-align: left;">' + layerRealName + '</li>';
                        } else { // ~~~~~~ TEMP ~~~~~~~
                            layerTooltip += '<li style="text-align: left;">missing layer? - ' + layersInTooltipArray[ltt] + '</li>';
                            missingLayerNames = true;
                        }
                    }
                    layerTooltip += '</ul>'
                    localStorage.WME_KeepMyLayers = JSON.stringify(myKMLayers);
                }
            } else {
                layersInTooltipArray = myKMLayers.visibleInLayersMenuRealName[kmlset];
                numLayersInTooltip = myKMLayers.visibleInLayersMenuRealName[kmlset].length;
                if (numLayersInTooltip === 0) {
                    layerTooltip = '<ul style="margin: 15px 5px 15px -15px;"><li style="text-align: left;">none</li></ul>';
                } else {
                    layerTooltip = '<ul style="margin: 15px 5px 15px -15px;">';
                    for (ltt = 0; ltt < numLayersInTooltip; ltt++) {
                        layerTooltip += '<li style="text-align: left;">' + layersInTooltipArray[ltt] + '</li>';
                    }
                    layerTooltip += '</ul>'
                }
            }

            //---------------------
            (kmlset === myKMLayers.idx) ? selStatus = 'active ' : selStatus = '';

            htmlText += '<li>' +
                '<a data-toggle="tooltip" data-placement="left" data-container="#kmlTooltipContainer" data-html="true" ' +
                'title=\'' + layerTooltip + '\' ' +
                'value=' + kmlset + ' name="kmlSet_' + kmlset + '" ' +
                'class = "kml-layers-menu dropdown-item ' + selStatus +
                '" ' + 'href="javascript:void(0)">' +
                '<div class="">' +
                myKMLayers.layerSetNames[kmlset] + ' </div> ' +
                '</a></li>'
            htmlText +=
                '<li role="separator" class="divider kml-layers-menu"></li>';

        }

        document.querySelector('ul[class*=kml-layers-menu]').innerHTML = htmlText;

        kmlset = -1;
        while (++kmlset < numKMLsets) {
            document.querySelectorAll('a.kml-layers-menu')[kmlset].onclick = function() {
                document.getElementsByName('kmlSet_' + myKMLayers.idx)[0].classList.remove('active');
                kmlThisName = this.name;
                //kmllog(kmlThisName)
                document.getElementsByName(kmlThisName)[0].classList.add('active');
                myKMLayers.idx = parseInt(document.getElementsByName(kmlThisName)[0].getAttribute("value"));
                localStorage.WME_KeepMyLayers = JSON.stringify(myKMLayers);
                setTimeout(function() {
                    userResetOfLayersToSavedKMLayers(true)
                }, 150);
            };
        }

        if (Object.keys(myKMLayers.visibleInLayersMenu[myKMLayers.idx]).length === 0) {
            document.getElementById("iKMLsaveLayers").classList.add('kml-icn-nsave');
        } else {
            document.getElementById("iKMLsaveLayers").classList.remove('kml-icn-nsave');
        }

        try {
            $(".kml-layers-menu[data-toggle=tooltip]").tooltip({
                html: true,
                delay: {
                    show: 10,
                    hide: 100
                },
                template: '<div class="kml-tooltip-spacer" style="min-height: 50px; width: 200px;"></div><div class="tooltip" role="tooltip" style="width: 200px; margin-top: 0px;"><div class="tooltip-arrow" style="display: none; margin-right: 3px;"></div><div class="tooltip-inner" style="font-weight: bold; text-align: left; word-wrap: break-word;"></div></div>'
            });
        } catch(err) {
            $(".kml-layers-menu[data-toggle=tooltip]").tooltip();
        }

        return missingLayerNames;

    };

    //----------------------------------------------------------------------
    var getGMBetaValue = function(callback) {
        requestAnimationFrame(function() {
            callback(GM_getValue("WMEKMLayers_Beta"))
        });
    };

    //----------------------------------------------------------------------
    // Beta Editor Toggle Button
    var toggleKMLToggle = function(e, disableBetaTog) {

        var enableKMLBetaToggle = function(kmlBetaToggleGM) {
            localStorage.WME_KMLSettings = localStorage.WME_KMLSettings.replace('#b', '&b'); //reset
            // kmllog('kmlBetaToggleGM = ' + kmlBetaToggleGM)
            kmlBetaToggleGM = (kmlBetaToggleGM.substr(kmlBetaToggleGM.indexOf('-') + 1) == "true");
            // kmllog('WMEKMLayers_Beta = ' + kmlBetaToggleGM)
            requestAnimationFrame(function() {
                GM_setValue("WMEKMLayers_Beta", kmlBetaToggleGM)
            });
            document.getElementById('cbKMLtoggle').disabled = false;
            document.getElementById('cbKMLtoggle').checked = kmlBetaToggleGM;
            document.getElementsByClassName('kml-toggle-innerD')[0].className = "kml-toggle-inner";
        };

        var disableKMLBetaToggle = function() {
            var kmlBetaToggleChecked = document.getElementById('cbKMLtoggle').checked,
                kmlBetaToggleGM = 'disabled-' + kmlBetaToggleChecked;

            //localStorage.WME_KMLSettings = localStorage.WME_KMLSettings.replace('&b', '#b');
            requestAnimationFrame(function() {
                GM_setValue("WMEKMLayers_Beta", kmlBetaToggleGM)
            });
            //kmllog('WMEKMLayers_Beta = ' + kmlBetaToggleGM)
            document.getElementById('cbKMLtoggle').disabled = true;
            document.getElementById('cbKMLtoggle').checked = kmlBetaToggleChecked;
            document.getElementsByClassName('kml-toggle-inner')[0].className = "kml-toggle-innerD";

        };
        //----------------------------------------------------
        //kmllog('disableBetaTog = ' + disableBetaTog)
        if (disableBetaTog === undefined || disableBetaTog === null) {
            //kmllog("cbKMLtoggle status: " + document.getElementById('cbKMLtoggle').disabled);
            if (document.getElementById('cbKMLtoggle').disabled) { //enable it
                //kmllog('Enabling Beta Toggle...')
                getGMBetaValue(enableKMLBetaToggle);
            } else {
                //kmllog('Disabling Beta Toggle...')
                disableKMLBetaToggle();
            }
        } else if (disableBetaTog) {
            disableKMLBetaToggle();
        } else {
            getGMBetaValue(enableKMLBetaToggle);
        }
    };

    var initAltPermalink = function() {

        var updateKMLPermalink = function(currPl, inBeta, togSuffix) {
            if (togSuffix === undefined) togSuffix = '';

            var kmlCurrAltPL = currPl.substr(currPl.indexOf(location.pathname));

            if (inBeta) {
                return 'https://www.waze.com' + kmlCurrAltPL + togSuffix;
            } else {
                return 'https://editor-beta.waze.com' + kmlCurrAltPL + togSuffix;
            }
        };

        var copyAltPlToClipboard = function(EEEEE) {
            if (EEEEE.metaKey) {
                requestAnimationFrame(function() {
                    GM_setClipboard(document.getElementById('aKMLAltPermalink').getAttribute('href'))
                });
            }
        };

        // make sure the welcome log-in screen is not up
        //document.getElementById("welcome-popup").className.lastIndexOf('hide') === -1
        if (document.getElementsByClassName('WazeControlPermalink')) {

            document.querySelector('.WazeControlPermalink>a.icon-link:first-child, .WazeControlPermalink>a.fa-link:first-child').id = 'wazePermalink';

            var wazePermalinkEl = document.getElementById('wazePermalink'),
                wazeCopyPlNote = wazePermalinkEl.getAttribute('data-original-title'),
                wazeCurrentPl = wazePermalinkEl.getAttribute('href').replace(/&layers=(\d+)/, ''),
                altPermalinkEl = document.createElement('div'),
                wazeControlPermalinkEl = document.getElementsByClassName('WazeControlPermalink')[0],
                kmlCurrentAltPl;

            altPermalinkEl.className = 'icon-stack fa-stack pull-right';
            altPermalinkEl.id = 'kmlAltPermalink';
            altPermalinkEl.style.position = 'relative';
            altPermalinkEl.style.bottom = '-1px';
            altPermalinkEl.style.margin = '0px -2px 0px 2px';

            if (location.host.indexOf('editor-beta') === -1) { // not beta-editor
                kmlPLColor = '#FA5257';
                inBetaEditor = false;
            } else {
                kmlPLColor = '#59899E';
                inBetaEditor = true;
            }

            kmlCurrentAltPl = updateKMLPermalink(wazeCurrentPl, inBetaEditor, '&b=0');
            altPermalinkEl.innerHTML = '<a id="aKMLAltPermalink" href="' + kmlCurrentAltPl + '"><span class="icon-circle icon-stack-1x fa fa-circle fa-stack-1x" style="color: ' + kmlPLColor + '; font-size: 23.5px;"></span><span class="icon-link icon-stack-1x fa fa-link fa-stack-1x" style="color: #FFF; font-size: 14.5px;"></span></a>';

            wazeControlPermalinkEl.appendChild(altPermalinkEl);

            var kmlAltPLTooltipEl = document.createElement('div');
            kmlAltPLTooltipEl.id = 'kmlAltPLTooltip';
            kmlAltPLTooltipEl.style.float = 'right';
            kmlAltPLTooltipEl.style.position = 'absolute';
            kmlAltPLTooltipEl.style.right = '20px';
            kmlAltPLTooltipEl.style.top = '-50px';
            kmlAltPLTooltipEl.style.color = '#FFF';
            kmlAltPLTooltipEl.style.backgroundColor = '#000';
            kmlAltPLTooltipEl.style.borderRadius = '5px';
            kmlAltPLTooltipEl.style.paddingLeft = '5px';
            kmlAltPLTooltipEl.style.paddingRight = '5px';
            kmlAltPLTooltipEl.style.display = 'none';
            kmlAltPLTooltipEl.style.zIndex = '1000';
            kmlAltPLTooltipEl.style.pointerEvents = 'none';
            kmlAltPLTooltipEl.innerHTML = '<span id="tooltipKMLAltPermalink">' + kmlCurrentAltPl + '</span><br>' + wazeCopyPlNote;

            wazeControlPermalinkEl.appendChild(kmlAltPLTooltipEl);

            document.getElementsByClassName('WazeControlPermalink')[0].addEventListener('mouseover', function(eeeee) {
                var thisPl = document.getElementById('wazePermalink').getAttribute('href').replace(/&layers=(\d+)/, ''),
                    altThisPl = updateKMLPermalink(thisPl, inBetaEditor, '&b=0');

                document.getElementById('tooltipKMLAltPermalink').innerHTML = altThisPl;
                document.getElementById('aKMLAltPermalink').setAttribute('href', altThisPl);
            }, false);

            document.getElementById('kmlAltPermalink').addEventListener('mouseover', function(eeeee) {
                document.getElementById('kmlAltPLTooltip').style.display = 'block';
                window.addEventListener("keydown", copyAltPlToClipboard, false);
            }, false);

            document.getElementsByClassName('WazeControlPermalink')[0].addEventListener('mouseout', function() {
                document.getElementById('kmlAltPLTooltip').style.display = 'none';
                window.removeEventListener("keydown", copyAltPlToClipboard);
            }, false);

        } else {
            setTimeout(initAltPermalink, 500);
        }

    };

    var insertKMLBetaToggle = function(kmlToggleArg) {
        //kmllog('insertKMLBetaToggle()', '/');
        var doInsertBetaToggle = function(kmlBetaTogVal) {
            $('#user-details').prepend(
                '<div class="kml-toggle-container"><div class="kml-toggle">' +
                '<input type="checkbox" name="kml-toggle" class="kml-toggle-checkbox" id="cbKMLtoggle"' +
                kmlBetaTogVal + '>' +
                '<label class="kml-toggle-label" for="cbKMLtoggle">' +
                '<span class="kml-toggle-inner"></span>' +
                '<span class="kml-toggle-switch"></span></label></div></div>');

            // Event listeners for beta/prod toggle
            document.getElementById('cbKMLtoggle').onclick = function() {
                requestAnimationFrame(function() {
                    GM_setValue("WMEKMLayers_Beta",
                        document.getElementById('cbKMLtoggle').checked);
                });
            };

            document.getElementsByClassName('kml-toggle')[0].ondblclick = toggleKMLToggle;
        }

        //---------------
        if (document.getElementById('user-details') !== null && document.getElementById('cbKMLtoggle') === null) {
            kml[4] = 0; //reset counter
            var kmlBetaTogVal, kmlBetaGMType;

            //kmllog(kmlToggleArg);
            if (kmlToggleArg === undefined || kmlToggleArg === null) {
                kmlToggleArg = !!(location.host.indexOf('editor-beta') + 1);
                kmlBetaGMType = kmlToggleArg;
            } else if (kmlToggleArg.constructor === Boolean) {
                kmlBetaGMType = kmlToggleArg;
                requestAnimationFrame(function() {
                    GM_setValue("WMEKMLayers_Beta", kmlToggleArg)
                });
            } else { //insertKMLBetaToggle('disabled')
                kmlToggleArg = (kmlToggleArg.substr(kmlToggleArg.indexOf('-') + 1) == "true"); //bool
                kmlBetaGMType = 'disabled';
            }

            (kmlToggleArg) ? kmlBetaTogVal = 'checked' : kmlBetaTogVal = '';
            doInsertBetaToggle(kmlBetaTogVal);
            requestAnimationFrame(initAltPermalink);

            // Disable toggle?
            if (kmlBetaGMType === 'disabled') {
                if (localStorage.WME_KMLSettings.indexOf('#b') !== -1) {
                    toggleKMLToggle(null, false); // enable toggle
                } else {
                    toggleKMLToggle(null, true); // disable toggle
                }
            }

        } else if ($('#cbKMLtoggle').length > 0) {
            kml[4] = 0;
            return true;
        } else if (kml[4]++ < 30) {
            var waitTime = 200 + (kml[4] * 50);
            setTimeout(function() {
                insertKMLBetaToggle(kmlToggleArg)
            }, waitTime);
        } else {
            console.warn('WMEKMLayers:',
                'Unable to insert "Beta-Editor Toggle".',
                'Element #user-details not found on page.')
        }
    };

    //----------------------------------------------------------------------
    var selectLanguageLocale = function() {
        var langLocaleEl = document.createElement('div');
        langLocaleEl.id = 'langLocaleEl';
        langLocaleEl.style.display = 'inline-block';
        langLocaleEl.style.margin = '0px';
        langLocaleEl.style.padding = '0px';
        langLocaleEl.innerHTML = '\
            <div class="language-selector">\
            <div class="btn-group pull-right">\
            <a class="btn btn-default dropdown-toggle toggle-language-selector" data-toggle="dropdown" href="#" style="margin: 0px 10px -7px 20px; width: 82px; padding: 3px 0px;">\
            <i class="icon-globe fa fa-globe"></i>\
            <span class="language_code">none</span>\
            <i class="icon-caret-down fa fa-caret-down"></i>\
            </a>\
            <ul class="dropdown-menu locales">\
            <li class="active"><a data-locale="none" href="#">&nbsp;</a></li>\
            <li><a data-locale="af" href="#">Afrikaans</a></li>\
            <li><a data-locale="ar" href="#">العربية</a></li>\
            <li><a data-locale="bg" href="#">Български</a></li>\
            <li><a data-locale="ca" href="#">Català</a></li>\
            <li><a data-locale="cs" href="#">Čeština</a></li>\
            <li><a data-locale="da" href="#">Dansk</a></li>\
            <li><a data-locale="de" href="#">Deutsch</a></li>\
            <li><a data-locale="en-GB" href="#">English (UK)</a></li>\
            <li><a data-locale="en" href="#">English</a></li>\
            <li><a data-locale="es-419" href="#">Español-América Latina</a></li>\
            <li><a data-locale="es" href="#">Español</a></li>\
            <li><a data-locale="fi" href="#">Suomi</a></li>\
            <li><a data-locale="fr" href="#">Français</a></li>\
            <li><a data-locale="gl" href="#">Galego</a></li>\
            <li><a data-locale="he" href="#">עברית</a></li>\
            <li><a data-locale="hu" href="#">Magyar</a></li>\
            <li><a data-locale="it" href="#">Italiano</a></li>\
            <li><a data-locale="ja" href="#">日本語</a></li>\
            <li><a data-locale="ko" href="#">한국어</a></li>\
            <li><a data-locale="lv" href="#">Latviešu</a></li>\
            <li><a data-locale="ms" href="#">Melayu</a></li>\
            <li><a data-locale="nl" href="#">Nederlands</a></li>\
            <li><a data-locale="pl" href="#">Polski</a></li>\
            <li><a data-locale="pt-BR" href="#">Português-Brasil</a></li>\
            <li><a data-locale="pt-PT" href="#">Português</a></li>\
            <li><a data-locale="ro" href="#">Română</a></li>\
            <li><a data-locale="ru" href="#">Русский</a></li>\
            <li><a data-locale="sl" href="#">Slovenščina</a></li>\
            <li><a data-locale="sk" href="#">Slovenčina</a></li>\
            <li><a data-locale="sv" href="#">Svenska</a></li>\
            <li><a data-locale="tr" href="#">Türkçe</a></li>\
            <li><a data-locale="zh" href="#">中文(简体)</a></li>\
            <li><a data-locale="zh-TW" href="#">中文(簡體)</a></li>\
            <li><a data-locale="id" href="#">Bahasa Indonesia</a></li>\
            <li><a data-locale="et" href="#">Eesti</a></li>\
            <li><a data-locale="hr" href="#">Hrvatski</a></li>\
            <li><a data-locale="sr" href="#">Srpski (Latinica)</a></li>\
            <li><a data-locale="no" href="#">Norsk</a></li>\
            </ul>\
            </div>\
            </div>';

        document.getElementById('cbKML_1').parentNode.appendChild(langLocaleEl);

        var kmlLocaleSelectorEl = document.querySelectorAll('div.kml-panel div.language-selector ul.dropdown-menu.locales>li>a'),
            numkmlLocaleSelector = kmlLocaleSelectorEl.length,
            kml_ls = -1,
            kmlLocaleSelector;

        //kmlayersLangChk = GM_getValue("WMEKMLayers_Lang");
        //kmllog(kmlayersLangChk);

        if (!kmlayersLangChk || kmlayersLangChk === true) kmlayersLangChk = 'none';

        while (++kml_ls < numkmlLocaleSelector) {
            if (kmlayersLangChk === kmlLocaleSelectorEl[kml_ls].getAttribute('data-locale')) {
                if (kml_ls) {
                    kmlLocaleSelectorEl[kml_ls].parentNode.className = 'active';
                    document.querySelector('div.kml-panel div.language-selector span.language_code').innerHTML = kmlayersLangChk;
                }
            } else {
                kmlLocaleSelectorEl[kml_ls].parentNode.className = '';
            }

            document.querySelectorAll('div.kml-panel div.language-selector ul.dropdown-menu.locales>li>a')[kml_ls].onclick = function() {
                var langLocale = this.getAttribute('data-locale');

                document.querySelector('div.kml-panel div.language-selector ul.dropdown-menu.locales>li.active').className = '';
                document.querySelector('div.kml-panel div.language-selector span.language_code').innerHTML = langLocale;
                this.parentNode.className = 'active'
            };
        }
    };

    var showKMLPrefsPanel = function() {
        //kmllog('showKMLPrefsPanel()');
        var kmlBetaInitState = !!(location.host.indexOf('editor-beta') + 1),
            kmlOptions, kmlSettingsUI;

        // setup checkbox list for UI
        kmlOptions = ['Show WME beta/production editor toggle in the left side-panel', //[0]
            'Remove language locale from clicked permalinks', //[1]
            'Increase the opacity of city polygons to make them more visible', //[2] layer 1 - 1city
            'Make area manager polygons more translucent', //[3] layer 5 - 5am
            'Add a small amount of transparency to Roads layer', //[4] layer 2 - 2roads
            'Disable KeepMyLayers from auto-resetting layers at startup'
        ]; //[5] xx

        kmlSettingsUI =
            '<div id="KMLsettings" class="kml-panel-blackout">' +
            '<div class="kml-panel">' +
            '   <i id="iKMLsettings" class="icon-cog icon-4x pull-left fa fa-cog fa-4x fa-pull-left"></i>' +
            '   <h2>KeepMyLayers Preferences</h2>' +
            '   <hr class="kml-panel-hr">' +
            '   <div class="kml-panel-section">';

        var selectedKML = Array(kmlOptions.length),
            allStr = ['b', '&l', '&1', '&5', '&2', '&x'], //beta, lang, city, am, roads, disable
            cbKMLSettingsStr;

        //kmllog('kmlayersBetaChk = ' + kmlayersBetaChk)

        //TODO: Clean the following code up....
        if (localStorage.WME_KMLSettings === undefined) {
            localStorage.WME_KMLSettings = ':';
            cbKMLSettingsStr = ':';
        } else {
            cbKMLSettingsStr = localStorage.WME_KMLSettings;
        }

        //  Setup KMLayers settings panel
        var kml_s, numKmlOpt = kmlOptions.length;

        for (kml_s = 0; kml_s < numKmlOpt; kml_s++) {
            (cbKMLSettingsStr.indexOf(allStr[kml_s]) !== -1) ? selectedKML[kml_s] =
                ' checked' : selectedKML[kml_s] = ' ';
            kmlSettingsUI +=
                '<div class="controls-container">' +
                '<input type="checkbox" id="cbKML_' + kml_s +
                '" class="checkbox"' + selectedKML[kml_s] +
                '></input>' +
                '<label for="cbKML_' + kml_s + '">' + kmlOptions[kml_s] +
                '</label>' +
                '</div>';
        }
        kmlSettingsUI += '</div>' +
            '<div style="font-size: 9pt; font-style: italic; margin-left: 35px; margin-top: 0px; margin-bottom: 0px;">' +
            '   Does not include any of the above settings' +
            '</div>' +
            '<hr class="kml-panel-hr">' +
            '<div class="kml-panel-btn">' +
            '   <div id="KMLnote" style="line-height: 10pt; color: #FF0080; position: absolute; left: 0px; display: inline-block; text-align: left; ' +
            '        width: 300px; vertical-align: middle">' + //line-height: 15px; height: 40px;
        '' + // notes and layers menu go here
        '   </div>' +
            '   <div style="position: absolute; right: 0px; display: inline-block;">' +
            '       <button id="btnKMLsave" style="width: 85px" class="btn btn-primary kml-panel-btn">Save</button>' +
            '       <button id="btnKMLcancel" class="btn btn-default kml-panel-btn">Cancel</button>' +
            '   </div>' +
            '</div></div></div>';
        $('#map').append(kmlSettingsUI);
        kmlSettingsUI = null;

        // Notice about neding to save default layers
        if (!getSavedKMLayers()) {
            $('#KMLnote').append(
                '<span style="font-size:10px">' +
                'To save a default layers setting, select your layers under the Layer Switcher menu and then click ' +
                '   <div style="color: #FF0080; font-size: 11pt; font-style: normal; margin-right: 4px; display:inline-block" ' +
                '        class="icon-save fa fa-save kml-icn-nsave"></div> (bottom-right).' +
                '</span>'
            );
        } else { // Dropdown menu of saved layer settings
            $('#KMLnote').append(
                '<div class="" style="display: inline-block; vertical-align: middle;">' +
                '   <select id="selKMLset" class="" style="width: 200px;"></select>' +
                '   <div style="display: inline-block; vertical-align: middle;">' +
                '   <div id="addKMLset" style="color: #AAAAAA; margin-left: 4px; display:inline-block; cursor: pointer;" class="icon-plus-sign icon-2x fa fa-plus-circle fa-2x"></div>' +
                '   <div id="removeKMLset" style="color: #AAAAAA; margin-left: 4px; display:inline-block; cursor: pointer;" class="icon-minus-sign icon-2x fa fa-minus-circle fa-2x"></div>' +
                '</div></div>' +
                '');

            var kml_sel, numSets = myKMLayers.layerSetNames.length;

            for (kml_sel = 0; kml_sel < numSets; kml_sel++) {
                document.getElementById("selKMLset").add(new Option(myKMLayers.layerSetNames[kml_sel]));
            };

            document.getElementById("selKMLset").selectedIndex = myKMLayers.idx;
            document.getElementById("selKMLset").value = myKMLayers.layerSetNames[myKMLayers.idx];

            document.getElementById("selKMLset").onchange = function() {
                myKMLayers.idx = document.getElementById("selKMLset").selectedIndex;
                if (Object.keys(myKMLayers.visibleInLayersMenu[myKMLayers.idx]).length === 0) {
                    document.getElementById("iKMLsaveLayers").classList.add('kml-icn-nsave');
                } else {
                    document.getElementById("iKMLsaveLayers").classList.remove('kml-icn-nsave');
                }
            };

            document.getElementById("addKMLset").onclick = function() {
                var newKMLayerSetName = prompt("Please enter a name", ""),
                    newKMLayerOpt = document.createElement('option');
                newKMLayerOpt.appendChild(document.createTextNode(newKMLayerSetName));
                document.getElementById("selKMLset").appendChild(newKMLayerOpt);
                document.getElementById("selKMLset").selectedIndex = myKMLayers.layerSetNames.length;
                myKMLayers.idx = myKMLayers.layerSetNames.length;
                myKMLayers.layerSetNames[myKMLayers.idx] = newKMLayerSetName;
                myKMLayers.visibleInLayersMenu[myKMLayers.idx] = {};
                myKMLayers.visibleInLayersMenuRealName[myKMLayers.idx] = [];
                document.getElementById("iKMLsaveLayers").classList.add('kml-icn-nsave');
            };

            document.getElementById("removeKMLset").onclick = function() {
                if (myKMLayers.layerSetNames.length > 1) {
                    var selectedKMLIndex = document.getElementById("selKMLset").selectedIndex;

                    myKMLayers.layerSetNames.splice(selectedKMLIndex, 1);
                    myKMLayers.visibleInLayersMenu.splice(selectedKMLIndex, 1);
                    myKMLayers.visibleInLayersMenuRealName.splice(selectedKMLIndex, 1);
                    document.getElementById("selKMLset").removeChild(document.getElementById("selKMLset").options[selectedKMLIndex]);
                    myKMLayers.idx = myKMLayers.layerSetNames.length - 1;
                    document.getElementById("selKMLset").selectedIndex = myKMLayers.idx;
                    document.getElementById("selKMLset").value = myKMLayers.layerSetNames[myKMLayers.idx];
                }
            };
        };

        var applyKMLayersSettings = function() {

            if (document.getElementById("cbKML_0").checked) {
                insertKMLBetaToggle(kmlBetaInitState);
            } else {
                if (document.getElementsByClassName('kml-toggle-container').length !== 0) {
                    requestAnimationFrame(function() {
                        GM_deleteValue("WMEKMLayers_Beta")
                    });
                    document.getElementsByClassName('kml-toggle-container')[0].remove();
                }
            }

            if (document.getElementById("cbKML_1").checked) {
                var langLocale = document.querySelector('div.kml-panel div.language-selector span.language_code').innerHTML;

                if (langLocale === 'none' || langLocale === 'en') {
                    requestAnimationFrame(function() {
                        GM_setValue("WMEKMLayers_Lang", true);
                    });
                } else {
                    requestAnimationFrame(function() {
                        GM_setValue("WMEKMLayers_Lang", langLocale);
                    });
                }
            } else {
                requestAnimationFrame(function() {
                    GM_deleteValue("WMEKMLayers_Lang")
                });
            }
            var storeStr = ':';

            if ($('#cbKML_5')[0].checked) storeStr += '&x'; //disable KML
            if ($('#cbKML_0')[0].checked) storeStr += '&b'; //beta
            if ($('#cbKML_1')[0].checked) storeStr += '&l'; //lang
            if ($('#cbKML_2')[0].checked) storeStr += '&1'; //city
            if ($('#cbKML_3')[0].checked) storeStr += '&5'; //am
            if ($('#cbKML_4')[0].checked) storeStr += '&2'; //roads

            document.getElementById("KMLsettings").remove();

            localStorage.WME_KMLSettings = storeStr + '&' + kmlVersion;
            localStorage.WME_KeepMyLayers = JSON.stringify(myKMLayers);

            //kmllog(document.getElementById("KMLsettings"))
            requestAnimationFrame(applyAdditionalKMLSettings);

            var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map_layers);

            if (myKMLayers && myKMLayers.visibleInLayersMenu) {
                updateKMLayersMenu(myKMLayers, kml_layerSwitcher);

                if (Object.keys(myKMLayers.visibleInLayersMenu[myKMLayers.idx]).length !== 0) {
                    userResetOfLayersToSavedKMLayers(true);
                }
            }

        };

        selectLanguageLocale();

        document.getElementById('btnKMLsave').onclick = applyKMLayersSettings;

        document.getElementById('btnKMLcancel').onclick = function() {
            document.getElementById("KMLsettings").remove();
            var tempResetHolder = myKMLayers.reset;
            myKMLayers = getSavedKMLayers();
            myKMLayers.reset = tempResetHolder;
            if (myKMLayers && myKMLayers.visibleInLayersMenu && Object.keys(myKMLayers.visibleInLayersMenu[myKMLayers.idx]).length === 0) {
                document.getElementById("iKMLsaveLayers").classList.add('kml-icn-nsave');
            } else {
                document.getElementById("iKMLsaveLayers").classList.remove('kml-icn-nsave');
            }
        };
    };

    //======================================================================
    var initKMLButtons = function() {
        if (document.getElementById("layer-switcher-list") && document.getElementById("iKMLsaveLayers") === null) {
            kml[6] = 0; //reset counter
            var panelHeight = 350,
                panelWidth = 540,
                kmlStyle = document.createElement("style");

            // Create CSS container element
            kmlStyle.type = "text/css";
            kmlStyle.id = "kml-css-container";

            // CSS for KMLayers icons under Layers dropdown menu
            kmlStyle.innerHTML = '\
                div.kml-icn { position: absolute; display: inline-block; vertical-align: middle;\
                   bottom: 0px; right: 0px; padding: 0; margin: 0px 10px 10px 0px; }\n\
                .kml-icn-nsave { font-weight: 400; color: #D36343 !important; }\n\
                .kml-icn-btn { position: relative; display: inline-block; padding-left: 4px; padding-right: 4px; }\n\
                .kml-icn:active, .kml-icn:focus, .kml-icn:hover, .kml-icn.active {\
                   text-decoration: none; background-image: none; outline: 0;\
                   -webkit-box-shadow: none; box-shadow: none; cursor: pointer; }\n\
                .kml-icn-off, .kml-icn-off:hover, .kml-icn-off:focus, a.kml-icn.kml-icn-off, a:link.kml-icn.kml-icn-off, a:hover.kml-icn.kml-icn-off, a.kml-icn.kml-icn-off:focus {\
                   color: #B1D4DF !important; cursor: default !important; pointer-events: none; }\n\
                span.kml-icn-btn { padding: 0; margin: 0px 10px 10px 0px; }\n';

            // CSS for settings panel
            kmlStyle.innerHTML += '\
                div.kml-panel-blackout { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;\
                   background: rgba(0,0,0,0.5); z-index: 2000; }\n\
                div.kml-panel-clear { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;\
                   background: transparent; z-index: 2001; }\n\
                .kml-panel { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);\
                   width:' + panelWidth + 'px; \
                   padding: 10px; margin: 0; overflow: visible !important; word-wrap: normal;\
                   background-color: white; box-shadow: 0px 5px 20px #555555;\
                   border: 1px solid #858585; border-radius: 10px; }\n\
                .kml-panel-section>.controls-container { padding: 0px; width: 100%; white-space: normal; }\n\
                .kml-panel-section>.controls-container>input[type="checkbox"]:checked+label { word-wrap: normal; white-space: normal !important; line-height: 1; margin-bottom: 8px; }\n\
                .kml-panel-section ul.dropdown-menu.locales { max-height: 400px; overflow-y: auto;} \n\
                .kml-panel h2 { margin-top: 10px; margin-bottom: 10px; font-size: 20pt; font-weight: bold; text-align: left; color: #C0C0C0 }\n\
                div.kml-panel-section {display: block; font-size: 12pt; text-align: left; padding: 0px 5px; }\n\
                .kml-panel-hr { display: block; border: 0; height: 0; border-top: 1px solid rgba(0, 0, 0, 0.1);\
                   border-bottom: 1px solid rgba(255, 255, 255, 0.3);\
                   margin-top: 8px; margin-bottom: 12px; }\n\
                .kml-panel-btn { margin: 0px 5px 0px; padding: 0px 15px; display: inline-block; height: 32px; }\n\
                div.kml-panel-btn {display: block; position: relative; padding: 0; width: 480px; margin: auto;\
                   vertical-align: middle; height: 40px; }\n\
                .kml-panel ul>li {padding-bottom: 4px}\n';

            // CSS for beta-editor toggle
            kmlStyle.innerHTML += '\
                .kml-toggle-container { position: absolute; right: 13px; top: 10px; }\n\
                .kml-toggle { position: relative; width: 40px;\
                   -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; }\n\
                .kml-toggle-checkbox { display: none; }\n\
                .kml-toggle-label { display: block;  overflow: hidden; cursor: pointer;  border: 2px solid #DADBDC; border-radius: 20px; }\n\
                .kml-toggle-inner { display: block; width: 200%; margin-left: -100%; transition: margin 0.2s ease-in 0s; }\n\
                .kml-toggle-inner:before, .kml-toggle-inner:after {\
                   display: block; float: left; width: 50%; height: 19px;\
                   padding: 0; line-height: 20px; font-size: 10px; box-sizing: border-box; }\n\
                .kml-toggle-inner:before { content: ""; padding-left: 5px; background-color: #FC6C70; }\n\
                .kml-toggle-inner:after { content: ""; padding-right: 5px; background-color: #93C4D3; }\n\
                .kml-toggle-switch { display: block; width: 22px; margin: 0px;\
                   position: absolute; top: 0; bottom: 0; right: 17px; background: #FFFFFF;\
                   border: 2px solid #DADBDC; border-radius: 20px; transition: all 0.2s ease-in 0s; }\n\
                .kml-toggle-checkbox:checked + .kml-toggle-label .kml-toggle-inner { margin-left: 0; }\n\
                .kml-toggle-checkbox:checked + .kml-toggle-label .kml-toggle-switch { right: 0px; }\n\
                .kml-toggle-switchD { display: block; width: 22px; margin: 1px 0px 1px;\
                   position: absolute; top: 0; bottom: 0; right: 17px; background: #FFFFFF;\
                   border: 2px solid #DADBDC; border-radius: 20px; }\n\
                .kml-toggle-innerD { display: block; width: 200%; margin-left: -100%; }\n\
                .kml-toggle-innerD:before, .kml-toggle-innerD:after {\
                   display: block; float: left; width: 50%; height: 20px;\
                   padding: 0; line-height: 20px; font-size: 10px; box-sizing: border-box; }\n\
                .kml-toggle-innerD:before { content: ""; padding-left: 5px; background-color: #DADBDC; }\n\
                .kml-toggle-innerD:after { content: ""; padding-right: 5px; background-color: #DADBDC; }\n';

            // CSS for layer set dropdown
            kmlStyle.innerHTML += '\
                .kml-layers-menu.kml-layers { white-space: normal; width: 200px !important; position: relative; border-radius:0px; border: 1px solid #DDDDDD; top: 0px; margin: 0; padding: 0;}\n\
                .kml-layers-menu.divider { background-color: #D4E7ED !important; margin: 0px !important; padding: 0px !important; height: 2px; }\n\
                .kml-layers-menu>li>a:active, .kml-layers-menu>li>a.active { background-color: #D4E7ED; }\n\
                .kml-layers-menu>li>a:hover { background-color: #DFECF0; color: #5A899F; }\n\
                .kml-layers-menu>li>a { font-weight: 600; color: #5A899F; word-wrap: break-word; white-space: normal; padding: 10px 10px 10px 10px;}\n\
                .dropdown.kml-layers:hover .dropdown-menu { display: block; visibility: visible; }\n\
                .kml-layers-icon { color: #58889E; width: 10px !important; height: 20px; right: 4px; top: 38% }\n\
                .kml-layers { width: 20px !important; }\n\
                .toolbar-button.kml-layers-icon:after, .toolbar-button.kml-layers-icon:before { left: 0px !important; right: 0px !important; width: 10px !important; }\n\
                .toolbar-button.kml-layers:after, .toolbar-button.kml-layers:before { display: none !important; }'; //left: 0px !important; right: 0px !important; width: 19px !important;

            document.head.appendChild(kmlStyle);
            kmlStyle = null;

            // Add save layers icon to Layers switcher dropdown panel
            var kmlDiv = document.createElement("div");
            kmlDiv.className = "kml-icn";
            kmlDiv.innerHTML = '\
                <a href="javascript:void(0)" class="kml-icn"><div id="iKMLsaveLayers" class="icon-save fa fa-save kml-icn-btn reload-button" data-toggle="tooltip" title="Save Current Set of Layers"></div></a>\
                <a href="javascript:void(0)" class="kml-icn"><div id="iKMLsettings" class="icon-cog fa fa-cog kml-icn-btn reload-button" data-toggle="tooltip" title="KeepMyLayers Preferences"></div></a>\
                <a href="javascript:void(0)" class="kml-icn"><div id="iKMLresetLayers" class="icon-magic fa fa-magic kml-icn-btn reload-button" data-toggle="tooltip" title="Reset Layers to My Settings"></div></a>\
                <div id="iKMLtempUndo" class="icon-eye-open fa fa-eye kml-icn-btn reload-button kml-icn-off" data-toggle="tooltip" title="Toggle Layers from Permalink"></div>';

            document.getElementById("layer-switcher-list").parentNode.insertBefore(
                kmlDiv, document.getElementById("layer-switcher-list").nextSibling);

            //--------------------------------
            // LAYER SET DROPDOWN MENU
            //--------------------------------
            kmlDiv = document.createElement("div");
            kmlDiv.className = "btn-group dropdown toolbar-button kml-layers";
            kmlDiv.style.verticalAlign = "middle";
            //'<div class="btn-group toolbar-button" style="width: 20px; vertical-align: middle">' +
            kmlDiv.innerHTML =
                '   <div class="toolbar-button kml-layers dropdown-toggle" style="border-left: 1px solid #A8CAD5;" data-toggle="dropdown">\
                       <div class="toolbar-button kml-layers-icon icon-caret-down icon-large fa fa-caret-down fa-lg">\
                       </div>\
                   </div>\
                	<ul class="kml-layers-menu kml-layers dropdown-menu pull-right dropdown-menu-right" \
                		style="">\
                		<li style="padding: 10px">Layers for different editing contexts will go here... You have not saved any yet! To start, selected your default set of layers under the WME Layers menu to the left and then click the red save icon at the bottom corner.</li>\
                	</ul>\
                	</div>'; //'</div>;
            document.getElementById("toolbar").insertBefore(kmlDiv, document.getElementById("layer-switcher"));

            if (myKMLayers) {
                var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map_layers),
                    tryUpdatingLayerNamesAgain = updateKMLayersMenu(myKMLayers, kml_layerSwitcher);


                var kmlTooltipContainerEl = document.createElement('div');
                kmlTooltipContainerEl.id = 'kmlTooltipContainer';
                kmlTooltipContainerEl.className = 'kml-tooltip-container';
                kmlTooltipContainerEl.style.position = 'absolute';
                kmlTooltipContainerEl.style.right = '0px';
                kmlTooltipContainerEl.style.top = '50px';
                kmlTooltipContainerEl.style.visibility = 'hidden';
                kmlTooltipContainerEl.style.width = '500px';
                kmlTooltipContainerEl.style.height = '600px';
                kmlTooltipContainerEl.style.zIndex = '999';
                kmlTooltipContainerEl.style.overflow = 'visible';
                kmlTooltipContainerEl.style.pointerEvents = 'none';

                document.body.appendChild(kmlTooltipContainerEl);



                if (tryUpdatingLayerNamesAgain) {
                    //kmllog('Trying to update layers set menu again in 3 seconds...')
                    setTimeout(function() {
                        try {
                            kml_layerSwitcher = getWazeMapLayersFromSwitcher(unsafeWindow.Waze.map.layers);
                            tryUpdatingLayerNamesAgain = updateKMLayersMenu(myKMLayers, kml_layerSwitcher);
                        } catch (err) {
                            console.warn(err);
                        }
                    }, 3000);
                }
            }

            //------------------ Setup event listeners -------------------
            // buttons under layer menu
            document.getElementById("iKMLsaveLayers").onclick = saveKMLayers;
            document.getElementById("iKMLsettings").onclick = showKMLPrefsPanel;
            document.getElementById("iKMLresetLayers").onclick = userResetOfLayersToSavedKMLayers;
            $(".kml-icn-btn[data-toggle=tooltip]").tooltip();
            //{	placement: 'bottom'	}

            // doubleclick layer menu shortcut for KMLayers preferences panel
            document.getElementById("layer-switcher-menu").ondblclick = showKMLPrefsPanel;

            // Insert beta/prod toggle
            var kmlBetaToggleGM = GM_getValue("WMEKMLayers_Beta"),
                kmlBetaTogSet = localStorage.WME_KMLSettings.indexOf('&b'),
                kmlBetaTogDisabled = localStorage.WME_KMLSettings.indexOf('#b'),
                kmlBetaInitState;

            // Sync betaTog between prod & beta by relying on the existence of WMEKMLayers_Beta in GM scope
            switch (true) {
                case (kmlBetaTogDisabled !== -1 && kmlBetaToggleGM): // if "betaTog is disabled" is set and GM var exists
                    insertKMLBetaToggle('disabled'); // insert betaTog as disabled
                    break;
                case (kmlBetaTogDisabled !== -1 && kmlBetaToggleGM === undefined): // if "betaTog is disabled" is set and GM var doesn't exist
                    localStorage.WME_KMLSettings = localStorage.WME_KMLSettings.replace('#b', ''); // then remove "betaTog is disabled" from settings
                    break;
                case (kmlBetaTogSet === -1 && kmlBetaToggleGM): // if betaTog is not set, but GM var exists
                    localStorage.WME_KMLSettings += '&b'; // then add the setting for betaTog to localStorage
                    insertKMLBetaToggle(kmlBetaToggleGM); // and insert the betaTog -- let the function decide on its state
                    break;
                case (kmlBetaTogSet !== -1 && kmlBetaToggleGM === undefined): // if betaTog is set, but GM var does not exist
                    localStorage.WME_KMLSettings = localStorage.WME_KMLSettings.replace('&b', ''); //then remove betaTog from settings
                    break;
                case (kmlBetaTogSet !== -1): // otherwise, if betaTog set in localStorage and GM var exists,
                    insertKMLBetaToggle(kmlBetaToggleGM); // insert the betaTog and let the function decide on its state
                    break;
            }

            // Make save button red if nothing saved
            //kmllog('Checking for localStorage.WME_KeepMyLayers_lV');
            setTimeout(function() {
                switch (true) {
                    case !myKMLayers:
                    case !myKMLayers.visibleInLayersMenu:
                    case !Object.keys(myKMLayers.visibleInLayersMenu[myKMLayers.idx]).length:
                        document.getElementById("iKMLsaveLayers").classList.add('kml-icn-nsave');
                        break;
                }
                //kmllog('Done checking for localStorage.WME_KeepMyLayers_lV');
            }, 300);

        } else if (document.getElementById("iKMLsaveLayers") !== null) {
            kml[6] = 0;
            return true; //icons already inserted into page
        } else if (kml[6]++ < 30) {
            var waitTime = 200 + (kml[6] * 50);
            setTimeout(initKMLButtons, waitTime);
        } else {
            console.warn('WMEKMLayers:',
                'Unable to insert WME KeepMyLayers under Layers menu.',
                'Element #layer-switcher-list not found on page.')
        }
    };


    //==========================================================================

    //kmllog('Stepping into initKMLButtons()...', '/');
    initKMLButtons();

    //==========================================================================

    window.addEventListener("beforeunload", function() {
        if (localStorage.WME_KMLSettings !== undefined &&
            localStorage.WME_KMLSettings.indexOf('&x') === -1) { // user has NOT set WMEKMLayers to be disabled
            resetLocalWithKMLayers();
        }
    }, false);

    // ~~~ TEMP (clean-up) ~~~
    localStorage.removeItem("WME_KML_Settings");
    GM_deleteValue("WMEKML_Beta");
    GM_deleteValue("WMEKML_Lang");
    //kmllog('Done performing cleanup')

    // ~~~~~~~~~~~~~~~~~~~~~~~
    var kmlNoticePanel = function(kmlPanelType, kmlVersion, kmlNoticeText, kmlForumURL) {
        var kmlNoticeUI = document.createElement("div");
        kmlNoticeUI.id = "divKMLnotice";
        kmlNoticeUI.innerHTML =
            '<i id="iKMLnotice" class="icon-exclamation-sign icon-4x pull-left fa fa-exclamation-circle fa-4x fa-pull-left"></i>' +
            '<h2>WME KMLayers Update</h2>' +
            '<hr class="kml-panel-hr">';
        kmlNoticeUI.innerHTML +=
            '<div class="kml-panel-section" style="font-size: 10pt">' +
            kmlNoticeText +
            '</div>' +
            '<div style="margin-top: 6px; font-size: 10pt">' +
            'For details and screenshots of new features, please visit the forum post <a href="' + kmlForumURL + '" target="_blank">here</a>.' +
            '</div>' +
            '<div style="margin-top:10px; font-size: 8pt;"> ' +
            'Note: This is a one-time alert for WME KMLayers v. ' + kmlVersion +
            '</div>';
        kmlNoticeUI.innerHTML += '<hr class="kml-panel-hr">' +
            '<div style="position: relative; width: 70px; display: block; left: 148px; bottom: 0px; margin: 10px; vertical-align: middle; padding: 0">' +
            '<button id="btnKMLokay" style="width: 70px" class="btn btn-primary kml-panel-btn">OK</button></div>' +
            '</div>';

        switch (kmlPanelType) {
            case "child": //requires also opening the settings panel beforehand
                kmlNoticeUI.className = "kml-panel";
                kmlNoticeUI.style.width = "500px";
                kmlNoticeUI.style.height = "270px";
                document.getElementsByClassName("kml-panel")[0].appendChild(kmlNoticeUI);
                break;
            case "blackout":
                kmlNoticeUI.innerHTML = '<div class="kml-panel" style="width: 420px; padding-left: 15px; padding-right: 15px;">' +
                    kmlNoticeUI.innerHTML;
                kmlNoticeUI.innerHTML += '</div>';
                kmlNoticeUI.className = "kml-panel-blackout"
                document.getElementById("map").appendChild(kmlNoticeUI);
                break;
            case "clear":
                kmlNoticeUI.innerHTML = '<div class="kml-panel" style="width: 420px; padding-left: 15px; padding-right: 15px;">' +
                    kmlNoticeUI.innerHTML;
                kmlNoticeUI.innerHTML += '</div>';
                kmlNoticeUI.className = "kml-panel-clear"
                document.getElementById("map").appendChild(kmlNoticeUI);
                break;
        }

        //document.getElementsByClassName("kml-panel")[0].appendChild(kmlNoticeUI);

        document.getElementById('btnKMLokay').onclick = function() {
            document.getElementById('divKMLnotice').remove();
            localStorage.WME_KMLSettings += '&' + kmlVersion;
        };
    };
    if (localStorage.WME_KMLSettings.indexOf('&') === -1) showKMLPrefsPanel();
    if (localStorage.WME_KMLSettings.indexOf('&' + kmlVersion) === -1) { //Display update notice
        var kmlNoticeText, kmlForumURL = "https://www.waze.com/forum/viewtopic.php?f=819&t=172335&p=1304954#p1304954";

        kmlNoticeText = 'Woohoo! Another update! This update to version 0.4 brings you the following new beta features and bug-fixes:<p>' +
            '<ul><li>Thanks to rickzabel\'s help, the bug that caused part of the URL to repeat itself <i>ad infinitum</i> has been found and squashed</li>' +
            '<li>Double-click on the beta/prod toggle to quickly disable/enable</li>' +
            '<li><div style="display: inline; text-decoration: line-through">Press <b>Alt</b>-key once while hovering the cursor over any PL within the WME window to switch it to the alternative editor (i.e., beta or prod)</div> (disabled for now due to conflict with WME Toolbox)</li>' +
            '<li>Within the preference pane, you can now add additional sets of layers to accommodate various editing contexts </li>' +
            '<li>Double-click on the WME Layer menu icon for easy access to the KMLayers preference pane</li>' +
            '</ul>';

        kmlNoticePanel("blackout", kmlVersion, kmlNoticeText, kmlForumURL);

    }
    //KML = myKMLayers;
};

////////////////////////////////////////////////////////////////////////////
function waitForWazeMap_KMLayers() {
    var waitCount = 0,
        maxWait = 50; //~30 seconds
    //kmllog('Waiting for Waze...', '/');

    var tryInit_KMLayers = function() {
        try {
            if (waitCount < maxWait &&
                "undefined" !== typeof(unsafeWindow) && unsafeWindow.$ &&
                unsafeWindow.Waze && unsafeWindow.Waze.map && unsafeWindow.Waze.map.layers
            ) {
                //kmllog('Initializing...', '/');
                KeepMyLayers();
            } else if (waitCount++ < maxWait) {
                var waitTime = 25 * waitCount;
                setTimeout(tryInit_KMLayers, waitTime);
            } else {
                console.error('WMEKMLayers:',
                    'KeepMyLayers could not find necessary Waze map objects.');
            }
        } catch (err) {
            console.error(
                'WMEKMLayers:',
                'WME KeepMyLayers failed to load',
                'due to some kind of technical script error. :(');
            console.error(err);
        }
    };
    tryInit_KMLayers();
};

////////////////////////////////////////////////////////////////////////////
var isReady = false;
document.onreadystatechange = function() {
    //kmllog('<' + document.readyState + '>', '/');
    if (!isReady) {
        if (document.readyState === 'interactive' || document.readyState === 'complete') {
            isReady = true;

            //kmllog('Inside DOM interactive event interval.', '/');
            requestAnimationFrame(waitForWazeMap_KMLayers);

            if (localStorage.WME_KMLSettings !== undefined &&
                localStorage.WME_KMLSettings.indexOf('&x') !== -1) { // user has set WMEKMLayers to be disabled
                //kmllog("Autocheck of KeepMyLayers at startup is disabled (1).");
            } else {
                resetLocalWithKMLayers();
            }
        }
    }
};