WME KeepMyLayers

(Beta) Resets WME layers to your preferred state plus other fancy stuff.

目前為 2016-02-05 提交的版本,檢視 最新版本

// ==UserScript==
// @name            WME KeepMyLayers
// @namespace       https://greasyfork.org/users/11629-TheLastTaterTot
// @version         0.4.4.1
// @description     (Beta) Resets WME layers to your preferred state plus other fancy stuff.
// @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
//      improve UI and user-friendliness - in progress
//      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 - in progress
//      make it easier to switch among layers - √
//      add the ability assign shortcut keys to layer presets
//      make layers manually sortable or sort ascending

// ################################# 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 ##################################

//========================================================================
//     RRRRRR  EEEEEEE DDDDD   IIIII RRRRRR  EEEEEEE  CCCCC  TTTTTTT
//     RR   RR EE      DD  DD   III  RR   RR EE      CC    C   TTT
//     RRRRRR  EEEEE   DD   DD  III  RRRRRR  EEEEE   CC        TTT
//     RR  RR  EE      DD   DD  III  RR  RR  EE      CC    C   TTT
//     RR   RR EEEEEEE DDDDDD  IIIII RR   RR EEEEEEE  CCCCC    TTT
//========================================================================

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'), ~localStorage.WME_KMLSettings.indexOf('&b'), ~localStorage.WME_KMLSettings.indexOf('&l')];

    if (!~kmlPLhrefLast20.lastIndexOf('&kmlayers')) { //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')) { // beta toggle check //&&
        kmlayersBetaChk = GM_getValue("WMEKMLayers_Beta");

        if (kmlayersBetaChk === true && //if set to beta-editor
            !~location.host.indexOf('editor-b')) { //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')) { //if PL is not www.waze.com
            kmlPLhost = 'http://www.waze.com';
        }
    }

    if (kmlayersStartupChk[2] && !~kmlPLhrefLast20.indexOf('&l=0')) { // 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=0' + kmlPLlayers;
            }
        } else if (kmlayersLangChk) { //is truthy
            var kmlPLpath_exemplar = '/' + kmlayersLangChk + '/editor/';
            if (location.pathname !== kmlPLpath_exemplar) {
                kmlPLpath = kmlPLpath_exemplar;
                kmlPLlayers = '&l=0' + kmlPLlayers;
            }
        }
    }

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

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

        if (kmlayersBetaChk === true && //if set to beta-editor
            !~location.host.indexOf('editor-b')) { //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')) { //if PL is not www.waze.com
            kmlPLhost = 'http://www.waze.com';
        }
    }

    if (!~kmlPLhrefLast20.indexOf('&l=0')) { //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=0' + kmlPLlayers;
            }
        } else if (kmlayersLangChk) { //is truthy
            var kmlPLpath_exemplar = '/' + kmlayersLangChk + '/editor/';
            if (location.pathname !== kmlPLpath_exemplar) {
                kmlPLpath = kmlPLpath_exemplar;
                kmlPLlayers = '&l=0' + 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 KeepMyLayers = function() {
    var kml = Array(10), //counter
        kml_W_map = unsafeWindow.Waze.map,
        kml_W_model = unsafeWindow.Waze.model,
        kml_lFTranslations = {
            closed_problems: [unsafeWindow.I18n.translations[unsafeWindow.I18n.locale].layer_switcher.filters.closed_problems.inactive,
                unsafeWindow.I18n.translations[unsafeWindow.I18n.locale].layer_switcher.filters.closed_problems.active
            ],
            residential: [unsafeWindow.I18n.translations[unsafeWindow.I18n.locale].layer_switcher.filters.residential.inactive,
                unsafeWindow.I18n.translations[unsafeWindow.I18n.locale].layer_switcher.filters.residential.active
            ]
        },
        $ = unsafeWindow.$,
        myKMLayers, kmlVersion = '0.4';

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

    // Add methods to myKMLayers object
    var addMethodsToMyKMLayers = function(mykml) {

        /*var hasSavedLayers = function() {
            if (this.visibleInLayersMenu && Object.keys(this.visibleInLayersMenu).length) {
                return true;
            } else {
                return false;
            }
        };

        var numPresets = mykml.SAVED_PRESETS.length;
        if (numPresets) {
            for (var kml_np = numPresets; kml_np--;) {
                mykml.SAVED_PRESETS[kml_np].hasSavedLayers = hasSavedLayers;
            }
        }*/

        mykml.addNewPreset = function(newKMLayerSetName) {
            var newIdx = this.SAVED_PRESETS.length;
            this.idx = newIdx;
            this.SAVED_PRESETS[newIdx] = {
                name: newKMLayerSetName,
                visibleInLayersMenu: {},
                visibleInLayersMenuRealName: [],
                layerFilters: {
                    mapProblem: 0,
                    mapUpdateRequest: 0,
                    venue: 1
                },
                saved: false
                //hasSavedLayers: hasSavedLayers
            };
        };

        mykml.removePreset = function(removeLayerSetIndex) {
            var numPresets = this.SAVED_PRESETS.length;
            if (numPresets > 1) {
                this.SAVED_PRESETS.splice(removeLayerSetIndex, 1);
                this.idx = numPresets - 2;
            }
        }

        return mykml;
    };

    var createNewMyKMLayers = function() {
        return {
            reset: false,
            idx: 0,
            savedonce: false,
            runonce: false,
            SAVED_PRESETS: []
        };
    };

    //======================================================================
    //   GGGGG EEEEEEE TTTTTTT     SSSSS    AAA   VV     VV EEEEEEE DDDDD
    //  GG     EE        TTT      SS       AAAAA  VV     VV EE      DD  DD
    // GG  GGG EEEEE     TTT       SSSSS  AA   AA  VV   VV  EEEEE   DD   DD
    // GG   GG EE        TTT           SS AAAAAAA   VV VV   EE      DD   DD
    //  GGGGGG EEEEEEE   TTT       SSSSS  AA   AA    VVV    EEEEEEE DDDDDD
    //======================================================================
    var getSavedKMLayers = function() {
        var mykml;

        if (localStorage.WME_KeepMyLayers) {
            //kmllog('Found some saved settings to load!');
            mykml = JSON.parse(localStorage.WME_KeepMyLayers);
            mykml.reset = false;

            /* ~~~~~~~~ TEMP: upgrade to new data structure ~~~~~~~~~~~~~~~ */
            var convertMyKMLayersStructure = function(mykml_old) {
                // Setup new var structure
                var numPresets = mykml_old.visibleInLayersMenu.length,
                    mykml_new = {
                        reset: false,
                        idx: mykml_old.idx,
                        savedonce: true,
                        runonce: true,
                        SAVED_PRESETS: Array(numPresets)
                    },
                    lF;

                if (localStorage.WME_KeepMyLayers_lF) {
                    lF = JSON.parse(localStorage.WME_KeepMyLayers_lF);
                } else {
                    lF = {
                        mapProblem: 0,
                        mapUpdateRequest: 0,
                        venue: 1
                    }
                }

                for (var kml_sp = numPresets; kml_sp--;) {
                    mykml_new.SAVED_PRESETS[kml_sp] = {
                        name: mykml_old.layerSetNames[kml_sp],
                        visibleInLayersMenu: mykml_old.visibleInLayersMenu[kml_sp],
                        visibleInLayersMenuRealName: mykml_old.visibleInLayersMenuRealName[kml_sp],
                        layerFilters: {
                            mapProblem: lF.mapProblem,
                            mapUpdateRequest: lF.mapUpdateRequest,
                            venue: lF.venue
                        },
                        saved: !!(Object.keys(mykml_old.visibleInLayersMenu[kml_sp]).length)
                    }
                }
                return mykml_new;
            };

            // Check for newest object structure
            if (mykml.SAVED_PRESETS === undefined) {
                if (mykml.visibleInLayersMenu !== undefined) { //check that required object key is present
                    // Check for even older object structure and adjust
                    if (mykml.visibleInLayersMenu.constructor !== Array) {
                        var tempHoldingVar = JSON.parse(JSON.stringify(mykml.visibleInLayersMenu));
                        mykml.visibleInLayersMenu = [tempHoldingVar];
                        mykml.layerSetNames = ['My default layers'];
                        mykml.idx = 0;
                    }
                    if (mykml.visibleInLayersMenuRealName === undefined) {
                        mykml.visibleInLayersMenuRealName = Array(mykml.layerSetNames.length);
                    }

                    return mykml = convertMyKMLayersStructure(mykml), localStorage.WME_KeepMyLayers = JSON.stringify(mykml);;
                } else {
                    return mykml = createNewMyKMLayers(), localStorage.WME_KeepMyLayers = JSON.stringify(mykml);
                }

            } else {
                return mykml;
            }
        } else { // myKMLayers has not been saved yet
            /* TODO: Call to popup of instructions for saving default layers set will maybe go here */
            return mykml = createNewMyKMLayers(), localStorage.WME_KeepMyLayers = JSON.stringify(mykml);
        }
    };

    var getMyKMLayersObject = function() {
        var mykml = getSavedKMLayers()

        addMethodsToMyKMLayers(mykml);

        if (mykml.SAVED_PRESETS && !mykml.SAVED_PRESETS.length) {
            mykml.addNewPreset('My default layers');
            localStorage.WME_KeepMyLayers = JSON.stringify(mykml);
        }

        return mykml;
    };

    //======================================================================================
    //  WW     WW   AAA   ZZZZZ EEEEEEE    LL        AAA   YY   YY EEEEEEE RRRRRR   SSSSS
    //  WW     WW  AAAAA     ZZ EE         LL       AAAAA  YY   YY EE      RR   RR SS
    //  WW  W  WW AA   AA   ZZ  EEEEE      LL      AA   AA  YYYYY  EEEEE   RRRRRR   SSSSS
    //  WW WWW WW AAAAAAA  ZZ   EE         LL      AAAAAAA   YYY   EE      RR  RR       SS
    //   WW   WW  AA   AA ZZZZZ EEEEEEE    LLLLLLL AA   AA   YYY   EEEEEEE RR   RR  SSSSS
    //======================================================================================

    // W.map.layers.forEach(function(a,i){console.info('[' + 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;
    };

    //======================================================================================
    //  SSSSS    AAA   VV    VV EEEEEEE    LL        AAA   YY   YY EEEEEEE RRRRRR   SSSSS
    // SS       AAAAA  VV    VV EE         LL       AAAAA  YY   YY EE      RR   RR SS
    //  SSSSS  AA   AA  VV  VV  EEEEE      LL      AA   AA  YYYYY  EEEEE   RRRRRR   SSSSS
    //      SS AAAAAAA   VVVV   EE         LL      AAAAAAA   YYY   EE      RR  RR       SS
    //  SSSSS  AA   AA    VV    EEEEEEE    LLLLLLL AA   AA   YYY   EEEEEEE RR   RR  SSSSS
    //======================================================================================
    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);
            }
        }

        var mykml = getMyKMLayersObject();

        // Save Waze's objects to localStorage and use them as a fail-safe
        /*  if (mykml.idx === 0) {
            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}';
            }
        }*/

        mykml.SAVED_PRESETS[mykml.idx].visibleInLayersMenu = visibleInLayersMenu; //save only visible
        mykml.SAVED_PRESETS[mykml.idx].visibleInLayersMenuRealName = visibleInLayersMenuRealName;
        mykml.SAVED_PRESETS[mykml.idx].layerFilters = {
            venue: kml_W_model.venues.getFilter(),
            mapProblem: kml_W_model.problems.getFilter(),
            mapUpdateRequest: kml_W_model.mapUpdateRequests.getFilter()
        };
        mykml.SAVED_PRESETS[mykml.idx].saved = true;
        mykml.savedonce = true;
        mykml.runonce = true; // failsafe

        localStorage.WME_KeepMyLayers = JSON.stringify(mykml);
        /*
        var kmlSaved = document.createElement("div");
        kmlSaved.id = "KMLSavedPopup";
        kmlSaved.style.fontWeight = "bold";
        kmlSaved.style.position = "absolute";
        kmlSaved.style.display = "block";
        // kmlSaved.style.color = "#80D9FF";
        // kmlSaved.style.bottom = "-28px";
        // kmlSaved.style.right = "4px";
        // kmlSaved.style.padding = '4px 11px';
        // kmlSaved.style.backgroundColor = '#1A1A1A';
        kmlSaved.style.color = "#FFF";
        kmlSaved.style.bottom = "32px";
        kmlSaved.style.right = "3px";
        kmlSaved.style.padding = '8px 25px';
        kmlSaved.style.backgroundColor = '#1A1A1A';
        kmlSaved.style.borderRadius = '5px';
        kmlSaved.style.opacity = 1;
        kmlSaved.style.transitionTimingFunction = 'ease-out';
        kmlSaved.style.transitionDelay = '1.0s'
        kmlSaved.style.transitionDuration = '0.3s'
        kmlSaved.style.zIndex = 5;
        kmlSaved.innerHTML = 'Saved'; //<
        document.getElementById('layer-switcher-list').appendChild(kmlSaved);
        */

        document.querySelector('#iKMLsaveLayers+div.tooltip>.tooltip-inner').innerHTML = '<div style="padding: 0px 24%; line-height: 2.75">&nbsp;SAVED&nbsp;</div>';
        //document.getElementById('iKMLsaveLayers').classList.remove('kml-icn-nsave');
        updateKMLayersSaveButton(true);

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

    //=============================================================================
    //     PPPPPP  LL         LL        AAA   YY   YY EEEEEEE RRRRRR   SSSSS
    //     PP   PP LL         LL       AAAAA  YY   YY EE      RR   RR SS
    //     PPPPPP  LL         LL      AA   AA  YYYYY  EEEEE   RRRRRR   SSSSS
    //     PP      LL         LL      AAAAAAA   YYY   EE      RR  RR       SS
    //     PP      LLLLLLL    LLLLLLL AA   AA   YYY   EEEEEEE RR   RR  SSSSS
    //=============================================================================
    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;
                }
            }
            return kml_layerVisibility_orig;
        } else {
            return false;
        }
    };

    var togglePLLayersEventListener = function(kml_toggledLayers, mykml) {
            if (mykml === undefined) mykml = getMyKMLayersObject();
            if (kml_toggledLayers === undefined) console.error('togglePLLayersEventListener requires an object containing layers that have been toggled!');

            document.getElementById('iKMLtempUndo').onclick = function togglePLLayers() {
                var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map.layers),
                    kml_accelNames = Object.keys(kml_layerSwitcher.accelerator),
                    kml_layerVisibility_kmlayers = mykml.SAVED_PRESETS[mykml.idx].visibleInLayersMenu,
                    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]];
                        setKMLayerVisibility(W_map_layers_idx, kml_toggledLayers[kml_accelNames[kml_tog]], kml_tog);
                    }
                }
                // Toggle icon
                document.getElementById('iKMLtempUndo').classList.toggle('fa-eye'); //beta editor - fontawesome 4.x
                document.getElementById('iKMLtempUndo').classList.toggle('fa-eye-slash'); //beta editor - fontawesome 4.x
                document.getElementById('iKMLtempUndo').classList.toggle('icon-eye-open'); //prod editor - fontawesome 3.x
                document.getElementById('iKMLtempUndo').classList.toggle('icon-eye-close'); //prod editor - fontawesome 3.x
            };
        }
        //var enableTogglePLBit = false;
    var enableTogglePLLayersButton = function(kmlResetStatus, mykml) {
        //kmllog('enableTogglePLLayersButton()');

        if (mykml === undefined) mykml = getMyKMLayersObject();
        if (kmlResetStatus === undefined) kmlResetStatus = mykml.reset;

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

            if (kmlResetStatus && mykml.SAVED_PRESETS.length && mykml.SAVED_PRESETS[mykml.idx] && mykml.SAVED_PRESETS[mykml.idx].saved) {
                //kmllog('Checking for toggled layers from PL');

                var kml_layerVisibility_orig = convertLayersToObj(), //kml_layerVisibility_kmlayers = mykml.SAVED_PRESETS[mykml.idx].visibleInLayersMenu,
                    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) { // true only if &kmlayers= is in the URL
                    //console.info(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;

                        currentVisibility = kml_W_map.layers[W_map_layers_idx].getVisibility();

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

                    // var kmlayersQueryCode = !!(location.href.search(/&kmlayers=(\d*)/)+1);
                    var kmlUndoBtnEl = document.getElementById('iKMLtempUndo');
                    if (nToggled !== 0) {
                        //kmllog('Layer visibilities were reset to preferred default setting.', '/');
                        kmlUndoBtnEl.classList.remove('kml-icn-off');
                        togglePLLayersEventListener(kml_toggledLayers, mykml);

                    } else {
                        kmlUndoBtnEl.classList.add('kml-icn-off');
                        try {
                            document.getElementById('iKMLtempUndo').removeEventListener('click', togglePLLayers);
                        } catch (err) {
                            /* do nothing */
                        }
                    }
                } // else do nothing, as there is nothing to undo bc layers were not reset
            }
        } else if (kml[2]++ < 30) {
            //kmllog(waitTime, 'ms');
            setTimeout(function() {
                enableTogglePLLayersButton(kmlResetStatus, mykml)
            }, 300 + (kml[2] * 50));
        } else {
            console.warn('WMEKMLayers:',
                'Unable to activate "Undo KMLayers Reset".',
                'Element #iKMLtempUndo not found on page.');
        }
    };
    //============================================================================================
    // RRRRRR  EEEEEEE  SSSSS  EEEEEEE TTTTTTT    LL        AAA   YY   YY EEEEEEE RRRRRR   SSSSS
    // RR   RR EE      SS      EE        TTT      LL       AAAAA  YY   YY EE      RR   RR SS
    // RRRRRR  EEEEE    SSSSS  EEEEE     TTT      LL      AA   AA  YYYYY  EEEEE   RRRRRR   SSSSS
    // RR  RR  EE           SS EE        TTT      LL      AAAAAAA   YYY   EE      RR  RR       SS
    // RR   RR EEEEEEE  SSSSS  EEEEEEE   TTT      LLLLLLL AA   AA   YYY   EEEEEEE RR   RR  SSSSS
    //============================================================================================
    var checkForReqLayers = function(permalink) {
        //kmllog('checkForReqLayers()');
        switch (true) {
            case !!~permalink.indexOf('&mapUp'):
                return "toggleUpdateRequests";
            case !!~permalink.indexOf('&ven'):
                return "togglePlaces";
            case !!~permalink.indexOf('&mapPr'):
                return "toggleMapProblems";
            case !!~permalink.indexOf('&bigJ'):
                return "toggleJunctionboxes";
            case !!~permalink.indexOf('&cam'):
                return "toggleSpeedcameras";
            default:
                return false;
        }
    };

    //----------------------------------------------------------------------
    function setKMLayerVisibility(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) {
            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) {

                    setKMLayerVisibility(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) {
            var kmlWaitTime = 200 * kml_wait;
            setTimeout(function() {
                waitForMissedLayers(kmlWaitAccelName_m, visibleMyKMLayersAccelObj, kml_wait)
            }, kmlWaitTime);
        } else {
            setTimeout(function() {
                enableTogglePLLayersButton(true);
            }, 300);
        }
    };

    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);
    };


    var updateKMLayerFilters = function(lF) {
        // Adjust visibility of secondary layer filters (residential, closed URs/MPs)
        kml_W_model.repositoryFilters.set('venue', lF.venue);
        kml_W_model.repositoryFilters.set('mapUpdateRequest', lF.mapUpdateRequest);
        kml_W_model.repositoryFilters.set('mapProblem', lF.mapProblem);
        unsafeWindow.W.controller.updateModel(true);
        document.querySelector('li[data-layer-id="' + kml_W_map.landmarkLayer.id + '"] a').innerHTML = kml_lFTranslations.residential[lF.venue ^ 1];
        document.querySelector('li[data-layer-id="' + kml_W_map.updateRequestLayer.id + '"] a').innerHTML = kml_lFTranslations.closed_problems[lF.mapUpdateRequest ^ 1];
        document.querySelector('li[data-layer-id="' + kml_W_map.problemLayer.id + '"] a').innerHTML = kml_lFTranslations.closed_problems[lF.mapProblem ^ 1];
    };

    //----------------------
    function resetLayersToSavedKMLayers(kml_exclude, mykml) {
        //kmllog('resetLayersToSavedKMLayers(' + kml_exclude + ')');

        if (mykml === undefined) mykml = getMyKMLayersObject();
        if (kml_exclude === undefined) kml_exclude = false;

        if (mykml !== undefined && mykml.SAVED_PRESETS[mykml.idx] !== undefined && mykml.SAVED_PRESETS[mykml.idx].saved) {

            var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map.layers),
                switcherAccelObj = kml_layerSwitcher.accelerator,
                switcherAccelNames = Object.keys(switcherAccelObj),
                kml_switcherName,
                visibleMyKMLayersAccelObj = mykml.SAVED_PRESETS[mykml.idx].visibleInLayersMenu,
                visibleMyKMLayersAccelName = Object.keys(visibleMyKMLayersAccelObj),
                togglePlacesAndPURs = false;

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

            for (var kml_sw = 0, kml_sw_length = switcherAccelNames.length; kml_sw < kml_sw_length; kml_sw++) {
                kml_switcherName = switcherAccelNames[kml_sw];

                setKMLayerVisibility(switcherAccelObj[kml_switcherName], !!visibleMyKMLayersAccelObj[kml_switcherName], kml_sw);
            }

            if (document.getElementById('layer-switcher-menu') !== null) {
                setTimeout(function() {
                    updateKMLayerFilters(mykml.SAVED_PRESETS[mykml.idx].layerFilters);
                }, 200);
            }

            mykml.reset = true;
            localStorage.WME_KeepMyLayers = localStorage.WME_KeepMyLayers.replace(/reset":true/, 'reset":false');


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

            try {
                document.getElementById('iKMLtempUndo').classList.toggle('fa-eye', true); //beta editor - fontawesome 4.x
                document.getElementById('iKMLtempUndo').classList.toggle('fa-eye-slash', false); //beta editor - fontawesome 4.x
                document.getElementById('iKMLtempUndo').classList.toggle('icon-eye-open', true); //prod editor - fontawesome 3.x
                document.getElementById('iKMLtempUndo').classList.toggle('icon-eye-close', false); //prod editor - fontawesome 3.x
            } catch (err) {
                /* do nothing */
            }
        }
    };

    //----------------------------------------------------------------------
    var userResetOfLayersToSavedKMLayers = function(myKMLayersStatus, mykml) {
        //kmllog('userResetOfLayersToSavedKMLayers()');
        if (mykml === undefined) mykml = getMyKMLayersObject();

        if (myKMLayersStatus === undefined) {
            myKMLayersStatus = mykml.SAVED_PRESETS[mykml.idx].saved;
        }

        if (myKMLayersStatus) {
            resetLayersToSavedKMLayers(mykml);

        } else {
            //kmllog('Nothing to reset.');
            return false;
        }
    };

    //--------------------------------------------------------------------------------------------
    //  OOOOO  TTTTTTT HH   HH EEEEEEE RRRRRR     LL        AAA   YY   YY EEEEEEE RRRRRR   SSSSS
    // OO   OO   TTT   HH   HH EE      RR   RR    LL       AAAAA  YY   YY EE      RR   RR SS
    // OO   OO   TTT   HHHHHHH EEEEE   RRRRRR     LL      AA   AA  YYYYY  EEEEE   RRRRRR   SSSSS
    // OO   OO   TTT   HH   HH EE      RR  RR     LL      AAAAAAA   YYY   EE      RR  RR       SS
    //  OOOO0    TTT   HH   HH EEEEEEE RR   RR    LLLLLLL AA   AA   YYY   EEEEEEE RR   RR  SSSSS
    //--------------------------------------------------------------------------------------------


    var applyAdditionalKMLSettings = function() {
        //kmllog('applyAdditionalKMLSettings()', '/');
        // ['&x', '&b', '&l', '&1', '&5', '&2']; //disable, beta, lang, city, am, roads
        if (~localStorage.WME_KMLSettings.indexOf('&1')) {
            if (kml_W_map.layers[1].opacity !== 0.8) {
                kml_W_map.layers[1].setOpacity(0.8);
                kmllog('Opacity of Cities layer increased.');
            }
        } else {
            if (kml_W_map.layers[1].opacity === 0.8) {
                kml_W_map.layers[1].setOpacity(0.5);
                kmllog('Opacity of Cities layer at default.');
            }
        }
        if (~localStorage.WME_KMLSettings.indexOf('&5')) {
            if (kml_W_map.managedAreasLayer.options.styleMap.styles.default.defaultStyle.fillOpacity !== 0.1) {

                kml_W_map.managedAreasLayer.options.styleMap.styles.default.defaultStyle.fillOpacity = 0.1;
                kml_W_map.managedAreasLayer.setZIndex(334);

                kmllog('Opacity of AM layer decreased.');
                try {
                    unsafeWindow.Waze.controller.reload();
                } catch (err) {};
            }
        } else {
            if (kml_W_map.managedAreasLayer.options.styleMap.styles.default.defaultStyle.fillOpacity < 0.3) {
                kml_W_map.managedAreasLayer.options.styleMap.styles.default.defaultStyle.fillOpacity = 0.3;
                kml_W_map.managedAreasLayer.setZIndex(350);
                kmllog('Opacity of AM layer returned to normal.');
                try {
                    unsafeWindow.Waze.controller.reload();
                } catch (err) {};
            }
        }
        if (~localStorage.WME_KMLSettings.indexOf('&2')) {
            if (kml_W_map.layers[2].opacity === 1) {
                kml_W_map.layers[2].setOpacity(0.82);
                kmllog('Opacity of Roads layer decreased.');
            }
        } else {
            if (kml_W_map.layers[2].opacity !== 1) {
                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')) { // user has set WMEKMLayers to be disabled
            kmllog('WMEKMLayers:', 'KeepMyLayers at page load is disabled.');
            return false;
        } else {
            return true;
        }
    };

    ///////////////////////////////////////////////////////////////////////////////
    //                       __ __  __  ___ __                                   //
    //    ____ ___   __  __ / //_/ /  |/  // /   ____ _ __  __ ___   _____ _____ //
    //   / __ `__ \ / / / // ,<   / /|_/ // /   / __ `// / / // _ \ / ___// ___/ //
    //  / / / / / // /_/ // /| | / /  / // /___/ /_/ // /_/ //  __// /   (__  )  //
    // /_/ /_/ /_/ \__, //_/ |_|/_/  /_//_____/\__,_/ \__, / \___//_/   /____/   //
    //            /____/                             /____/                      //
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    myKMLayers = getMyKMLayersObject();
    //KML = myKMLayers;

    if (runSecondaryKMLayersCheck() &&
        myKMLayers.SAVED_PRESETS &&
        myKMLayers.SAVED_PRESETS[myKMLayers.idx] &&
        myKMLayers.SAVED_PRESETS[myKMLayers.idx].saved) {

        resetLayersToSavedKMLayers(checkForReqLayers(location.href), myKMLayers);
    }

    applyAdditionalKMLSettings();

    var kmlayersBetaChk = GM_getValue("WMEKMLayers_Beta"),
        kmlayersLangChk = GM_getValue("WMEKMLayers_Lang");
    //                                                                          //
    //////////////////////////////////////////////////////////////////////////////

    //-----------------------------------------------------------------------------
    //  UU   UU  SSSSS    AAA     GGGGG EEEEEEE    HH   HH EEEEEEE LL      PPPPPP
    //  UU   UU SS       AAAAA   GG     EE         HH   HH EE      LL      PP   PP
    //  UU   UU  SSSSS  AA   AA GG  GGG EEEEE      HHHHHHH EEEEE   LL      PPPPPP
    //  UU   UU      SS AAAAAAA GG   GG EE         HH   HH EE      LL      PP
    //   UUUUU   SSSSS  AA   AA  GGGGGG EEEEEEE    HH   HH EEEEEEE LLLLLLL PP
    //-----------------------------------------------------------------------------

    var insertKMLPopupCssToDOM = function(popupId, arrowSidePosition, arrowPosDistProp, popupWidth, offScreenSideProp) {
        var usageCssEl = document.createElement('style'),
            arrowPosDistProp2, arrowFeatBorder, arrowFeatMargin;


        switch (arrowSidePosition) {
            case 'top':
                if (arrowPosDistProp == '') arrowPosDistProp = 'left: 50%';
                arrowPosDistProp2 = 'bottom: 100%';
                arrowSpacerMargin = 'margin: 10px 0px';

                arrowFeatBorder  = 'border-bottom-color: ';
                arrowFeatMargin = 'margin-left: ';
            break;

            case 'bottom':
                if (arrowPosDistProp == '') arrowPosDistProp = 'left: 50%';
                arrowPosDistProp2 = 'top: 100%'
                arrowSpacerMargin = 'margin: 10px 0px';

                arrowFeatBorder = 'border-top-color: ';
                arrowFeatMargin = 'margin-left: ';
            break;

            case 'right':
                if (arrowPosDistProp == '') arrowPosDistProp = 'top: 50%';
                arrowPosDistProp2 = 'left: 100%';
                arrowSpacerMargin = 'margin: 0px 10px';

                arrowFeatBorder = 'border-left-color: ';
                arrowFeatMargin = 'margin-top: ';
            break;

            case 'left':
                if (arrowPosDistProp == '') arrowPosDistProp = 'top: 50%';
                arrowPosDistProp2 = 'right: 100%;';
                arrowSpacerMargin = 'margin: 0px 10px';

                arrowFeatBorder = 'border-right-color: ';
                arrowFeatMargin = 'margin-top: ';
            break;
        }

        usageCssEl.type = 'text/css'
        usageCssEl.id = 'cssKMLPopup_' + popupId;
        usageCssEl.innerHTML = '#' + popupId + '.kml-arrow-box { width: ' + popupWidth + '; z-index: 9999; position: relative; background: #D04294; border: 1px solid #cf38a6; border-radius: 4px; box-shadow: 0px 4px 10px rgba(0,0,0,0.8); padding: 10px 10px 8px ; color: #FFF; ' + arrowSpacerMargin + '; overflow: visible; transition: all .2s ease-out 0s;}\n' +
            '.kml-arrow-box.kml-grow, .kml-arrow-box.kml-grow .kml-header, .kml-arrow-box.kml-grow h4, .kml-arrow-box.kml-grow i.kml-header-icon, .kml-arrow-box.kml-grow div.kml-section {width: 150px !important; height: 1px !important; padding: 0; margin: 0; opacity: 0 !important; overflow: hidden !important; font-size: 1px !important; color: transparent !important; line-height: 0.1 !important; overflow: hidden !important; ' + offScreenSideProp + ' !important; }\n' +
            '#' + popupId + '.kml-arrow-box:after, #' + popupId + '.kml-arrow-box:before {' + arrowPosDistProp + '; ' + arrowPosDistProp2 + '; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; }\n' +
            '#' + popupId + '.kml-arrow-box:after { border-color: transparent; ' + arrowFeatBorder + '#cf38a6; border-width: 8px; ' + arrowFeatMargin + '-8px; }\n' +
            '#' + popupId + '.kml-arrow-box:before { border-color: transparent; ' + arrowFeatBorder + '#cf38a6; border-width: 9px; ' + arrowFeatMargin + '-9px; }\n' +
            '#' + popupId + '.kml-arrow-box br { line-height: 2; }\n';
        document.body.appendChild(usageCssEl);
        return usageCssEl;
    };

    var createKMLPopupNode = function(popupId, usageTitle, usageText, popupStyleProps, parentNodeEl) {
        // popupStyleProps is for specifying the position of the popup container
        var kmlPopupEl = document.createElement('div');
        kmlPopupEl.id = popupId;
        kmlPopupEl.className = 'kml-arrow-box kml-grow';
        (usageTitle === '') ? usageTitle = '&nbsp;KMLayers Usage Tip' : usageTitle = '&nbsp;' + usageTitle;

        if (popupStyleProps !== '') {
            kmlPopupEl.setAttribute('style', 'position: absolute; ' + popupStyleProps);
        }

        kmlPopupEl.innerHTML = '<div class="kml-header">' +
            '<i class="kml-header-icon pull-left icon-info-sign fa fa-info-circle fa-pull-left"' +
            ' style="font-size: 26px; margin: auto; color: #54265F; line-height: 28px; height: 28px; width: 28px;"></i>' +
            '<h4 style="margin-top: -5px; margin-bottom: 5px; margin-left: -11px; margin-right: -11px; padding: 4px; padding-left: 36px; font-size: 12pt; font-weight: 600; text-align: left; color: #8D529C; background-color: rgba(255,199,242,0.6);">' +
            usageTitle + '</h4>' +
            '</div><div class="kml-section" style="font-size: 9pt; line-height: normal;">' +
            usageText +
            '</div></div>';

        parentNodeEl.appendChild(kmlPopupEl);

        setTimeout(function() {
            kmlPopupEl.classList.remove('kml-grow')
        }, 200);

        return kmlPopupEl;
    };

    var trackUsagePopupDisplay = function(kmlUsageQueryCode) {
        if (!~localStorage.WME_KMLUsageHelper.indexOf(kmlUsageQueryCode)) {
            localStorage.WME_KMLUsageHelper += kmlUsageQueryCode;
            requestAnimationFrame(function() {
                GM_setValue('WMEKMLayers_Usage', localStorage.WME_KMLUsageHelper)
            });
        }
    };

    var hasSeenUsagePopup = function(kmlUsageQueryCode) {
        if (!~localStorage.WME_KMLUsageHelper.indexOf(kmlUsageQueryCode)) {
            return false;
        } else {
            return true;
        }
    };

    var KMLayersUsageHelper = function(kmlHelpTopic, hasSeenOnce) {
        // hasSeenOnce:   [true|false|'none'];
        //                Has the usageHelper popup been displayed at least once before?
        //                  Popup will _not_ display for only boolean `true`

        if (hasSeenOnce !== true) {

            //localStorage.WME_KMLUsageHelper.match(/&0.4(=\d|,\d)*/g)[0].match(/[=|,](\d)/g).map(function(a){return a.substr(-1)})
            var usageTitle, usageText, usageId;

            switch (kmlHelpTopic) {
                case 'layer_presets_runonce':
                    document.getElementById('kmlDropdownMenu').classList.add('kml-keep-open');
                    document.getElementById('kmlDropdownMenu').classList.add('open');
                    localStorage.WME_KeepMyLayers = localStorage.WME_KeepMyLayers.replace(/runonce":false/, 'runonce":true');
                    document.querySelector('#kmlDropdownMenu li').classList.toggle('kml-usage-helper');
                    setTimeout(function() {
                        document.querySelector('#kmlDropdownMenu li').classList.toggle('kml-usage-helper');
                    }, 10000);

                    break;

                case 'stay_open_dropdown_menu':
                    var popupParentEl = document.getElementById('kmlDropdownMenu');
                    if (popupParentEl) {
                        usageId = 'kmlStayopenPopup';
                        usageTitle = 'Preset-Switcher Menu';
                        usageText = 'Depress the KMLayers menu button to force it to stay open on the screen. It can be used for quickly switching among saved presets and it will automatically fade and tuck itself away when not in focus.';

                        var kmlStayopenPopupCssEl = insertKMLPopupCssToDOM(usageId, 'top', 'right: 2px', '240px', 'right: -40px');
                        var kmlStayopenPopupEl = createKMLPopupNode(usageId, usageTitle, usageText, 'top: 40px; right: 0px;', popupParentEl);

                        document.getElementById(usageId).onclick = function() {
                            kmlStayopenPopupCssEl.remove();
                            kmlStayopenPopupEl.classList.toggle('kml-grow');
                            setTimeout(function(){kmlStayopenPopupEl.remove()}, 250);
                            if (hasSeenOnce === false) trackUsagePopupDisplay('&m');
                        };
                    } else {
                        setTimeout(function() {
                            KMLayersUsageHelper('stay_open_dropdown_menu', false)
                        }, 500);
                    }

                    break;

                case 'beta_toggle':
                    var popupParentEl = document.getElementById('map-search').parentNode;
                    if (popupParentEl) {
                        usageId = 'kmlBetaTogPopup';
                        usageTitle = 'Beta-Prod Editor Toggle';
                        usageText = 'Switch to Beta (Red) or to Prod (Blue) to force WME to always load in that editing mode. Double-click on the toggle to disable it. <br/>Note: If you are not part of the WME Beta program, you will not typically need this feature and can turn it off in the KMLayers preference pane.';

                        var kmlBetaTogPopupCssEl = insertKMLPopupCssToDOM(usageId, 'left', 'top: 22px', '280px', 'left: -60px');
                        var kmlBetaTogPopupEl = createKMLPopupNode(usageId, usageTitle, usageText, 'top: 1px; left: 0px;', popupParentEl);

                        document.getElementById(usageId).onclick = function() {
                            kmlBetaTogPopupCssEl.remove();
                            kmlBetaTogPopupEl.classList.toggle('kml-grow');
                            setTimeout(function(){kmlBetaTogPopupEl.remove()}, 250);
                            if (hasSeenOnce === false) trackUsagePopupDisplay('&b');
                        };
                    } else {
                        setTimeout(function() {
                            KMLayersUsageHelper('beta_toggle', false)
                        }, 500);
                    }
                    break;

                case 'alt_permalink':
                    var popupParentEl = document.getElementById('kmlAltPermalink');
                    if (popupParentEl) {
                        usageId = 'kmlAltPLPopup';
                        usageTitle = 'Alt-Editor Permalink';
                        usageText = 'The alternate editor permalink (alt-PL) comes with the Beta-Prod toggle. Clicking alt-PL will take you to the alternate editor (i.e., Prod if currently in Beta or Beta if currently in Prod). It tags the PL with \"&b=0\", which temporarily disables KMLayers\' Beta-Prod editor redirection. You can also hover over the icon and copy to clipboard.';

                        var kmlAltPLPopupCssEl = insertKMLPopupCssToDOM(usageId, 'bottom', 'right: 16px', '320px', 'bottom: -50px');
                        var kmlAltPLPopupEl = createKMLPopupNode(usageId, usageTitle, usageText, 'bottom: 23px; right: -15px;', popupParentEl);

                        document.getElementById(usageId).onclick = function() {
                            kmlAltPLPopupCssEl.remove();
                            kmlAltPLPopupEl.classList.toggle('kml-grow');
                            setTimeout(function(){kmlAltPLPopupEl.remove()}, 250);
                            if (hasSeenOnce === false) trackUsagePopupDisplay('&a');
                        };
                    } else {
                        setTimeout(function() {
                            KMLayersUsageHelper('alt_permalink', false)
                        }, 500);
                    }
                    break;

            } //switch
        } //if hasSeenOnce is not boolean true
    };

    //============================================================================
    //        KK  KK MM    MM LL         MM    MM EEEEEEE NN   NN UU   UU
    //        KK KK  MMM  MMM LL         MMM  MMM EE      NNN  NN UU   UU
    //        KKKK   MM MM MM LL         MM MM MM EEEEE   NN N NN UU   UU
    //        KK KK  MM    MM LL         MM    MM EE      NN  NNN UU   UU
    //        KK  KK MM    MM LLLLLLL    MM    MM EEEEEEE NN   NN  UUUUU
    //============================================================================
    // Red save button
    var updateKMLayersSaveButton = function(kmlSavedStatus) {
        // Make save button red if nothing saved (nsave)
        setTimeout(function() {
            if (kmlSavedStatus) {
                document.getElementById("iKMLnotSaved").style.visibility = 'hidden';
            } else {
                document.getElementById("iKMLnotSaved").style.visibility = 'visible';
            }
        }, 300);
    };

    // Dropdown menu for selecting layers
    var updateKMLayersMenu = function(kml_layerSwitcher, mykml) {

        if (mykml === undefined) mykml = getMyKMLayersObject();
        if (kml_layerSwitcher === undefined) kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map.layers);

        var numKMLsets = mykml.SAVED_PRESETS.length,
            findRealNames, missingLayerNames = false,
            layersInTooltipArray, numLayersInTooltip, layerTooltip, ltt, layerRealName,
            selStatus, kmlset, htmlText = '',
            coloredText = Array(2);

        if (mykml.savedonce || numKMLsets > 1) { //both checks included as fail-safes
            coloredText[0] = 'kml-text-nsave';
            coloredText[1] = '';

            kmlset = -1
            while (++kmlset < numKMLsets) {
                findRealNames = false;
                /* ~~~~~~~~~~~~~~~ TEMP: Get real names to update old version of object ~~~~~~~~~~~~~~~ */
                if (mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName === null ||
                    mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName === undefined) {
                    mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName = []; //start with an empty array
                    findRealNames = true;
                } else if (mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName.length !== Object.keys(mykml.SAVED_PRESETS[kmlset].visibleInLayersMenu).length) {
                    mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName = []; //start with an empty array
                    findRealNames = true;
                }

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

                    if (numLayersInTooltip === 0) {
                        layerTooltip = '<ul style="margin: 14px 10px 14px -14px;"><li style="text-align: left;">none</li></ul>';
                    } else {
                        layerTooltip = '<ul style="margin: 14px 10px 14px -14px;">';
                        for (ltt = 0; ltt < numLayersInTooltip; ltt++) {
                            layerRealName = kml_layerSwitcher.name[layersInTooltipArray[ltt]];
                            if (layerRealName !== undefined) {
                                mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName.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(mykml);
                    }
                } else {
                    layersInTooltipArray = mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName;
                    numLayersInTooltip = mykml.SAVED_PRESETS[kmlset].visibleInLayersMenuRealName.length;
                    if (numLayersInTooltip === 0) {
                        layerTooltip = '<ul style="margin: 14px 10px 14px -14px;"><li style="text-align: left;">none</li></ul>';
                    } else {
                        layerTooltip = '<ul style="margin: 14px 10px 14px -14px;">';
                        for (ltt = 0; ltt < numLayersInTooltip; ltt++) {
                            layerTooltip += '<li style="text-align: left;">' + layersInTooltipArray[ltt] + '</li>';
                        }
                        layerTooltip += '</ul>';
                    }
                }

                //---------------------
                (kmlset === mykml.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 + coloredText[0 ^ mykml.SAVED_PRESETS[kmlset].saved] + '" ' +
                    'href="javascript:void(0)">' +
                    '<div>' + mykml.SAVED_PRESETS[kmlset].name + '</div>' +
                    '</a></li>'
                if (kmlset < numKMLsets - 1) {
                    htmlText +=
                        '<li role="separator" class="divider kml-layers-menu"></li>';
                }

            }

            document.querySelector('ul[class*=kml-layers-menu]').innerHTML = htmlText;
            document.getElementById('divKMLlayerName').innerHTML = mykml.SAVED_PRESETS[mykml.idx].name;

            // Setup event listeners for each menu item
            kmlset = -1;
            while (++kmlset < numKMLsets) {
                document.querySelectorAll('a.kml-layers-menu')[kmlset].onclick = function(eee) {
                    eee.stopPropagation();
                    var mykml = JSON.parse(localStorage.WME_KeepMyLayers);

                    document.getElementsByName('kmlSet_' + mykml.idx)[0].classList.remove('active');
                    var kmlThisName = this.name;
                    //kmllog(kmlThisName)
                    document.getElementsByName(kmlThisName)[0].classList.add('active');
                    mykml.idx = parseInt(document.getElementsByName(kmlThisName)[0].getAttribute("value"));
                    document.getElementById('divKMLlayerName').innerHTML = mykml.SAVED_PRESETS[mykml.idx].name;
                    localStorage.WME_KeepMyLayers = localStorage.WME_KeepMyLayers.replace(/idx":\d?/, 'idx":' + mykml.idx);

                    setTimeout(function() {
                        updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);
                        userResetOfLayersToSavedKMLayers(mykml.SAVED_PRESETS[mykml.idx].saved, mykml);
                        enableTogglePLLayersButton(mykml.SAVED_PRESETS[mykml.idx].saved, mykml);
                    }, 150);
                };
            }

            updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);

            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; margin-top: 5px; width: 170px;"></div><div class="tooltip" role="tooltip" style="width: 170px; margin-top: 0px;"><div class="tooltip-arrow" style="display: none; margin-right: 2px;"></div><div class="tooltip-inner" style="margin-left: -5px; padding-right: 0; font-weight: bold; text-align: left; word-wrap: break-word;"></div></div>'
                });
            } catch (err) {
                $(".kml-layers-menu[data-toggle=tooltip]").tooltip();
            }

            return missingLayerNames;
        } else {
            return false;
        }
    };

    //===================================================================
    //    BBBBB   EEEEEEE TTTTTTT   AAA      TTTTTTT  OOOOO    GGGGG
    //    BB   B  EE        TTT    AAAAA       TTT   OO   OO  GG
    //    BBBBBB  EEEEE     TTT   AA   AA      TTT   OO   OO GG  GGG
    //    BB   BB EE        TTT   AAAAAAA      TTT   OO   OO GG   GG
    //    BBBBBB  EEEEEEE   TTT   AA   AA      TTT    OOOO0   GGGGGG
    //===================================================================
    //----------------------------------------------------------------------
    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 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 -----
            // popup prod/beta indicator helper text
            var kmlTogHelpEl = document.createElement('div');
            kmlTogHelpEl.id = 'kmlTogHelp'
            kmlTogHelpEl.setAttribute('style', 'position: absolute; right: 43px; top: 0px; font-size: 16px; font-weight: 600; letter-spacing: -0.5px; text-align: center; color: #C0C0C0; line-height: 1.4; border-radius: 8px; padding: 0px 4px; background-color: rgba(242, 243, 244, 0.5); transition-duration: .2s; transition-timing-function: ease-in-out; opacity: 0;')
            document.getElementsByClassName('kml-toggle-container')[0].appendChild(kmlTogHelpEl);

            var cbKMLtoggleEl = document.getElementById('cbKMLtoggle');
            cbKMLtoggleEl.onclick = function() {
                requestAnimationFrame(function() {
                    GM_setValue("WMEKMLayers_Beta",
                        document.getElementById('cbKMLtoggle').checked);
                });

                setTimeout(function() {
                    switch (true) {
                        case cbKMLtoggleEl.disabled:
                            kmlTogHelpEl.innerHTML = 'DISABLED';
                            break;
                        case cbKMLtoggleEl.checked:
                            kmlTogHelpEl.innerHTML = 'BETA';
                            break;
                        case !cbKMLtoggleEl.checked:
                            kmlTogHelpEl.innerHTML = 'PROD';
                            break;
                    }
                    kmlTogHelpEl.style.opacity = 1;

                    setTimeout(function() {
                        kmlTogHelpEl.style.opacity = 0;
                    }, 600);

                }, 300);
            };

            document.getElementsByClassName('kml-toggle')[0].ondblclick = function(eee) {
                //eee.stopPropagation();
                setTimeout(function() {
                    if (!cbKMLtoggleEl.disabled) {
                        kmlTogHelpEl.innerHTML = 'ENABLED';
                        kmlTogHelpEl.style.opacity = 1;
                    }
                    setTimeout(function() {
                        kmlTogHelpEl.style.opacity = 0;
                    }, 600);
                }, 300);
                toggleKMLToggle();
            };

            // Beta-prod toggle usage helper
            setTimeout(function() {KMLayersUsageHelper('beta_toggle', hasSeenUsagePopup('&b'))}, 1500);

        };

        //---------------
        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')) {
                    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.')
        }
    };
    //========================================================================
    //              AAA   LL     TTTTTTT      PPPPPP  LL
    //             AAAAA  LL       TTT        PP   PP LL
    //            AA   AA LL       TTT        PPPPPP  LL
    //            AAAAAAA LL       TTT        PP      LL
    //            AA   AA LLLLLLL  TTT        PP      LLLLLLL
    //========================================================================
    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, kmlPLColor, inBetaEditor;

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

            if (!~location.host.indexOf('editor-beta')) { // 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 fa fa-circle fa-stack-1x icon-full-width fa-fw" style="color: ' + kmlPLColor + '; font-size: 25px; bottom: 0px;"></span><span class="icon-link icon-light fa fa-link fa-stack-1x fa-inverse icon-full-width fa-fw" style="font-size: 14px; bottom: 0px;"></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+|&mapProblemFilter=\d|&mapUpdateRequestFilter=\d|&venueFilter=\d/g, ''),
                    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);

            setTimeout(function() {KMLayersUsageHelper('alt_permalink', hasSeenUsagePopup('&a'))}, 1500);
        } else {
            setTimeout(initAltPermalink, 500);
        }

    };

    //==============================================================================
    //    PPPPPP  RRRRRR  EEEEEEE FFFFFFF    PPPPPP    AAA   NN   NN EEEEEEE
    //    PP   PP RR   RR EE      FF         PP   PP  AAAAA  NNN  NN EE
    //    PPPPPP  RRRRRR  EEEEE   FFFF       PPPPPP  AA   AA NN N NN EEEEE
    //    PP      RR  RR  EE      FF         PP      AAAAAAA NN  NNN EE
    //    PP      RR   RR EEEEEEE FF         PP      AA   AA NN   NN EEEEEEE
    //==============================================================================

    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 mykml = getMyKMLayersObject(),
            mlBetaInitState = !!~location.host.indexOf('editor-beta'),
            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 page load'
        ]; //[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
        for (var kml_s = 0, numKmlOpt = kmlOptions.length; kml_s < numKmlOpt; kml_s++) {~
            cbKMLSettingsStr.indexOf(allStr[kml_s]) ? 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;

        //----------------------------------------------------------
        // Post note about nedding to save default layers
        if (!mykml.savedonce) {
            //'<div style="color: #FF0080; font-size: 11pt; font-style: normal; margin-right: 4px; display:inline-block" class="icon-save icon-fixed-width fa fa-save fa-fw kml-icn-nsave"></div>'
            $('#KMLnote').append(
                '<span style="font-size:10px">' +
                'Save your first layer preset by selecting your layers under the WME Layers menu and click' +
                '<div class="fa-stack icon-stack kml-icn-btn reload-button" style="margin-right: 5px;" title="Save current set of layers"><div class="icon-save fa fa-save fa-stack-1x" style="color: #59899e;"></div><div class="icon-plus-sign fa fa-plus-circle fa-stack-1x" style="font-size: 10px; margin: -3px -5px 3px 5px; text-shadow: 1px -1px 0px white, 2px -2px 0px white; color: crimson;"></div></div>' +
                'in the bottom-right to save.' +
                '</span>'
            );
        } else { // Dropdown menu of saved layer settings
            $('#KMLnote').append(
                '<div class="form-inline" style="display: inline-block; vertical-align: middle;">' +
                '   <select id="selKMLset" class="form-control" 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>' +
                '');

            for (var kml_sel = 0, numSets = mykml.SAVED_PRESETS.length; kml_sel < numSets; kml_sel++) {
                document.getElementById("selKMLset").add(new Option(mykml.SAVED_PRESETS[kml_sel].name));
            };

            document.getElementById("selKMLset").selectedIndex = mykml.idx;
            document.getElementById("selKMLset").value = mykml.SAVED_PRESETS[mykml.idx].name;

            document.getElementById("selKMLset").onchange = function() {
                mykml.idx = document.getElementById("selKMLset").selectedIndex;
                updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);
            };

            if (kmlayersLangChk) document.getElementById('cbKML_1').checked = true;

            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);
                mykml.addNewPreset(newKMLayerSetName);
                document.getElementById("selKMLset").selectedIndex = mykml.idx;

                updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);
            };


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

                    mykml.removePreset(selectedKMLIndex);
                    document.getElementById("selKMLset").removeChild(document.getElementById("selKMLset").options[selectedKMLIndex]);
                    document.getElementById("selKMLset").selectedIndex = mykml.idx;
                    document.getElementById("selKMLset").value = mykml.SAVED_PRESETS[mykml.idx].name;

                    updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);
                }
            };
        };
        //----------------------------------------------------------------//
        //                 APPLY AND SAVE PREFERENCES                     //
        //----------------------------------------------------------------//
        var applyKMLayersSettings = function() {
            var kmlBetaInitState = !!~location.host.indexOf('editor-b');

            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();
                    document.getElementById('kmlAltPermalink').remove();
                    document.getElementById('kmlAltPLTooltip').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(mykml);

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

            var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map.layers);

            if (mykml && mykml.SAVED_PRESETS && mykml.SAVED_PRESETS.length) {
                updateKMLayersMenu(kml_layerSwitcher, mykml);

                if (mykml.SAVED_PRESETS[mykml.idx].saved) {
                    userResetOfLayersToSavedKMLayers(true, mykml);
                }
            }

            KMLayersUsageHelper('layer_presets_runonce', mykml.runonce);
        }; // applyKMLayersSettings()

        selectLanguageLocale();

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

        document.getElementById('btnKMLcancel').onclick = function() {
            document.getElementById("KMLsettings").remove();
            var tempResetHolder = myKMLayers.reset;
            mykml = getMyKMLayersObject();
            mykml.reset = tempResetHolder;

            updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);
            KMLayersUsageHelper('layer_presets_runonce', mykml.runonce);
        };
    };

    //======================================================================================
    //   KK  KK MM    MM LL         BBBBB   UU   UU TTTTTTT TTTTTTT  OOOOO  NN   NN  SSSSS
    //   KK KK  MMM  MMM LL         BB   B  UU   UU   TTT     TTT   OO   OO NNN  NN SS
    //   KKKK   MM MM MM LL         BBBBBB  UU   UU   TTT     TTT   OO   OO NN N NN  SSSSS
    //   KK KK  MM    MM LL         BB   BB UU   UU   TTT     TTT   OO   OO NN  NNN      SS
    //   KK  KK MM    MM LLLLLLL    BBBBBB   UUUUU    TTT     TTT    OOOO0  NN   NN  SSSSS
    //======================================================================================
    var initKMLButtons = function(mykml) {
        //kmllog('initKMLButtons()');
        if (document.getElementById("layer-switcher-list") && document.getElementById("iKMLsaveLayers") === null) {
            kml[6] = 0; //reset counter
            var panelWidth = 540,
                kmlStyle = document.createElement("style");
            //mykml = JSON.parse(localStorage.WME_KeepMyLayers);

            // 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 { display: block; vertical-align: middle; padding: 9px 0px 0px; margin: 0px; \
                   border-top: 1px solid #D4E7ED; font-weight: bold; }\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\
                .fa-stack.kml-icn-btn, .icon-stack.kml-icn-btn { line-height: 1 !important; height: 11px !important; width: 18px !important;}\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 KMLayers notice panels
            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: 13px; }\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; background-color: #DADBDC; border: 2px solid #DADBDC; border-radius: 21px; }\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: 23px; margin: 0px;\
                   position: absolute; top: 0; bottom: 0; right: 17px; background: #FFFFFF;\
                   border: 2px solid #DADBDC; border-radius: 23px; transition: all 0.1s cubic-bezier(0.55, 0.09, 0.68, 0.53) 0.15s; }\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: 23px; margin: 1px 0px 1px;\
                   position: absolute; top: 0; bottom: 0; right: 17px; background: #FFFFFF;\
                   border: 2px solid #DADBDC; border-radius: 23px; }\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 { z-index: 2; white-space: normal; max-width: 180px; min-width: 160px; position: relative; border-radius:0px; border: 1px solid #DDDDDD; top: 0px; margin: 0; padding: 0;}\n\
                div.toolbar-button>.dropdown-toggle { -webkit-box-shadow: none; box-shadow: none; }\n\
                div.toolbar-button.kml-keep-open>.dropdown-toggle { -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.125); box-shadow: inset 0 3px 5px rgba(0,0,0,0.125); }\n\
                #toolbar .toolbar-button:hover:not(.ItemDisabled):not(:disabled) { background-color: transparent; }\n\
				div.toolbar-button.kml-keep-open>ul.kml-layers-menu.dropdown-menu { right: -100px; display: block; border: 1px solid rgba(221,221,221,0.7); background-color: rgba(255,255,255,0.5); transition-duration: 1s; transition-timing-function: linear; transition-delay: .8s;}\n\
                div.toolbar-button.kml-keep-open-runonce>ul.kml-layers-menu.dropdown-menu { right: 0px; border: 1px solid #DDDDDD; background-color: #fff; }\n\
				div.toolbar-button.kml-keep-open>ul.kml-layers-menu.dropdown-menu:hover, div.toolbar-button.kml-keep-open>ul.kml-layers-menu.dropdown-menu:active, div.toolbar-button.kml-keep-open>ul.kml-layers-menu.dropdown-menu:focus \
					{ right: 0px; border: 1px solid #DDDDDD; background-color: #fff; transition-delay: 0s; transition-duration: .1s; }\n\
                .kml-usage-helper { right: 0px !important; border: 1px solid #DDDDDD !important; background-color: #FFF !important; transition-delay: 0s; transition-duration: .1s; }\n\
				div.toolbar-button.kml-keep-open>ul>li.divider.kml-layers-menu { background-color: rgba(212,231,237,0.4); transition-duration: 1s; transition-timing-function: linear; transition-delay: .8s; }\n\
				div.toolbar-button.kml-keep-open>ul>li.divider.kml-layers-menu:hover, div.toolbar-button.kml-keep-open>ul>li.divider.kml-layers-menu:active, div.toolbar-button.kml-keep-open>ul>li.divider.kml-layers-menu:focus { background-color: #D4E7ED; transition-delay: 0s; transition-duration: .1s; }\n\
    			div.toolbar-button.kml-keep-open li>a:active, div.toolbar-button.kml-keep-open li>a.active { background-color: rgba(212,231,237,0.4); transition-duration: 1s; transition-timing-function: linear; transition-delay: .8s; }\n\
				div.toolbar-button.kml-keep-open li>a.active:hover, div.toolbar-button.kml-keep-open li>a:focus { background-color: #D4E7ED; transition-delay: 0s; transition-duration: .1s; }\n\
                .kml-layers-menu.divider { background-color: #D4E7ED; margin: 0px !important; padding: 0px !important; height: 2px; max-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: #5A898F; }\n\
                .kml-layers-menu>li>a { letter-spacing: 0.4px; font-weight: 600; color: #5A898F; word-wrap: break-word; white-space: normal; padding: 10px 10px 10px 10px;}\n\
                .kml-layers-menu>li>a.kml-text-nsave, .kml-layers-menu>li>a.kml-text-nsave:hover { color: #D36343 !important; }\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";
            //<div id="iKMLsaveLayers" class="icon-save fa fa-save kml-icn-btn reload-button" data-toggle="tooltip" title="Save current set of layers"></div>
            kmlDiv.innerHTML = '\
                <a href="javascript:void(0)" class="kml-icn"><div class="fa-stack icon-stack kml-icn-btn reload-button" id="iKMLsaveLayers" style="margin-right: 8px;" data-toggle="tooltip" title="Save current set of layers"><div class="icon-save fa fa-save fa-stack-1x"></div><div id="iKMLnotSaved" class="icon-plus-sign fa fa-plus-circle fa-stack-1x" style="font-size: 10px; margin: -3px -5px 3px 5px; text-shadow: 1px -1px 0px white, 2px -2px 0px white; color: crimson; visibility: hidden;"></div></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 saved presets"></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>\
                <div id="divKMLlayerName" style="margin-bottom: -4px; padding-left: 14px; color: #93c4d3; line-height: 1;"></div>';

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

            //--------------------------------
            // LAYER PRESETS DROPDOWN MENU
            //--------------------------------
            kmlDiv = document.createElement("div");
            kmlDiv.id = 'kmlDropdownMenu'
            kmlDiv.className = "btn-group dropdown toolbar-button kml-layers";
            kmlDiv.style.verticalAlign = "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">\
                    Layer presets for different editing contexts will go here... \
                    To start, select your layers under the WME Layers menu and click the save icon at the bottom corner when done. \
                    You may add/remove additional presets within the KMLayers preference pane.\
                </li>\
                </ul></div>';
            document.getElementById("toolbar").insertBefore(kmlDiv, document.getElementById("layer-switcher"));

            if (mykml && mykml.SAVED_PRESETS && mykml.SAVED_PRESETS.length) {
                var kml_layerSwitcher = getWazeMapLayersFromSwitcher(kml_W_map.layers),
                    tryUpdatingLayerNamesAgain = updateKMLayersMenu(kml_layerSwitcher, mykml);


                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 = '2';
                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(kml_layerSwitcher, mykml);
                        } catch (err) {
                            console.warn(err);
                        }
                    }, 3000);
                }

                updateKMLayersSaveButton(mykml.SAVED_PRESETS[mykml.idx].saved);

                //-----------------------------------------------------------------------------
                // Delayed resetting of secondary layer filters (residential, UR/MPs) due to delayed loading of layer menu
                requestAnimationFrame(function() {
                    updateKMLayerFilters(mykml.SAVED_PRESETS[mykml.idx].layerFilters);
                });
                //-----------------------------------------------------------------------------

            } else {
                updateKMLayersSaveButton(false);
            }

            //------------------ Setup event listeners -------------------
            // Setup event listener for stay open dropdown
            document.getElementById('kmlDropdownMenu').onclick = function(e) {
                if (this.classList.toggle('kml-keep-open')) {
                    this.classList.remove('open');
                }
            };

            // 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');

            // Sync betaTog between prod & beta by relying on the existence of WMEKMLayers_Beta in GM scope
            switch (true) {
                case (kmlBetaTogDisabled && kmlBetaToggleGM !== undefined): // if "betaTog is disabled" is set and GM var exists
                    insertKMLBetaToggle('disabled'); // insert betaTog as disabled
                    break;
                case (kmlBetaTogDisabled && 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
                    requestAnimationFrame(function() { // Try to remove GM var just in case it exists, but is undefined
                        GM_deleteValue("WMEKMLayers_Beta")
                    });
                    break;
                case (!kmlBetaTogSet && kmlBetaToggleGM !== undefined): // 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
                    setTimeout(function(){if (document.getElementById('cbKML_0') !== null) document.getElementById('cbKML_0').checked = true;}, 1000);
                    break;
                case (kmlBetaTogSet && 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 and don't insert beta-tog
                    requestAnimationFrame(function() { // Try to remove GM var just in case it exists, but is undefined
                        GM_deleteValue("WMEKMLayers_Beta")
                    });
                    setTimeout(function(){if (document.getElementById('cbKML_0') !== null) document.getElementById('cbKML_0').checked = false;}, 1000);
                    break;
                case (kmlBetaTogSet && kmlBetaToggleGM !== undefined): // otherwise, if betaTog set in localStorage and GM var exists,
                    insertKMLBetaToggle(kmlBetaToggleGM); // insert the betaTog and determine state using GM var value
                    break;
            }

            //return mykml;

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


    //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    //--------------------------------------------------------------------------
    //  First-time Usage Helper
    //--------------------------------------------------------------------------

    var usageHelperHistory = GM_getValue("WMEKMLayers_Usage");

    if (usageHelperHistory) {
        localStorage.WME_KMLUsageHelper = usageHelperHistory;
    } else if (!localStorage.WME_KMLUsageHelper) {
        localStorage.WME_KMLUsageHelper = ':'
    }

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

    ///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\


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

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

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //          NN   NN  OOOOO  TTTTTTT IIIII  CCCCC  EEEEEEE  SSSSS
    //          NNN  NN OO   OO   TTT    III  CC   CC EE      SS
    //          NN N NN OO   OO   TTT    III  CC      EEEEE    SSSSS
    //          NN  NNN OO   OO   TTT    III  CC   CC EE           SS
    //          NN   NN  OOOO0    TTT   IIIII  CCCCC  EEEEEEE  SSSSS
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //-------------------------------------------------------------------------
    //  Update Popup Notice
    //-------------------------------------------------------------------------
    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.getElementById('btnKMLokay').onclick = function() {
            document.getElementById('divKMLnotice').remove();
            localStorage.WME_KMLSettings += '&' + kmlVersion;
        };
    };

    //-------------------------------------------------------------------------
    if (!~localStorage.WME_KMLSettings.indexOf('&')) showKMLPrefsPanel();
    if (!~localStorage.WME_KMLSettings.indexOf('&' + kmlVersion)) { //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);
    }

    setTimeout(function() {KMLayersUsageHelper('stay_open_dropdown_menu', hasSeenUsagePopup('&m'))}, 1000);


};

//==========================================================================
/*
function resetLocalWithKMLayers() {
    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;
    }
};
*/
////////////////////////////////////////////////////////////////////////////
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.I18n &&
                unsafeWindow.Waze.map && unsafeWindow.Waze.model &&
                unsafeWindow.Waze.map.layers && unsafeWindow.Waze.model.repositoryFilters &&
                unsafeWindow.I18n.translations
            ) {
                //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')) { // user has set WMEKMLayers to be disabled
                //kmllog("Autocheck of KeepMyLayers at startup is disabled (1).");
            } else {
                resetLocalWithKMLayers();
            }*/
        }
    }
};