WME Context Menu

WME Context Menu stores various WME elements in an easy-to-access right-click menu. It copies properties of selected segments directly to clipboard and integrates with WME Speedhelper and WME Road Selector to help make it even easier and faster to edit the map.

Verzia zo dňa 19.02.2016. Pozri najnovšiu verziu.

// ==UserScript==
// @name            WME Context Menu
// @namespace       https://greasyfork.org/users/11629-TheLastTaterTot
// @version         0.2.1
// @description     WME Context Menu stores various WME elements in an easy-to-access right-click menu. It copies properties of selected segments directly to clipboard and integrates with WME Speedhelper and WME Road Selector to help make it even easier and faster to edit the map.
// @author          TheLastTaterTot
// @include         https://editor-beta.waze.com/*editor/*
// @include         https://www.waze.com/*editor/*
// @exclude         https://www.waze.com/*user/editor/*
// @grant           GM_setClipboard
// @run-at          document-end
// ==/UserScript==
/* jshint -W097 */

var _W_, _$_,
    roadTypes = {
        1: "Street",
        2: "Primary Street",
        3: "Freeway",
        4: "Ramp",
        5: "Walking Trail",
        6: "Major Highway",
        7: "Minor Highway",
        8: "Dirt road / 4X4 Trail",
        10: "Pedestrian Boardwalk",
        15: "Ferry",
        16: "Stairway",
        17: "Private Road",
        18: "Railroad",
        19: "Runway/Taxiway",
        20: "Parking Lot Road"
    },
    menuResetEvent_RSel = false,
    menuResetEvent_SL = true,
    contextMenuSettings;

if (localStorage.WME_ContextMenu) {
    contextMenuSettings = JSON.parse(localStorage.WME_ContextMenu);
} else {
    contextMenuSettings = {
        clipboard: 0,
        position: 0,
        pin: false
    };
    localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
}


var getUnique = function(objArray) {
    var isNotDuplicate = function(comparisonList, checkThisName) {
        var isNotDup = true;
        try {
             for (var c=0, cLength=comparisonList.length; c<cLength; c++) {
                if (comparisonList[c] === checkThisName) isNotDup = false;
            }
        } catch (err) { console.error(err); }
        return isNotDup;
    };

    try {
        var uniqObjs = [];
        for (var r=objArray.length; r--;) {
            if (isNotDuplicate(uniqObjs, objArray[r])) uniqObjs.push(objArray[r]); // && objArray[r] !== ''
        }
        return uniqObjs;
    } catch (err) { console.error(err); }
};

var addStreetAndCityToRSel = function (segIds, caseSelection) {
    var opAndOr = parseInt(document.getElementById('cmOpAddOr').value),
        opNot = document.getElementById('cmOpNot').classList.contains('active'),
        addConjunction = !!document.getElementById('outRSExpr').innerHTML.length;

    switch (caseSelection^0) {
        case 'primaryStreet':
        case 0:
            if (segIds.primaryStreet.length !== 0) {
                for (var s=segIds.primaryStreet.length; s--;) {
                    if (addConjunction) {
                        if (opAndOr) {
                            document.getElementById('btnRSOr').click();
                        } else {
                            document.getElementById('btnRSAnd').click();
                        }
                    }
                    if (opNot) document.getElementById('btnRSNot').click();
                    //set to primary
                    document.getElementById('selRSAlttStreet').value = 0;
                    document.getElementById('selRSAltCity').value = 0;

                    document.getElementById('btnRSLBkt').click();
                    document.getElementById('inRSStreet').value = _W_.model.streets.objects[segIds.primaryStreet[s]].name;
                    document.getElementById('btnRSAddStreet').click();
                    //document.getElementById('btnRSAnd').click();
                    document.getElementById('inRSCity').value = _W_.model.cities.objects[_W_.model.streets.objects[segIds.primaryStreet[s]].cityID].name;
                    document.getElementById('btnRSAddCity').click();
                    document.getElementById('btnRSRBkt').click();
                }
            }
            break;
        case 'altStreets':
        case 1:
            if (segIds.altStreets.length !== 0) {
                for (var s=segIds.primaryStreet.length; s--;) {
                    if (addConjunction) {
                        if (opAndOr) {
                            document.getElementById('btnRSOr').click();
                        } else {
                            document.getElementById('btnRSAnd').click();
                        }
                    }

                    if (opNot) document.getElementById('btnRSNot').click();
                    //set to alt
                    document.getElementById('selRSAlttStreet').value = 1;
                    document.getElementById('selRSAltCity').value = 1;

                    document.getElementById('btnRSLBkt').click();
                    document.getElementById('inRSStreet').value = _W_.model.streets.objects[segIds.altStreets[s]].name;
                    document.getElementById('btnRSAddStreet').click();
                    //document.getElementById('btnRSAnd').click();
                    document.getElementById('inRSCity').value = _W_.model.cities.objects[_W_.model.streets.objects[segIds.altStreets[s]].cityID].name;
                    document.getElementById('btnRSAddCity').click();
                    document.getElementById('btnRSRBkt').click();
                }
            }
            break;
        case 'anyStreet':
        case 2:
            addStreetAndCityToRSel(segIds, 0); //primary
            addStreetAndCityToRSel(segIds, 1); //alt
            break;
    }
};

var addStreetNameToRSel = function(segNames, inputFieldId, altSelId, altVal, addBtnId) {
    var opAndOr = parseInt(document.getElementById('cmOpAddOr').value),
        opNot = document.getElementById('cmOpNot').classList.contains('active'),
        addConjunction = !!document.getElementById('outRSExpr').innerHTML.length;

    for (n = 0, nLength = segNames.length; n < nLength; n++) {
        if (addConjunction) {
            if (opAndOr) {
                document.getElementById('btnRSOr').click();
            } else {
                document.getElementById('btnRSAnd').click();
            }
        }
        if (opNot) document.getElementById('btnRSNot').click();

        document.getElementById(inputFieldId).value = segNames[n];
        document.getElementById(altSelId).value = altVal^0;
        document.getElementById(addBtnId).click();
        addConjunction = true;
    }
};

var addRoadTypeToRSel = function(ids, inputFieldId, addBtnId) {
    var opAndOr = parseInt(document.getElementById('cmOpAddOr').value),
        opNot = document.getElementById('cmOpNot').classList.contains('active'),
        addConjunction = !!document.getElementById('outRSExpr').innerHTML.length;

    document.getElementById('btnRSLBkt').click();
    for (n = 0, nLength = ids.length; n < nLength; n++) {
        if (addConjunction) {
            if (opAndOr) {
                document.getElementById('btnRSOr').click();
            } else {
                document.getElementById('btnRSAnd').click();
            }
        }
        if (opNot) document.getElementById('btnRSNot').click();

        document.getElementById(inputFieldId).value = ids[n];
        document.getElementById(addBtnId).click();
        addConjunction = true;
    }
    document.getElementById('btnRSRBkt').click();
};

var copyTo = function(e, opt, val) {
    if (document.getElementById('cmPinMenu').value) e.stopPropagation();

    if (document.getElementById('cmClipboard').value) {
        GM_setClipboard(val);
    } else {
        try {
            switch (opt) {
                case 'cm_priSC':
                    if (document.getElementById('cmRoadType').classList.contains('active')) {
                        addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
                        document.getElementById('btnRSAnd').click();
                        document.getElementById('btnRSLBkt').click();
                        addStreetAndCityToRSel(val, 0);
                        document.getElementById('btnRSRBkt').click();
                    } else {
                        addStreetAndCityToRSel(val, 0);
                    }
                     break;
                case 'cm_altSC':
                    if (document.getElementById('cmRoadType').classList.contains('active')) {
                        addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
                        document.getElementById('btnRSAnd').click();
                        document.getElementById('btnRSLBkt').click();
                        addStreetAndCityToRSel(val, 1);
                        document.getElementById('btnRSRBkt').click();
                    } else {
                        addStreetAndCityToRSel(val, 1);
                    }
                    break;
                case 'cm_anySC':
                    if (document.getElementById('cmRoadType').classList.contains('active')) {
                        addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
                        document.getElementById('btnRSAnd').click();
                        document.getElementById('btnRSLBkt').click();
                        addStreetAndCityToRSel(val, 2);
                        document.getElementById('btnRSRBkt').click();
                    } else {
                        addStreetAndCityToRSel(val, 2);
                    }
                    break;
                case 'cm_priS':
                    if (document.getElementById('cmRoadType').classList.contains('active')) {
                        addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
                        document.getElementById('btnRSAnd').click();
                        document.getElementById('btnRSLBkt').click();
                        addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
                        document.getElementById('btnRSRBkt').click();
                    } else {
                        addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
                    }
                    break;
                case 'cm_altS':
                    if (document.getElementById('cmRoadType').classList.contains('active')) {
                        addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
                        document.getElementById('btnRSAnd').click();
                        document.getElementById('btnRSLBkt').click();
                        addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
                        document.getElementById('btnRSRBkt').click();
                    } else {
                        addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
                    }
                    break;
                case 'cm_anyS':
                    if (document.getElementById('cmRoadType').classList.contains('active')) {
                        addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
                        document.getElementById('btnRSAnd').click();
                        document.getElementById('btnRSLBkt').click();
                        addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
                        addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
                        document.getElementById('btnRSRBkt').click();
                    } else {
                        addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
                        addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
                    }
                    break;
                case 'cm_ids':
                    document.getElementById('inRSSegId').value = val;
                    document.getElementById('btnRSAddSegId').classList.add('btn-info');
                    break;
                case 'cm_primaryStreet':
                    document.getElementById('inRSStreet').value = val;
                    document.getElementById('selRSAlttStreet').value = 0;
                    document.getElementById('btnRSAddStreet').classList.add('btn-info');
                    break;
                case 'cm_altStreets':
                    document.getElementById('inRSStreet').value = val;
                    document.getElementById('selRSAlttStreet').value = 1;
                    document.getElementById('btnRSAddStreet').classList.add('btn-info');
                    break;
                case 'cm_altStreetsAND':
                    document.getElementById('inRSStreet').value = '';
                    break;
                case 'cm_altStreetsOR':
                    document.getElementById('inRSStreet').value = '';
                    break;
                case 'cm_primaryCity':
                    document.getElementById('inRSCity').value = val;
                    document.getElementById('selRSAltCity').value = 0;
                    document.getElementById('btnRSAddCity').classList.add('btn-info');
                    break;
                case 'cm_altCities':
                    document.getElementById('inRSCity').value = val;
                    document.getElementById('selRSAltCity').value = 1;
                    document.getElementById('btnRSAddCity').classList.add('btn-info');
                    break;
                case 'cm_state':
                    document.getElementById('inRSState').value = val;
                    document.getElementById('btnRSAddState').classList.add('btn-info');
                    break;
                case 'cm_roadType':
                    document.getElementById('selRSRoadType').value = val;
                    document.getElementById('btnRSAddRoadType').classList.add('btn-info');
                    break;
                case 'cm_updatedBy':
                    document.getElementById('inRSUpdtd').value = val;
                    document.getElementById('btnRSAddUpdtd').classList.add('btn-info');
                    break;
                case 'cm_createdBy':
                    document.getElementById('inRSCrtd').value = val;
                    document.getElementById('btnRSAddCrtd').classList.add('btn-info');
                    break;
                case 'cm_toConnections':
                    break;
            }
        } catch (err) { console.error(err); }

        // swap panel from selection panel
        try {
            document.getElementById('user-info').style.display = 'block';
            document.getElementById('edit-panel').style.display = 'none';
        } catch (err) { console.error(err); }

        // switch active tab-content
        try {
            document.querySelector('.tab-content>.active').classList.remove('active');
            document.getElementById('sidepanel-roadselector').classList.add('active');
        } catch (err) { }

        // switch active nav-tab
        try {
            document.querySelector('#user-tabs li.active').classList.remove('active');
            document.getElementById('tabRSel').classList.add('active');
        } catch (err) { }

        // switch to RSel editor tab
        try {
            document.getElementById('roadselector-tabs').children[1].classList.remove('active');
            document.getElementById('roadselector-tabs').children[0].classList.add('active');
            document.getElementById('roadselector-tab-content').children[1].classList.remove('active');
            document.getElementById('roadselector-tab-content').children[0].classList.add('active');
        } catch (err) { /* */ }
    }
};

var getAutoAddToRSelCase = function (addType) {
    var nameClass = ((document.getElementById('cm_pri').checked * document.getElementById('cm_pri').value) + (document.getElementById('cm_alt').checked * document.getElementById('cm_alt').value)) - 1;

    switch (addType) {
        case 'cm_S':
            switch (nameClass) {
                case 0: //primary
                    return 'cm_priS';
                case 1: //alt
                    return 'cm_altS';
                case 2: //any
                    return 'cm_anyS';
            }
            break;
        case 'cm_SC': // cm_SC street and city
            switch (nameClass) {
                case 0: //primary
                    return 'cm_priSC';
                case 1: //alt
                    return 'cm_altSC';
                case 2: //any
                    return 'cm_anySC';
            }
            break;
    }
};

var getSegmentProperties = function(selectedItems) {
    try {
        /*var roadTypeOpts = document.querySelector('#segment-edit-general select[name="roadType"]'),
            numRoadTypes = roadTypeOpts.options.length, r, roadTypes = {};
        for (r=0; r < numRoadTypes; r++) {
            roadTypes[roadTypeOpts[r].value] = roadTypeOpts[r].text;
        }*/
        var s, s_ids = {}, s_altStObjKeys;
            s_ids = {ids: {},
                     primaryStreet: {},
                     altStreets: {},
                     altCities: {},
                     roadType: {},
                     createdBy: {},
                     updatedBy: {},
                     toConnections: {},
                     primaryCity: {},
                     state: {},
                     country: {}
            };

        for (s = selectedItems.length; s--;) {
            s_ids.ids[selectedItems[s].model.attributes.id] = null;
            s_ids.primaryStreet[selectedItems[s].model.attributes.primaryStreetID] = null;
            s_ids.roadType[selectedItems[s].model.attributes.roadType] = null;
            s_ids.createdBy[selectedItems[s].model.attributes.createdBy] = null;
            s_ids.updatedBy[selectedItems[s].model.attributes.updatedBy] = null;
            s_ids.primaryCity[_W_.model.streets.objects[selectedItems[s].model.attributes.primaryStreetID].cityID] = null;
            s_ids.state[_W_.model.cities.objects[_W_.model.streets.objects[selectedItems[s].model.attributes.primaryStreetID].cityID].stateID] = null;
            s_ids.country[_W_.model.cities.objects[_W_.model.streets.objects[selectedItems[s].model.attributes.primaryStreetID].cityID].countryID] = null;

            s_altSt = selectedItems[s].model.attributes.streetIDs;
            for (var a=0, numAlts=s_altSt.length; a<numAlts; a++) {
                s_ids.altStreets[s_altSt[a]] = null;
                s_ids.altCities[_W_.model.streets.objects[s_altSt[a]].cityID] = null;
            }

            s_toConnObjKeys = Object.keys(selectedItems[s].model.attributes.toConnections);
            for (var k=0, numKeys=s_toConnObjKeys.length; k<numKeys; k++) {
                if (s_toConnObjKeys[k] !== '') {
                    s_ids.toConnections[s_toConnObjKeys[k]] = selectedItems[s].model.attributes.toConnections[s_toConnObjKeys[k]];
                }
            }
        }

        var seg_ids = {}, seg_names = {
                ids: [],
                primaryStreet: [],
                altStreets: [],
                altCities: [],
                roadType: [],
                createdBy: [],
                updatedBy: [],
                toConnections: [],
                primaryCity: [],
                state: [],
                country: []
        };

        for ( var idKey in s_ids ) {
            seg_ids[idKey] = Object.keys(s_ids[idKey]);

            for (var k=0, numKeys=seg_ids[idKey].length; k<numKeys; k++){
                if (seg_ids[idKey][k] !== '') {
                    switch (idKey) {
                        case 'primaryStreet':
                            seg_names[idKey][k] = _W_.model.streets.objects[seg_ids[idKey][k]].name;
                            break;
                        case 'primaryCity':
                            seg_names[idKey][k] = _W_.model.cities.objects[seg_ids[idKey][k]].name;
                            break;
                        case 'altStreets':
                            seg_names[idKey][k] =  _W_.model.streets.objects[seg_ids[idKey][k]].name;
                            break;
                        case 'altCities':
                            seg_names[idKey][k] = _W_.model.cities.objects[seg_ids[idKey][k]].name;
                            break;
                        case 'state':
                            seg_names[idKey][k] = _W_.model.states.objects[seg_ids[idKey][k]].name;
                            break;
                        case 'roadType':
                            seg_names[idKey][k] = roadTypes[String(seg_ids[idKey][k])];
                            break;
                        case 'createdBy':
                            seg_names[idKey][k] = _W_.model.users.objects[seg_ids[idKey][k]].userName;
                            break;
                        case 'updatedBy':
                            seg_names[idKey][k] = _W_.model.users.objects[seg_ids[idKey][k]].userName;
                            break;
                    }
                }
            }
        }

        return { ids: seg_ids, names: seg_names };

    } catch (err) { console.error(err); }
};



var closeContextMenu = function() {
    try {
        document.getElementById('WazeMap').removeEventListener('keydown', menuShortcutKeys, false);
        window.removeEventListener('click', closeContextMenu, false);
        document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
        document.getElementById('copyContextMenu').style.display = 'none';
        menuResetEvent_SL = true;
    } catch (err) {}
};

var addCMEventListeners = function () {
    window.addEventListener('click', closeContextMenu, false);
    document.getElementById('toolbar').addEventListener('mouseenter', closeContextMenu, false);
};

var resetCopyContextMenu = function(contextMenuSettings){
    if (menuResetEvent_RSel) document.getElementById('btnRSClear').click();
    menuResetEvent_RSel = false;

    try {
        document.querySelector('#user-tabs a[href="#sidepanel-roadselector"]').parentNode.id = 'tabRSel';
    } catch (err) {}
// <label for="cm_any" class="btn cm-rsel-options badge cm-badge-right active"><input id="cm_any" type="radio" name="cmOptions" value=2 style="opacity: 0" checked>any</label> //dl - background-color: rgba(177, 210, 220, 0.75);

    document.getElementById('cmContainer').innerHTML = `<div id="cm_rselOnly" class="cm-menu-section" style="display: none; border: 0; background-color: rgba(154, 204, 220, 0.9); border-top-right-radius: 3px; border-top-left-radius: 3px; margin-bottom: -1px;">
        <dl style="padding-top: 1px; border-top-right-radius: 4px; border-top-left-radius: 4px;">
            <dt style="background-color: rgba(111, 167, 185, 0.7); height: 20px; margin-top: -2px; border-top-right-radius: 3px; border-top-left-radius: 3px; padding-top: 4px; padding-bottom: 4px; color: #d8e9ef; font-size: 10px;">RSel Auto-Add Names</dt>
            <dd style="height: 24px; margin: 0px 0px 3px; padding: 5px 10px 5px 9px; background-color: rgba(228, 248, 255, 0.3); box-shadow: 0px 1px 0px rgba(0,0,0,0.1);">
                <div class="btn-group pull-left" data-toggle="buttons">
                    <label for="cm_pri" class="btn cm-rsel-options cm-badge-left active"><input id="cm_pri" type="checkbox" value=1 checked>&nbsp;Primary</label>
                    <label for="cm_alt" class="btn cm-rsel-options cm-badge-right active"><input id="cm_alt" type="checkbox" value=2 checked>Alternate&nbsp;</label>
                </div>
                <div class="pull-left btn-group" style="margin: 0px 2px">
                    <button type="button" id="cmRoadType" class="btn cm-rsel-options active" data-toggle="button">Type</button>
                </div>
                <div class="btn-group pull-right">
                    <button type="button" id="cmOpAddOr" class="btn cm-rsel-options cm-badge-left and" value="0" style="padding-right: 4px;">and</button>
                    <button type="button" id="cmOpNot" class="btn cm-rsel-options cm-badge-right" style="padding-left: 4px;" data-toggle="button">!</button>
                </div>
            </dd>
            <dd id="cm_SC">All <span id="cm_textSC">Primary/Alt. Street, City</span></dd>
            <dd id="cm_S">All <span id="cm_textS">Primary/Alt. Street</span></dd>
        </dl>
    </div>
    <div class="cm-menu-header">
        <dl><dt id="cmMenuHeaderTitle">Copy To Clipboard</dt></dl>
    </div>
    <div id="cmMenuContent">
        <div id="cm_street" class="cm-menu-section">
            <dl id="cm_primaryStreet">
                <dt>Street</dt>
            </dl>
            <dl id="cm_altStreets">
                <dt>Alt street</dt>
            </dl>
        </div>
        <div id="cm_city" class="cm-menu-section">
            <dl id="cm_primaryCity">
                <dt>City</dt>
            </dl>
            <dl id="cm_altCities">
                <dt>Alt city</dt>
            </dl>
        </div>
        <div class="cm-menu-section">
            <dl id="cm_state">
                <dt>State</dt>
            </dl>
        </div>
        <div class="cm-menu-section">
            <dl id="cm_roadType">
                <dt>Road type</dt>
            </dl>
        </div>
        <div class="cm-menu-section">
            <dl id="cm_updatedBy">
                <dt>Updated by</dt>
            </dl>
            <dl id="cm_createdBy">
                <dt>Created by</dt>
            </dl>
        </div>
        <div class="cm-menu-section">
            <dl>
                <dd id="cm_ids">Segment IDs</dd>
            </dl>
    </div></div>`;

    if (!document.getElementById('cmPinMenu').value) {
        setTimeout(addCMEventListeners, 250);
    }

    if (contextMenuSettings.position === 1) {
        document.getElementById('cmFooterCaret').classList.add('fa-caret-down');
        document.getElementById('cmFooterCaret').classList.remove('fa-caret-up');
        document.getElementById('cmFooter').style.marginBottom = '-2px';
        document.getElementById('copyContextMenu').insertBefore(document.getElementById('cmFooter'), document.getElementById('copyContextMenu').children[0]);
    } else {
        document.getElementById('cmFooterCaret').classList.add('fa-caret-up');
        document.getElementById('cmFooterCaret').classList.remove('fa-caret-down');
        document.getElementById('cmFooter').style.marginBottom = '0';
        document.getElementById('copyContextMenu').appendChild(document.getElementById('cmFooter'));
    }
};


var populateCopyContextMenu = function(segInfo, contextMenuSettings) {
    try {
        resetCopyContextMenu(contextMenuSettings);
        var updateNames = Object.keys(segInfo.ids),
            numNames = updateNames.length,
            n, selOption, emptyArr, s_names = {}, s_ids = {};

        for (n = numNames; n--;) {
            if (document.getElementById('cm_'+updateNames[n]) && segInfo.ids[updateNames[n]] && segInfo.ids[updateNames[n]].length) {
                if (updateNames[n] !== 'ids') {
                    emptyArr = 0;
                    s_names[updateNames[n]] = getUnique(segInfo.names[updateNames[n]])
                    s_ids[updateNames[n]] = getUnique(segInfo.ids[updateNames[n]])

                    for (var a=0, aLength = s_ids[updateNames[n]].length; a < aLength; a++) {
                        if (s_names[updateNames[n]][a]) {
                            selOption = document.createElement('dd');
                            if (s_names[updateNames[n]][a] === '') {
                                if (~updateNames[n].indexOf('Cit')) {
                                    selOption.innerHTML = 'No City';
                                } else if (~updateNames[n].indexOf('Street')) {
                                    selOption.innerHTML = 'No Street';
                                }
                            } else {
                                selOption.innerHTML = s_names[updateNames[n]][a];
                            }
                            selOption.name = s_ids[updateNames[n]][a];
                            document.getElementById('cm_'+updateNames[n]).appendChild(selOption);

                            switch (updateNames[n]) {
                                case 'roadType':
                                    selOption.onclick = function(e){
                                        //if (document.getElementById('cmPinMenu').value) e.stopPropagation();
                                        copyTo(e, this.parentNode.id, this.name);
                                    };
                                    break;
                                default:
                                    selOption.onclick = function(e){
                                        //if (document.getElementById('cmPinMenu').value) e.stopPropagation();
                                        copyTo(e, this.parentNode.id, this.innerHTML);
                                    };
                            }
                        } else {
                            emptyArr++;
                        }
                    }
                    if (emptyArr === aLength) {
                        if (document.getElementById('cm_'+updateNames[n])) {
                            document.getElementById('cm_'+updateNames[n]).style.display = "none";
                        }
                    }
                } else {
                    selOption = document.getElementById('cm_ids');
                    selOption.name = segInfo.ids[updateNames[n]].join(',');
                    selOption.onclick = function(e){
                        //if (document.getElementById('cmPinMenu').value) e.stopPropagation();
                        copyTo(e, this.id, this.name);
                    };
                }
            } else if (document.getElementById('cm_'+updateNames[n])) {
                document.getElementById('cm_'+updateNames[n]).style.display = "none";
            }
        }

        if (!s_names.primaryStreet.length && !s_names.altStreets.length) {
            document.getElementById('cm_primaryStreet').parentNode.style.display = 'none';
        }

        if (!s_names.primaryCity.length && !s_names.altCities.length) {
            document.getElementById('cm_primaryCity').parentNode.style.display = 'none';
        }

        if (!s_names.state.length) document.getElementById('cm_state').parentNode.style.display = 'none';


        // RSEL menu items
        if (document.getElementById('cmRSel').value) {
            document.getElementById('cmMenuHeaderTitle').innerHTML = 'Copy To Road Selector';

            var copyToRSelAndSelect = document.createElement('dd');
            copyToRSelAndSelect.id = 'cm_SCgo';
            copyToRSelAndSelect.zIndex = 1;
            copyToRSelAndSelect.className = 'fa fa-fast-forward pull-right cm-rsel-goselect';
            document.getElementById('cm_SC').parentNode.insertBefore(copyToRSelAndSelect, document.getElementById('cm_SC'));

            var copyToRSelAndSelect2 = copyToRSelAndSelect.cloneNode();
            copyToRSelAndSelect2.id = 'cm_Sgo';
            copyToRSelAndSelect.zIndex = 1;
            document.getElementById('cm_S').parentNode.insertBefore(copyToRSelAndSelect2, document.getElementById('cm_S'));

            document.getElementById('cm_rselOnly').style.display = 'block';
            //name options
            document.getElementById('cm_pri').parentNode.addEventListener('click', function(e){
                e.stopPropagation();
                var numBtnDown = this.parentNode.getElementsByClassName('active').length;
                if (this.children[0].checked) { //currently checked... decide whether to uncheck
                    this.classList.remove('active');
                    this.children[0].checked = false;
                    if (numBtnDown===0) {
                        document.getElementById('cm_alt').parentNode.classList.add('active')
                        document.getElementById('cm_alt').checked = true;
                    }
                    document.getElementById('cm_textSC').innerHTML = 'Alt. Street, City';
                    document.getElementById('cm_textS').innerHTML = 'Alt. Street';
                } else { //unchecked
                    this.classList.add('active');
                    this.children[0].checked = true;
                    document.getElementById('cm_textSC').innerHTML = 'Primary/Alt. Street, City';
                    document.getElementById('cm_textS').innerHTML = 'Primary/Alt. Street';
                }
            }, false);
            document.getElementById('cm_alt').parentNode.addEventListener('click', function(e){
                e.stopPropagation();
                var numBtnDown = this.parentNode.getElementsByClassName('active').length;
                if (this.children[0].checked) { //currently checked... decide whether to uncheck
                    this.classList.remove('active');
                    this.children[0].checked = false;
                    if (numBtnDown===0) {
                        document.getElementById('cm_pri').parentNode.classList.add('active');
                        document.getElementById('cm_pri').checked = true;
                    }
                    document.getElementById('cm_textSC').innerHTML = 'Primary Street, City';
                    document.getElementById('cm_textS').innerHTML = 'Primary Street';
                } else { //unchecked
                    this.classList.add('active');
                    this.children[0].checked = true;
                    document.getElementById('cm_textSC').innerHTML = 'Primary/Alt. Street, City';
                    document.getElementById('cm_textS').innerHTML = 'Primary/Alt. Street';
                }
            }, false);

            //operations
            document.getElementById('cmOpAddOr').addEventListener('click', function(e) {
                e.stopPropagation();
                var opToggleLabel = ['and', 'or'], newValue = this.value^1;
                this.innerHTML = opToggleLabel[newValue];
                this.value = newValue;
                //console.info(this.value);
            }, false);

            //menu selections
            document.getElementById('cm_SC').addEventListener('click', function(e){
                copyTo(e, getAutoAddToRSelCase('cm_SC'), segInfo.ids);
            }, false);
            document.getElementById('cm_S').addEventListener('click', function(e){
                copyTo(e, getAutoAddToRSelCase('cm_S'), segInfo.names);
            }, false);
            /*document.getElementById('cm_EM').addEventListener('click', function(e){
                copyTo(e, 'cm_EM', segInfo.ids);
            }, false);*/

            document.getElementById('cm_SCgo').addEventListener('click', function (e) {
                menuResetEvent_RSel = true;
                copyTo(e, getAutoAddToRSelCase('cm_SC'), segInfo.ids);
                document.getElementById('btnRSSelect').click();
            }, false);
            document.getElementById('cm_Sgo').addEventListener('click', function (e) {
                menuResetEvent_RSel = true;
                copyTo(e, getAutoAddToRSelCase('cm_S'), segInfo.names);
                document.getElementById('btnRSSelect').click();
            }, false);

        }
    } catch (err) { console.error(err); };
};

var populateSpeedMenu = function (contextMenuSettings) {
    if (menuResetEvent_SL) {
        resetCopyContextMenu(contextMenuSettings);

        try {
            document.getElementById('cmMenuHeaderTitle').innerHTML = 'Edit Speed Limits';
            document.getElementById('cmMenuContent').innerHTML = '';
            var speedLimit = document.querySelector('#segment-edit-general div.speed-limit').cloneNode(true);
            speedLimit.id = 'cmSpeedLimit';
            speedLimit.className = 'cm-speed-limit cm-menu-section';
            speedLimit.innerHTML = '<div id="signsContainer"></div><div class="form-inline">' + speedLimit.innerHTML + '</div>';
            document.getElementById('cmMenuContent').appendChild(speedLimit);
         } catch (err) {}
    }

    try {
        if (menuResetEvent_SL) {
            var cmVerifyChkBoxLabel = document.querySelectorAll('div#cmSpeedLimit input[type="checkbox"]+label'),
                wazeChkboxId;
            for (var cb = 0; cb < cmVerifyChkBoxLabel.length; cb++) {
                cmVerifyChkbox = cmVerifyChkBoxLabel[cb].parentNode.children[0];
                wazeChkboxId = cmVerifyChkbox.id;
                cmVerifyChkbox.id = wazeChkboxId + '_cm';
                cmVerifyChkBoxLabel[cb].addEventListener('click', function(e) {
                    e.stopPropagation();
                    this.parentNode.children[0].checked = !document.getElementById(this.parentNode.children[0].id.slice(0,-3)).checked;
                }, false);
            }
        }
        _$_('#fwdMaxSpeedUnverifiedCheckbox_cm').prop('checked',_$_('#fwdMaxSpeedUnverifiedCheckbox').prop('checked'));
        _$_('#revMaxSpeedUnverifiedCheckbox_cm').prop('checked',_$_('#revMaxSpeedUnverifiedCheckbox').prop('checked'));
    } catch (err) {}

    try {
        var cmSpeedInput = document.querySelectorAll('div#cmSpeedLimit input[type="number"]'),
            cmSpeedInputLength = cmSpeedInput.length;

        if (menuResetEvent_SL) {
            var wazeSpeedInputName;
            for (var nm = 0; nm < cmSpeedInputLength; nm++) {
                wazeSpeedInputName = cmSpeedInput[nm].name;
                cmSpeedInput[nm].name = wazeSpeedInputName + '_cm';

                cmSpeedInput[nm].addEventListener('click', function(e) {
                    e.stopPropagation();
                    this.select();
                    document.getElementById('WazeMap').removeEventListener('keydown', menuShortcutKeys, false);
                    }, false);

                cmSpeedInput[nm].addEventListener('blur', function(e) {
                    document.getElementById('WazeMap').addEventListener('keydown', menuShortcutKeys, false);
                    _$_('input[name="' + this.name.slice(0,-3) + '"]').val(this.value).change();
                }, false);

                cmSpeedInput[nm].addEventListener('change', function(e) {
                    //e.stopPropagation();
                    _$_('input[name="' + this.name.slice(0,-3) + '"]').val(this.value).change();
                }, false);
            }
        } else {
            var wazeSpeedInput = document.querySelectorAll('#segment-edit-general div.speed-limit input[type="number"]'),
                wazeSpeedInputLength = wazeSpeedInput.length;
            if (wazeSpeedInputLength > cmSpeedInputLength) {
                menuResetEvent_SL = true;
                populateSpeedMenu(contextMenuSettings);
                return false;
            }
        }

        _$_('input[name="fwdMaxSpeed_cm"]').val(_$_('input[name="fwdMaxSpeed"]').val());
        _$_('input[name="revMaxSpeed_cm"]').val(_$_('input[name="revMaxSpeed"]').val());
    } catch (err) {}

    try {
        if (menuResetEvent_SL && !document.getElementById('cmPinMenu').value) {
            document.getElementById('cmSpeedLimit').addEventListener('mouseleave', function(){
                    addCMEventListeners();
                    _$_('input[name="fwdMaxSpeed_cm"]').val(_$_('input[name="fwdMaxSpeed"]').val());
                    _$_('input[name="revMaxSpeed_cm"]').val(_$_('input[name="revMaxSpeed"]').val());
                }, false);
            document.getElementById('cmSpeedLimit').addEventListener('mouseenter', function(){
                window.removeEventListener('click', closeContextMenu, false);
                document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
            }, false);
        }
    } catch (err) {}


    var waitCount = 0, maxWait = 15;

    var addListenersToSigns = function() {
        var cmSpeedSigns = document.getElementById('signsholder_cm').children;
        for (var ss = cmSpeedSigns.length; ss--;) {
            cmSpeedSigns[ss].addEventListener('click', function(e) {
                var speedVal = this.firstElementChild.innerHTML;
                    //cmSpeedInput = document.querySelectorAll('div#cmSpeedLimit input[type="number"]'),
                    //wazeSpeedInput = document.querySelectorAll('#segment-edit-general div.speed-limit input[type="number"]'),
                    //cmVerifySpeedChkBox = document.querySelectorAll('div#cmSpeedLimit input[type="checkbox"]'),
                    //wazeVerifySpeedChkBox = document.querySelectorAll('#segment-edit-general div.speed-limit input[type="checkbox"]');
                try {
                    _$_('#segment-edit-general div.speed-limit input[type="number"]').val(speedVal).change();
                } catch (err) {}
                try {
                    _$_('div#cmSpeedLimit input[type="number"]').val(speedVal).change();
                } catch (err) {}
                try {
                    _$_('#fwdMaxSpeedUnverifiedCheckbox_cm').prop('checked',true);
                    _$_('#fwdMaxSpeedUnverifiedCheckbox').prop('checked',true);
                } catch (err) {}
                try {
                    _$_('#revMaxSpeedUnverifiedCheckbox_cm').prop('checked',true);
                    _$_('#revMaxSpeedUnverifiedCheckbox').prop('checked',true);
                } catch (err) {}
                try {
                    _$_('#segment-edit-general div.speed-limit input[type="number"]').val(speedVal).change();
                } catch (err) {}
                if (!document.getElementById('cmPinMenu').value) {
                    setTimeout(closeContextMenu,100);
                }
            }, false);
        }
    };

    var waitForSpeedhelper = function() {

        var addLaggedSigns = function() {
            var signsHolder = document.querySelector('#segment-edit-general div.speed-limit #signsholder');
            if (menuResetEvent_SL && signsHolder !== null) {
                menuResetEvent_SL = false;
                document.getElementById('signsContainer').innerHTML = signsHolder.outerHTML;
                document.querySelector('#cmSpeedLimit #signsholder').id = 'signsholder_cm';
                document.getElementById('signsholder_cm').style.marginBottom = '15px';
                document.getElementById('signsholder_cm').style.opacity = 0.9;
                addListenersToSigns();
            } else {
                waitForSpeedhelper();
            }
        };
        //------------------------------------------------------
        if (document.getElementById('signsholder_cm') !== null) {
            addListenersToSigns();
        } else if (waitCount++ < maxWait) {
            setTimeout(addLaggedSigns, 50);
        }
        //------------------------------------------------------
    };


    if(menuResetEvent_SL) {
        try {
            document.querySelector('#cmSpeedLimit #signsholder').id = 'signsholder_cm';
            document.getElementById('signsholder_cm').style.marginBottom = '15px';
            document.getElementById('signsholder_cm').style.opacity = 0.9;
        } catch (err) {}

        setTimeout(waitForSpeedhelper,0);
    }

    if (menuResetEvent_SL) menuResetEvent_SL = false;
};

var selectionIsSegment = function() {
    try {
        var sel = _W_.selectionManager.selectedItems;
        if (sel.length) {
            return (sel[sel.length-1].model.type === 'segment') ? sel : false;
        } else { return false; }
    } catch (err) { console.error(err); };
};

//var pressedKeys = [];
var menuShortcutKeys = function(e) {
    switch (e.which) {
        case 49: //81: //q
            e.preventDefault();
            e.stopPropagation();
            document.getElementById('cmClipboard').click();
            break;
        case 50: //87: //w
            e.preventDefault();
            e.stopPropagation();
            document.getElementById('cmRSel').click();
            break;
        case 51: //69: //e
            e.preventDefault();
            e.stopPropagation();
            document.getElementById('cmSpeed').click();
            break;
        default:
            return false;
    }
};

var setupSegmentContextMenu = function() {
 try {
        var selectedItems = selectionIsSegment();
        if (selectedItems) {
            switch (contextMenuSettings.clipboard) {
                case 2:
                    populateSpeedMenu(contextMenuSettings);
                    break;
                case 1:
                case 0:
                    var segInfo = getSegmentProperties(selectedItems);
                    populateCopyContextMenu(segInfo, contextMenuSettings);
                    break;
            }
        }
    } catch (err) {}
};

var initCopyContextMenu = function(){
    var copyMenu = document.createElement('div'),
        copyMenuCSS = document.createElement('style');

    try {
        copyMenuCSS.type = 'text/css';
        copyMenuCSS.innerHTML = `
            div.cm-menu-header { padding: 0px; border: 0; height: 20px; }
            .cm-menu-header dl { background-color: rgba(147, 196, 211, 0.90); padding: 0; border-top-right-radius: 4px; border-top-left-radius: 4px; }
            .cm-menu-header dt { padding: 4px 12px; text-transform: uppercase; line-height: 1.2; background-color: rgba(113, 168, 185, 0.7); color: #D8E9EF; font-size: 10px; border-top-right-radius: 3px; border-top-left-radius: 3px; height: 22px; margin-top: 1px; box-shadow: 0px -1px 0px rgba(154, 204, 220, 0.9); }
            div.cm-menu-section { border-bottom: 1px solid #416B7C; padding: 2px 0px 3px; background-color: rgba(147, 196, 211, 0.95); }
            .cm-menu-section dl { margin: 0; padding: 0; display: block; }
            .cm-menu-section dt { font-size: 9px; padding: 0px 12px; margin-top: 3px; text-transform: uppercase; line-height: 1.2; }
            .cm-menu-section dd { padding: 0px 12px; font-size: 11px; color: #234350; font-weight: 600; line-height: 1.3;}
            .cm-menu-section dd:hover, .cm-menu-section dd:active, .cm-menu-section dd:focus { background-color: #BEDCE5; color: #416B7C; }
            .cm-menu-section dd:active { color: #64D8EA; }
            .cm-footer-icns { font-size: 13px; margin: 0px 4px 0px 2px; cursor: pointer; display: inline-table; line-height: 1; }
            .cm-footer-icns:active, .cm-footer-icns:focus, .cm-footer-icns.toggle-off:active, .cm-footer-icns.toggle-off:focus { color: #64D8EA; }
            .cm-footer-icns.toggle-off, .cm-footer-text.toggle-off { color: #8CBBCC; }
            dd.cm-rsel-goselect { padding-right: 14px 3px; cursor: pointer; }
            .cm-menu-section .cm-rsel-goselect:hover { background-color: transparent; color: #d4e7ed; }
            .cm-rsel-options, cm-rsel-options:focus:hover, cm-rsel-options+input:not(checked) { background-color: rgba(89, 137, 158, 0.60); color: #D4E7ED; font-weight: bold !important; height: 14px !important; line-height: 1; padding: 3px 6px; font-size: 8px !important; border-radius: 15px; }
            .cm-rsel-options:hover { background-color: rgba(89, 137, 158, 0.7); color: white; }
            .cm-rsel-options.active:hover { background-color: #274B5A }
            .cm-rsel-options.active, .cm-rsel-options:active, .cm-rsel-options:active:focus { color: white; background-color: #3F6271; }
            .cm-rsel-options.and { background-color: #EEE; color: #59899E; border-right: 1px solid #AAA;}
            .cm-rsel-options.cm-badge-right { border-left: 1px solid #59899E; }
            div#cmSpeedLimit { width: 100%; font-size: 10px; text-align: center; display: inline-block; padding: 10px; }
            div#cmSpeedLimit input[type="number"] { height: 25px; width: 50px; font-size: 11px; padding: 4px 5px; line-height: 1; margin: 0px 2px; }
            div#cmSpeedLimit input[type="checkbox"]+label { padding-left: 22px; line-height: 1.8; }
            div#cmSpeedLimit .controls-container { margin-left: 5px; }
            div#cmSpeedLimit div { display: inline-block; }`;

        document.body.appendChild(copyMenuCSS);

        copyMenu.id = 'copyContextMenu';
        copyMenu.style.position = 'fixed';
        copyMenu.style.display = 'none';
        copyMenu.style.top = '0px';
        copyMenu.style.left = '0px';
        copyMenu.style.width = '210px';
        //copyMenu.style.minHeight = '100px';
        copyMenu.style.margin = '0';
        copyMenu.style.padding = '0px';
        copyMenu.style.borderRadius = '4px';
        copyMenu.style.boxShadow = '0px 1px 12px rgba(0,0,0,0.7)';
        copyMenu.style.border = '1px solid rgb(89, 137, 150)';
        copyMenu.style.borderBottom = '1px solid #2D505F';
        copyMenu.style.color = 'white';
        copyMenu.style.zIndex = '9999';
        copyMenu.innerHTML = '<div id="cmContainer" style="border-radius: 2px; color: white; padding:0; margin:0; position: relative; width: 100%; display: block;"></div>' +
            '<div id="cmHolder" style="display: none"></div>' +
            '<div id="cmFooter" style="color: #DDEDF3; z-index: 1; height: 21px; background-color: rgba(88, 136, 158, 0.90); ' +
            'padding: 1px 7px 1px; margin: 0; position: relative; width: 100%; display: block;"></div>';

        document.getElementById('WazeMap').appendChild(copyMenu);

        document.getElementById('cmFooter').innerHTML = `
            <div style="position: relative; float: left; vertical-align: middle;">
            <i id="cmPinMenu" class="fa fa-thumb-tack cm-footer-icns toggle-off" style="margin: 0px -3px 0px -3px; padding: 3px 6px;" value=true title="Pin menu" data-toggle="tooltips"></i>
            <span id="cmPinClose" class="cm-footer-text toggle-off" style="cursor: pointer; font-weight: 600; border-left: 1px solid #D4E7ED; padding-left: 8px; text-transform: uppercase; font-size: 10px; letter-spacing: .7px;">Close</span>
            </div>
            <div id="cmFooterCaret" class="fa fa-caret-up cm-footer-icns pull-right" style="position: relative; top: 3px; margin: auto 0px auto 7px;"></div>
            <div style="position: relative; height: 21px; border-radius: 20px; border: 1px solid #6EA1B7;  padding: 0px 1px 0px 5px;" class="btn-group pull-right">
              <div style="position: relative; display: inline-block; border-right: 1px solid #6EA1B7; padding-left: 2px; width: 22px;" class="">
                <i id="cmClipboard" value="false" style="font-size: 13px;" class="fa fa-clipboard cm-footer-icns toggle-off" title="Copy to Clipboard" data-toggle="tooltips"></i>
              </div>
              <div style="position: relative; display: inline-block; border-right: 1px solid #6EA1B7;" class="">
                <i id="cmRSel" style="font-size: 14px;" value="false" class="fa fa-road cm-footer-icns toggle-off" title="Copy to WME Road Selector" data-toggle="tooltips"></i>
              </div>
              <div style="position: relative; display: inline-block; width: 20px;  margin: 0px 0px 0px -2px; opacity: 0.84;" class="">
                <span id="cmSpeed" style="height: 16px" value="false" title="Edit Speed Limits" class="fa fa-stack">
                  <i class="fa fa-circle cm-footer-icns" style="font-size: 15px; width: 15px; color: #DDEDF3; line-height: 14px; position: absolute; left: 0; text-align: center;"></i>
                  <i class="fa fa-circle-o cm-footer-icns" style="font-size: 15px; width: 15px; font-weight: 500; color: crimson; line-height: 14px; position: absolute; left: 0; text-align: center;"></i>
                  <i class="fa cm-footer-icns" style="font-size: 8px; font-style: normal; width: 15px; color: black; line-height: 14px; position: absolute; left: 0; text-align: center;">S</i>
                </span>
              </div>
            </div>`;

/*<div style="display: inline-table; border-radius: 20px; border: 1px solid #6EA1B7; position: relative; float: right; padding: 0px 1px 0px 5px;">
            <span><i id="cmClipboard" value=false style="font-size: 12px; padding: 0px 3px; border-right: 1px solid #6EA1B7;" class="fa fa-clipboard fa-fw cm-footer-icns" title="Copy to Clipboard" data-toggle="tooltips"></i></span>
            <span><i id="cmRSel" value=false class="fa fa-road cm-footer-icns fa-fw toggle-off" title="Copy to WME Road Selector" data-toggle="tooltips"></i></span>
            </div>*/


        resetCopyContextMenu(contextMenuSettings);

        setTimeout( function() {
            if (contextMenuSettings.clipboard === 0 || document.getElementById('tabRSel') === null) {
                document.getElementById('cmClipboard').value = true;
                document.getElementById('cmClipboard').classList.remove('toggle-off');
                document.getElementById('cmRSel').value = false;
                document.getElementById('cmRSel').classList.add('toggle-off');
                document.getElementById('cmSpeed').value = false;
                document.getElementById('cmSpeed').parentNode.style.opacity = 0.4;
            }
        }, 2000);

        if (contextMenuSettings.clipboard === 1) {
            document.getElementById('cmClipboard').value = false;
            document.getElementById('cmClipboard').classList.add('toggle-off');
            document.getElementById('cmRSel').value = true;
            document.getElementById('cmRSel').classList.remove('toggle-off');
            document.getElementById('cmSpeed').value = false;
            document.getElementById('cmSpeed').parentNode.style.opacity = 0.4;
        } else if (contextMenuSettings.clipboard === 2) {
            document.getElementById('cmClipboard').value = false;
            document.getElementById('cmClipboard').classList.add('toggle-off');
            document.getElementById('cmRSel').value = false;
            document.getElementById('cmRSel').classList.add('toggle-off');
            document.getElementById('cmSpeed').value = true;
            document.getElementById('cmSpeed').parentNode.style.opacity = 0.84;
        }

        if (contextMenuSettings.pin) {
            document.getElementById('cmPinMenu').value = true;
            document.getElementById('cmPinMenu').classList.remove('toggle-off');
            document.getElementById('cmPinClose').classList.remove('toggle-off');
        } else {
            document.getElementById('cmPinMenu').value = false;
            document.getElementById('cmPinMenu').classList.add('toggle-off');
            document.getElementById('cmPinClose').classList.add('toggle-off');
        }


        document.getElementById('cmClipboard').onclick = function(e){
            try {
                e.stopPropagation();
                document.getElementById('cmRSel').value = false;
                document.getElementById('cmRSel').classList.add('toggle-off');
                document.getElementById('cmSpeed').value = false;
                document.getElementById('cmSpeed').parentNode.style.opacity = 0.4;
                this.value = true;
                this.classList.remove('toggle-off');
                contextMenuSettings.clipboard = 0;
                localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);

                var selectedItems = selectionIsSegment();
                if (selectedItems) {
                    var segInfo = getSegmentProperties(selectedItems);
                    populateCopyContextMenu(segInfo, contextMenuSettings);
                }
            } catch (err) { console.error(err); };
        };


        document.getElementById('cmRSel').onclick = function(e){
            try {
                e.stopPropagation();
                if (document.getElementById('tabRSel') !== null) {
                    document.getElementById('cmClipboard').value = false;
                    document.getElementById('cmClipboard').classList.add('toggle-off');
                    document.getElementById('cmSpeed').value = false;
                    document.getElementById('cmSpeed').parentNode.style.opacity = 0.4;
                    this.value = true;
                    this.classList.remove('toggle-off');
                    contextMenuSettings.clipboard = 1;
                    localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);

                    var selectedItems = selectionIsSegment();
                    if (selectedItems) {
                        var segInfo = getSegmentProperties(selectedItems);
                        populateCopyContextMenu(segInfo, contextMenuSettings);
                    }
                }
            } catch (err) { console.error(err); }
        };

        document.getElementById('cmSpeed').onclick = function(e){
            try {
                e.stopPropagation();
                document.getElementById('cmClipboard').value = false;
                document.getElementById('cmClipboard').classList.add('toggle-off');
                document.getElementById('cmRSel').value = false;
                document.getElementById('cmRSel').classList.add('toggle-off');
                this.value = true;
                this.parentNode.style.opacity = 0.84;
                contextMenuSettings.clipboard = 2;
                localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);

                var selectedItems = selectionIsSegment();
                if (selectedItems) {
                    menuResetEvent_SL = true;
                    populateSpeedMenu(contextMenuSettings);
                    window.removeEventListener('click', closeContextMenu, false);
                    document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
                }
            } catch (err) { console.error(err); }
        };

        document.getElementById('WazeMap').addEventListener('contextmenu', function(e){
            try {
                var selectedItems = selectionIsSegment();
                if (selectedItems) {
                    e.preventDefault();
                    menuResetEvent_SL = true;
                    setupSegmentContextMenu();

                    var copyMenu = document.getElementById('copyContextMenu'),
                        wazeMapWidth = _$_('#WazeMap').width(),
                        wazeMapHeight = _$_('#WazeMap').height();

                    copyMenu.style.display = 'block';
                    copyMenu.style.top = e.pageY - 10 + 'px';
                    copyMenu.style.left = e.pageX + 'px';

                    document.getElementById('WazeMap').addEventListener('keydown', menuShortcutKeys, false);
                } else {
                    return false;
                }
            } catch (err) { console.error(err); }
        }, false);

        _W_.selectionManager.events.register("selectionchanged", null, setupSegmentContextMenu);

        document.getElementById('cmPinMenu').onclick = function(e){
            try {
                e.stopPropagation();
                if (this.value) {
                    this.value = false;
                    this.classList.add('toggle-off');
                    document.getElementById('cmPinClose').classList.add('toggle-off');
                    closeContextMenu();
                } else {
                    this.value = true;
                    this.classList.remove('toggle-off');
                    document.getElementById('cmPinClose').classList.remove('toggle-off');
                    window.removeEventListener('click', closeContextMenu, false);
                    document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
                }
                contextMenuSettings.pin = !contextMenuSettings.pin;
                localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
            } catch (err) { console.error(err); }
        };

        document.getElementById('cmPinClose').onclick = closeContextMenu;

        document.getElementById('cmFooterCaret').addEventListener('click', function(e) {
            e.stopPropagation();
            try {
                if (this.classList.contains('fa-caret-up')) {
                    contextMenuSettings.position = 1;
                    localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
                    this.classList.add('fa-caret-down');
                    this.classList.remove('fa-caret-up');
                    document.getElementById('cmFooter').style.marginBottom = '-2px';
                    document.getElementById('copyContextMenu').insertBefore(document.getElementById('cmFooter'), document.getElementById('copyContextMenu').children[0]);
                } else if (this.classList.contains('fa-caret-down')) {
                    contextMenuSettings.position = 0;
                    localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
                    this.classList.add('fa-caret-up');
                    this.classList.remove('fa-caret-down');
                    document.getElementById('cmFooter').style.marginBottom = '0';
                    document.getElementById('copyContextMenu').appendChild(document.getElementById('cmFooter'));
                }
            } catch (err) { console.error(err); }
        }, false);

    } catch (err) { console.error(err); }


    setTimeout(function(){
        try {
            rselBtnEls = document.querySelectorAll('#RSconditions button');
            for (var b = rselBtnEls.length; b--;) {
                rselBtnEls[b].addEventListener('click', function(){this.classList.remove('btn-info')}, false);
            }
        } catch (err) {console.error(err)}},1200)
};

var waitCount = 0, maxWaitCount = 50;
var waitForWaze = function() {
    try {
        if (typeof(unsafeWindow) !== "undefined" && unsafeWindow.Waze && unsafeWindow.Waze.model &&
            unsafeWindow.Waze.selectionManager && unsafeWindow.Waze.selectionManager.selectedItems &&
            unsafeWindow.Waze.model.segments && unsafeWindow.Waze.model.cities) {

            _W_ = unsafeWindow.Waze;
            _$_ = unsafeWindow.$;
            //console.info('starting...');
            setTimeout(initCopyContextMenu,2000);
            console.info('WMECM:','Something may have went wrong... not sure.');
        } else if (waitCount++ < maxWaitCount) {
            //console.info('waiting...');
            setTimeout(waitForWaze,1000);
        } else {
            console.error('WMECM:','Failed to start');
        }
    } catch (err) {
        console.error('WMECM:',err);
    }
};

waitForWaze();