UROverview Plus (URO+)

Adds filtering and pop-up infobox for UR, MP and camera markers

当前为 2014-06-08 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name                UROverview Plus (URO+)
// @namespace           http://greasemonkey.chizzum.com
// @description         Adds filtering and pop-up infobox for UR, MP and camera markers
// @include             https://*.waze.com/*editor*
// @include             https://editor-beta.waze.com/*
// @grant               none
// @version             3.9
// ==/UserScript==

function uroGlobals()
{
   uroVersion = "3.9";
   uroCtrlsHidden = false;
   uroCurrentTab = 1;
   uroFID = -1;
   uroShownFID = -1;
   uroInhibitSave = true;
   uroPopupTimer = -2;
   uroPopupShown = false;
   uroSetupListeners = true;
   uroRootContainer = null;
   uroURvroot = null;
   uroMPvroot = null;
   uroMaskLayer = null;
   uroCamLayer = null;
   uroCrushedConeFID = null;

   uroCamvroot = null;
   uroURLayerIdx = null;
   uroProblemLayerIdx = null;
   uroMouseInPopup = false;
   uroURControlsIdx = null;
   uroProblemControlsIdx = null;
   uroMaskActive = false;

   uroNullCamLayer = false;
   uroNullOpenLayers = false;
   uroNullRootContainer = false;
   uroNullURLayer = false;
   uroNullProblemLayer = false;
   uroNullMapViewport = false;
   
   uroUserID = -1;
   uroURSCurrentCount = 0;
   uroURSPrevCount = 0;
   
   uroBetaEditor = false;
   uroWazeBitsPresent = 0;
   
   uroCamWatchObjects = new Array();
   uroCWLGroups = new Array();
   
   dteControlsIdx = -1;
   dteOldestFullDrive = new Date(0);
   dteEpoch = new Date(0);
   
   uroUserTabId = '';

   // uroIcons
   // 0 = group collapse/group expand
   // 1 = addtogroup active/addtogroup idle
   // 2 = goto active/goto idle
   // 3 = normal/squashed cone UR
   uroIcons = 
   [
      ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRIqo78SIAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAADtJREFUKM9j/P//PwNJgCQN////ZyFeGyMjIwMDAxMDiWAQamDB9Bb+kKTMBmICdxgFK64AxZKiSE3eAAOXFRnJRfN6AAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRDHbt/O0AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAE5JREFUKM+9UkEKACAMcmP//7IdgghqMQvytoOKTiMJCRKBZNRpZgbAIcIzsa5XJcgOB8Qaaz3nSt4chlLX3nb9OXRlL7cO2V83I1Dn3QDKfhshMqWScAAAAABJRU5ErkJggg=="],
      ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYVKhKBubQAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAEZJREFUOMtjYBjygBHB/P8fjzJGIszCZQA+gxkYWIjTABPDdAkL8U7G7hIcYcDISEGYwDQSFyZM5AQckYA4F7CQZ8goQAYAMCsd/TxbqrwAAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tDee2t8AAAABPSURBVDjL7ZAxCgAgDAMT6cP6dH+mUwfBaugmeFMpbTgCPA9j6H2M7MidvCZlAadgADDlIXY7E1OVM5NtB+5kuZN4VDtpleIkVAOrhHxWJoJkNv2QAd51AAAAAElFTkSuQmCC"],
      ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYfLAEN9AsAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAGdJREFUOMutk+EKACEIg7fD93/l3Y+uP5kmeYMgkH0NTUpCRw+acgBynHaCKsgBlpaIhDJQtQchaAtIBuNAlAQSV7OUwPYYGX2kL6Zi37hYYk6NU1ZPui/Y4XWeVsWSDpdkt8bftvEFOy0jJkeygWMAAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tFm3TfiwAAABySURBVDjLrZNRDsAgCEPp4r306HKy7sMsMRMckZH4ZfqoYEFSMnVJshYAME7aQRS0AOaR9C5UFe5AoRnsQCbAW4wFAklRlaNd1ipIrxHeRwKGZeuuNcEjK554J5x7lohNS+g+4d39Kyqug2jGyqnwtzTengM2Gxwa0GsAAAAASUVORK5CYII="],
      ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAoCAYAAABw65OnAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94GCAc3MvOL7YEAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAACsJJREFUWMOlmHtsHVV+x7/nMWdm7r1zH45zvXnYuQFCQ0ikJC6JTEC9RbRg+AOpqf9KJdqKBFb9gy1/rlYrFgmhVuIhVSgbpF0WqyAoEivEsqtNUDMtCaAUV9k0BkKcteXYvbGv7VzfudczZ2bOOf0Dm80mfm33SPPPzJlzPuec3+P7OwR/eKMASLVaJUEQkKWXnucZ3/cNAANA/yEDknX2IdVqlY6NjfFKpcLTNLXCMGS2bdNms0ny+byRUmrXdRXnPBkbG0srlUrq+75ehDKrTcDWmJz29vZyrbWTz+eznuflwzAsaq1LADo45yUhRIlSmldKeUqpjJTSKRaLQinFkiQhO3fuNLVa7f+1E6RarTIppQXAZYzltNb5AwcOdB85cuQvenp6/jSXy93uOE4npVRoreMoimZardaV8fHxz998881T586du0opbSqlWgBC27YT3/fVcruyHATp7e3ljuM4URTlLMsqPvroo3/y+OOPP7lly5YHKaV8pRWFcRuuyEJrnU5OTn70xhtvnPjwww8vJUnScBynFUVRNDQ0lN4MQpYD4Jy7tm0X4jje+NJLL/3NgQMHvksocSih6zY2bTSMNtG5c+eOP/PMM/8qhKhLKefTNA1vBiE3H0GSJC4hpJTJZDadOHHih5VK5RH8kW1sbOyXTz755HMLCws1Y8x1y7LCG4/mRsNkYRg6xWKxQAj5zuuvv/6jtQDS8UugM6PA7AS0Bkg2v2y/YrG44/7779/y3nvvndNaJ5cvX07b7fYtEKS/v9/KZDKelLL88ssv/92ePXuOrLXCK4/dgQ1Xfgn86qeYuDyGwgN/tWLfYrG4Y+fOnfKDDz74qlwux7t3705GRkb0UuBBtVpl09PTjjEm39/ff/fBgwePrQUw88VvoK7OA44HMBvz/i/WPJaDBw8e6+/vv9sYk5+ennaq1Sr7Nvr5vs+iKHJt2y4ePXr0CcaYvdaAs5+dRIcHgBFACHitebTra8QDSuyjR48+Ydt2MYoi1/d9BoBQAPTQoUPCcZzs/v37t2/btu2B9Rjb/Ke/Ro4umjYnKDLg+mcfrR7vCUV3d/ef7d+/f7vjONlDhw4JAJRWq1WSJInIZDLZw4cPP7heizdTV8HKBSC/EejoglUuQo5+uXbioZQdPnz4wUwmk02SRFSrVcJ932e9vb1CSpnt6enZtx6ASEp0fe+fYHeVgUIBUCmcIAAP185bC7KFnp6efVLKrFJK+L7PeF9fHyWECMuynGKxWFkPxEy9jo57/hzwCr+XWrNzdcRxDCHEiv9m7Bx0ERXXdZ0kSURfXx+lnudRKSWP41hkMpnieiBm52bg3ADw7QQdG9CYm13z/0wmU4zjWEgpued5lMdxTDjn1BhDKaXWeiDmnv1bTEfT2HTH7SB33QmkCrh4EfMT19B67CmUj/1gLbuwjDGUc07jOCYcAFzXNVEUQSmVMMZWBTHGAKMXkJEGTM0AbggkEhgZhjVt0D7nA2tAKKWSpXkBgAohTJqmWgih2u323NpuYeBEBpziGwGVSEApgFBYCkguX1hziHa7PSeEUIvzGh4EgWaMpVrreHZ2dsx2rS7bclfNjuUn/hHW3DhgQmBzJ2A0ULgDjiig3LMXjWYTxfzyeUQmIebm5ka11jGANAgCzT/99FPd29ubWJYVXrp06fz27dsPrraKMIzQ8fffh1vqvOWbDSA/P4f563MrQtiWi6+++uo3aZqGSZIkQ0NDmlarVSWEkISQhcHBwTNKKbkaxNT/XgWnK0tGphXC+ZU9JE1TOTg4eIYQsiCEkNVqVVHf97Vt2zFjrD0xMVG7ePGiv+JRqBS1wVcQfXISqF0BrteAoP7NM1cDxobR/mAQ82++siLE8PCwPzExUWOMtW3bjn3f12Qx+ovdu3cXc7ncljvvvHPva6+99opt297NXjF69iNcOfKX2JEAmzsAcXsB2NYNKAOM/RZ6NMTkPDDak8POf/sfbNy6DYT8TjdJKYNjx4597+uvvz7farUmL1682AAQfytqduzYAcYYazQacF13Yc+ePQcJIURrjWvXruEnPxvEr3/4D6gEITYVgGIBIBYBBAGSCGgtgJgUCwa4NBXjxJlPULp9F7q7t4IQAmOMefvtt3986tSpzxhjU7Ztz1+9elUC0EuiVZ89ezbu7e1tUkqnjh8/fmrDhg2VkZGRx1544QUsSfa/BmCXv/XUbzbRGMAsbqgBCAO4BP7z9H/hJ6fvR6VSwfPPP49yufzz48ePn0qSZFpr3RwaGoqXiqQb5Z3ZvHmzyeVyOooic/bs2dFHHnnE+vzzz3ddu3YNAGAB2KSB77jARhegGQvIut8AhAvQCykuzwP/MQP8uwYiAI1GA+fPn58+efLkCUrp17lcbjqO41atVouX5N0tQheAI6UsACgD2DIwMPDAhQsXvvvWW285cRyjC8ABAHfngZ4ikM1zGBgETYXxBvDfTeATACGAzs5Ofc899/xqbm7uBKV0AsC0bdvzAKIbhS5ZrugB4ARB4AkhOhljXfl8fttdd931xDvvvHNgYmJiVd1PCEEulzMPP/zwcLPZ/Jd2u/1bpdRUHMcznucFNwOsWPxUq1UWBIHIZDLZIAiKjuN0MMa6OOfdmUzmmY8//vi2Vqu1LMRDDz0032w2n+Wcj8VxfE1KOet5XmNhYaHteV68XBW23KqM7/tqaGhIMsYCAHVjzKTWelQpdanRaDz/1FNP1bLZ7OLKgV27duH999/H7Oxso1Qq/cgYcymKojGt9SSAOmMsGBoakiuVgXy1+jQIAuW6rozj2DiOo7XWRmtNJycn/7lWqz2by+UKWuulWKBffPHF1ycmJkaUUjVK6YyUsuW6rqzX6/qmsc1qVTkZGBigX3zxhdXV1SU6OjoEIcTmnAulFE+ShNu2bTUaDdput+fvvffe3mZ4nbh2FqdPnz716quvfgRghjEWUEqTMAzBOWednZ1s06ZNfOvWrbRQKJB6vb4iBKlWq2xqasru7u7Olkolj1JaMMbkOecFSmnetm2PEJJVSmW+/PJLWalU3F07d1fGx8fHnn766XeVUi1KaUwIoQBs13XdNE0zcRy7AOwgCLjjONi7d69ZLHxuKQOXLkEylmUV0zQtCSFKjLFSkiQlQkgxSZICpTRvjNmqlCqfOXMm2LdvX9dzzz13pl6vLyVSMMa4MSZrjMkByDLGXEqpEEIwIYSWUqpyuaxrtdotLsr6+voEIcQjhJTSNC1ZlpUD4CZJIoQQFiGExXFsGWN6AOTTNHU551wppY0xkhDS4pxPU0qvG2NSxlhKCEmSJJFCiHYYhk3Lsq4LIeaDIGgvVefkJk+x7rvvvgwAT0rpWZaVIYQ4xhhLKcUJIYxSSgkhTCnFOeeMEMKSJNHGGMUYS40xyhijCCGac54CSKWUsTEmTJKknaZp0xjTHh4ejgAoAOZG7zADAwNpvV4PgyDQUkrpuq5oNBrccRyLUsqUUlQpBc455ZxTKSUxxhBCiLFt2xBCjFJKp2lqHMcxUspUKaVs204JIQkhRCZJIgEs5Y3lI+biRQmbnZ1lGzZsoJ7n0SAImOd5JE1TopQii2L1lkDHGDO/U2ChZowZx3H0yMiIvu2223Sz2VQbN27U64mYN74ni26Ler3+e1eGa7WlK8WBgQG8++675ob4cEuw+j+lA177aXrCYwAAAABJRU5ErkJggg==","data:image/png;base64,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"]
   ];   
}


function uroBootstrap()
{
   var bGreasemonkeyServiceDefined = false;
   try {
      bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object");
   }
   catch (err) { /* Ignore */ }
   if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) {
      unsafeWindow    = ( function () {
         var dummyElem = document.createElement('p');
         dummyElem.setAttribute('onclick', 'return window;');
         return dummyElem.onclick();
      }) ();
   }
   /* begin running the code! */
   uroInitialise();
}


function uroAddLog(logtext)
{
   console.log('URO+: '+logtext);
}

function uroGatherSettings(container)
{
   var options = '';
   var urOptions = document.getElementById(container).getElementsByTagName('input');
   for (var optIdx=0;optIdx<urOptions.length;optIdx++)
   {
      var id = urOptions[optIdx].id;
      if((id.indexOf('_cb') == 0)||(id.indexOf('_text') == 0)||(id.indexOf('_input') == 0))
      {
         options += ':' + id;
         if(urOptions[optIdx].type == 'checkbox') options += ',' + urOptions[optIdx].checked.toString();
         else if((urOptions[optIdx].type == 'text')||(urOptions[optIdx].type == 'number')) options += ',' + urOptions[optIdx].value.toString();
      }
   }
   return options;
}


function uroGatherCamWatchList()
{
   var liststr = '';
   for(var loop=0;loop<uroCamWatchObjects.length;loop++)
   {
      camObj = uroCamWatchObjects[loop];
      if((camObj.fid != undefined) && (camObj.persistent == true))
      {
         if(loop > 0) liststr += ':';

         liststr += camObj.fid+',';
         liststr += camObj.watchLon+',';
         liststr += camObj.watchLat+',';
         liststr += camObj.watchType+',';
         liststr += camObj.watchAzymuth+',';
         liststr += camObj.watchSpeed+',';
         liststr += camObj.watchValidated+',';
         liststr += camObj.groupID;
      }
   }
   return liststr;
}

function uroGatherCWLGroups()
{
   var liststr = '';
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      groupObj = uroCWLGroups[loop];
      if(groupObj.groupID != -1)
      {
         if(loop > 0) liststr += ':';

         liststr += groupObj.groupID+',';
         liststr += groupObj.groupName+',';
         liststr += groupObj.groupCollapsed;
      }
   }
   return liststr;
}

function uroSaveSettings()
{
   if(uroInhibitSave) return;

   if (localStorage)
   {
      localStorage.UROverviewUROptions = uroGatherSettings('uroCtrlURs');
      localStorage.UROverviewMPOptions = uroGatherSettings('uroCtrlMPs');
      localStorage.UROverviewCameraOptions = uroGatherSettings('uroCtrlCameras');
      localStorage.UROverviewMiscOptions = uroGatherSettings('uroCtrlMisc');
      localStorage.UROverviewCamWatchList = uroGatherCamWatchList();
      localStorage.UROverviewCWLGroups = uroGatherCWLGroups();
   }
}

function uroApplySettings(settings)
{
   var options = settings.split(':');
   for(var optIdx=0;optIdx<options.length;optIdx++)
   {
      var fields = options[optIdx].split(',');
      if(fields[0].indexOf('_cb') == 0)
      {
         if(document.getElementById(fields[0]) != null) document.getElementById(fields[0]).checked = (fields[1] == 'true');
      }
      else if((fields[0].indexOf('_input') == 0)||(fields[0].indexOf('_text') == 0))
      {
         if(document.getElementById(fields[0]) != null) document.getElementById(fields[0]).value = fields[1];
      }
   }
}


function uroApplyCamWatchList()
{
   var objects = localStorage.UROverviewCamWatchList.split(':');
   uroCamWatchObjects = new Array();

   for(var objIdx=0;objIdx<objects.length;objIdx++)
   {
      var fields = objects[objIdx].split(',');
      if(fields.length == 7)
      {
         fields.push(0);
      }
      if(fields[7] == -1) fields[7] = 0;
      uroCamWatchObjects.push(new uroCamWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7]));
   }
}

function uroApplyCWLGroups()
{
   var objects = localStorage.UROverviewCWLGroups.split(':');
   uroCWLGroups = new Array();

   for(var objIdx=0;objIdx<objects.length;objIdx++)
   {
      var fields = objects[objIdx].split(',');
      if(fields.length < 2)
      {
         fields.push(false);
      }
      uroCWLGroups.push(new uroCWLGroupObj(fields[0],fields[1],(fields[2] == 'true')));
   }
}

function uroLoadSettings()
{
   uroAddLog('loadSettings()');
   if (localStorage.UROverviewUROptions)
   {
      uroAddLog('recover UR tab settings');
      uroApplySettings(localStorage.UROverviewUROptions);
   }
   
   if (localStorage.UROverviewCameraOptions)
   {
      uroAddLog('recover camera tab settings');
      uroApplySettings(localStorage.UROverviewCameraOptions);
   }

   if (localStorage.UROverviewMPOptions)
   {
      uroAddLog('recover MP tab settings');
      uroApplySettings(localStorage.UROverviewMPOptions);
   }

   if (localStorage.UROverviewMiscOptions)
   {
      uroAddLog('recover misc tab settings');
      uroApplySettings(localStorage.UROverviewMiscOptions);
   }
   
   if(localStorage.UROverviewCamWatchList)
   {
      uroAddLog('recover camera watchlist');
      uroApplyCamWatchList();
      uroGetCurrentCamWatchListObjects();
   }
   
   if(localStorage.UROverviewCWLGroups)
   {
      uroAddLog('recover CWL groups');
      uroApplyCWLGroups(); 
   }   
   else
   {
      uroAddLog('set default CWL group');
      uroCWLGroups.push(new uroCWLGroupObj(0,'No group',false));
   }
   
   uroInhibitSave = false;
}

function uroSettingsToText()
{
   var txtSettings = '';
   
   uroSaveSettings();
   
   if (localStorage.UROverviewUROptions)
   {
      txtSettings += '[UROverviewUROptions][len=' + localStorage.UROverviewUROptions.length + ']' + localStorage.UROverviewUROptions + '[END]';
   }
   if (localStorage.UROverviewCameraOptions)
   {      
      txtSettings += '[UROverviewCameraOptions][len=' + localStorage.UROverviewCameraOptions.length + ']' + localStorage.UROverviewCameraOptions + '[END]';
   }
   if (localStorage.UROverviewMPOptions)
   {
      txtSettings += '[UROverviewMPOptions][len=' + localStorage.UROverviewMPOptions.length + ']' + localStorage.UROverviewMPOptions + '[END]';
   }
   if (localStorage.UROverviewMiscOptions)
   {
      txtSettings += '[UROverviewMiscOptions][len=' + localStorage.UROverviewMiscOptions.length + ']' + localStorage.UROverviewMiscOptions + '[END]';
   }
   if (localStorage.UROverviewCamWatchList)
   {
      txtSettings += '[UROverviewCamWatchList][len=' + localStorage.UROverviewCamWatchList.length + ']' + localStorage.UROverviewCamWatchList + '[END]';
   }
   if (localStorage.UROverviewCWLGroups)
   {
      txtSettings += '[UROverviewCWLGroups][len=' + localStorage.UROverviewCWLGroups.length + ']' + localStorage.UROverviewCWLGroups + '[END]';
   }
   
   document.getElementById('_txtSettings').value = txtSettings;
   document.getElementById('_txtSettings').focus();
   document.getElementById('_txtSettings').select();
}  

function uroTextToSettings()
{
   var txtSettings = '';
   txtSettings = document.getElementById('_txtSettings').value;
   if(txtSettings.indexOf('[END]') == -1) return;
   
   var subText = txtSettings.split('[END]');
   for(var i=0;i<subText.length;i++)
   {
      var bPos = subText[i].indexOf(']');
      if(bPos != -1)
      {
         var settingID = subText[i].substr(1,bPos-1);
         subText[i] = subText[i].substr(bPos+1);
         bPos = subText[i].indexOf(']');
         if(bPos != -1)
         {
            var settingLength = subText[i].substr(5,bPos-5);
            subText[i] = subText[i].substr(bPos+1);
            if(subText[i].length == settingLength)
            {
               if(settingID == 'UROverviewCamWatchList') localStorage.UROverviewCamWatchList = subText[i];
               if(settingID == 'UROverviewCWLGroups') localStorage.UROverviewCWLGroups = subText[i];
               if(settingID == 'UROverviewUROptions') localStorage.UROverviewUROptions = subText[i];
               if(settingID == 'UROverviewCameraOptions') localStorage.UROverviewCameraOptions = subText[i];
               if(settingID == 'UROverviewMPOptions') localStorage.UROverviewMPOptions = subText[i];
               if(settingID == 'UROverviewMiscOptions') localStorage.UROverviewMiscOptions = subText[i];
            }
         }
      }
   }  
   uroLoadSettings();
}

function uroClearSettingsText()
{
   document.getElementById('_txtSettings').value = '';
}


function uroDateToDays(dateToConvert, ticksPerDay)
{
   var dateNow = new Date();
   return Math.floor((dateNow.getTime() - dateToConvert) / 86400000);
}

function uroGetURAge(urObj,ageType)
{
   if(ageType == 0)
   {
      if((urObj.attributes.driveDate == null)||(urObj.attributes.driveDate == 0)) return -1;
      return uroDateToDays(urObj.attributes.driveDate, urObj.ONE_DAY);
   }
   else
   {
      if((urObj.attributes.resolvedOn == null)||(urObj.attributes.resolvedOn == 0)) return -1;
      return uroDateToDays(urObj.attributes.resolvedOn, 86400000);
   }
}

function uroGetCameraAge(camObj, mode)
{
   if(mode == 0)
   {
      if(camObj.attributes.updatedOn == null) return -1;
      return uroDateToDays(camObj.attributes.updatedOn, 86400000);
   }
   if(mode == 1)
   {
      if(camObj.attributes.createdOn == null) return -1;
      return uroDateToDays(camObj.attributes.createdOn, 86400000);
   }
}

function uroGetCommentAge(commentObj)
{
   if(commentObj.createdOn == null) return -1;
   return uroDateToDays(commentObj.createdOn, 86400000);
}

function uroParseDaysAgo(days)
{
  if(days == 0) return 'today';
  else if(days == 1) return '1 day ago';
  else return days+' days ago';
}

function uroIsCameraSpeedValid(camObj)
{
   // returns 1 if the entered speed converts correctly into a multiple of 10MPH
   // returns -1 if the entered speed does not convert correctly
   // returns 0 if no speed data is present, or if the entered speed is 0
   if(camObj.attributes.speed != null)
   {
      var speed = Math.round(camObj.attributes.speed /1.609);
      if(speed == 0) return 0;
      else if(speed % 10 == 0) return 1;
      else return -1;
   }
   else return 0;
}


function uroTypeCast(varin)
{
   if(varin == "null") return null;
   if(typeof varin == "string") return parseInt(varin);
   return varin;
}

function uroCWLGroupObj(groupID, groupName, groupCollapsed)
{
   groupID = uroTypeCast(groupID);
   this.groupID = groupID;
   this.groupName = groupName;
   this.groupCount = 0;
   this.groupCollapsed = groupCollapsed;
}
  
function uroCamWatchObj(persistent, fid, lon, lat, type, azymuth, speed, validated, groupID)
{
   fid = uroTypeCast(fid);
   lon = uroTruncate(uroTypeCast(lon));
   lat = uroTruncate(uroTypeCast(lat));
   type = uroTypeCast(type);
   azymuth = uroTruncate(uroTypeCast(azymuth)%360);
   speed = uroTruncate(uroTypeCast(speed));
   groupID = uroTypeCast(groupID);
   
   if(typeof validated == "string") validated = (validated == "true");
   if(typeof persistent == "string") persistent = (persistent == "true");

   this.fid = fid;
   this.persistent = persistent;
   this.loaded = false;
   this.watchType = type;
   this.watchAzymuth = azymuth;
   this.watchSpeed = speed;
   this.watchValidated = validated;
   this.watchLat = lat;
   this.watchLon = lon;
   this.groupID = groupID;
   this.currentType = null;
   this.currentAzymuth = null;
   this.currentSpeed = null;
   this.currentValidated = null;
   this.currentLat = null;
   this.currentLon = null;
}

function uroCamDataChanged(camidx)
{
   camObj = uroCamWatchObjects[camidx];
   if(camObj.loaded == false) return false;
   if(camObj.currentType != camObj.watchType) return true;
   if(camObj.currentAzymuth != camObj.watchAzymuth) return true;
   if(camObj.currentSpeed != camObj.watchSpeed) return true;
   if(camObj.currentValidated != camObj.watchValidated) return true;
   if(camObj.currentLat != camObj.watchLat) return true;
   if(camObj.currentLon != camObj.watchLon) return true;
   return false;
}

function uroAddCurrentCamWatchData(idx, lat, lon, type, azymuth, speed, validated)
{
   camObj = uroCamWatchObjects[idx];
   camObj.loaded = true;
   camObj.currentType = type;
   camObj.currentAzymuth = uroTruncate(azymuth%360);
   camObj.currentSpeed = uroTruncate(speed);
   camObj.currentValidated = validated;
   camObj.currentLat = uroTruncate(lat);
   camObj.currentLon = uroTruncate(lon);
   
   return(uroCamDataChanged(idx));
}

function uroIsCamOnWatchList(fid)
{
   for(var loop=0;loop<uroCamWatchObjects.length;loop++)
   {
      if(uroCamWatchObjects[loop].fid == fid) return loop;
   }
   return -1;
}

function uroAddCamToWatchList()
{
   if(uroIsCamOnWatchList(uroShownFID) == -1)
   {
      camObj = wazeModel.cameras.objects[uroShownFID];
      uroCamWatchObjects.push(new uroCamWatchObj(true, uroShownFID, camObj.geometry.x, camObj.geometry.y, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, 0));
      uroAddCurrentCamWatchData(uroCamWatchObjects.length-1, camObj.geometry.y, camObj.geometry.x, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated);
      uroAddLog('added camera '+uroShownFID+' to watchlist');
      uroCWLUpdateHTML();
   }
}

function uroRemoveCamFromWatchList()
{
   camidx = uroIsCamOnWatchList(uroShownFID);
   if(camidx != -1)
   {
      uroCamWatchObjects.splice(camidx,1);
      uroAddLog('removed camera '+uroShownFID+' from watchlist');
      uroCWLUpdateHTML();
   }
}

function uroUpdateCamWatchList()
{
   var camIdx = uroIsCamOnWatchList(uroShownFID);
   if(camIdx != -1)
   {
      var camObj = wazeModel.cameras.objects[uroShownFID];
      uroCamWatchObjects[camIdx].lon = camObj.geometry.x;
      uroCamWatchObjects[camIdx].lat = camObj.geometry.y;
      uroCamWatchObjects[camIdx].azymuth = camObj.attributes.azymuth;
      uroCamWatchObjects[camIdx].speed = camObj.attributes.speed;
      uroCamWatchObjects[camIdx].validated = camObj.attributes.validated;
   }
}


function uroClearCamWatchList()
{
   if(confirm('Removing all cameras from the CWL cannot be undone\nAre you sure you want to do this?') == true)
   {
      uroCamWatchObjects = new Array();
      uroCWLUpdateHTML();
   }
}

function uroTruncate(val)
{
   if(val == null) return val;
   if(val < 0) return Math.ceil(val);
   return Math.floor(val);
}


function uroRetrieveCameras(lat, lon)
{
   var camPos = new OpenLayers.LonLat();
   var camChanged = false;
   
   camPos.lon = lon;
   camPos.lat = lat;
   camPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));

   var camURL = 'https://' + document.location.host;
   camURL += Waze.Config.api_base;
   camURL += '/Features?language=en&cameras=true&bbox=';
   var latl = camPos.lat - 0.25;
   var latu = camPos.lat + 0.25;
   var lonl = camPos.lon - 0.25;
   var lonr = camPos.lon + 0.25;
   camURL += lonl+','+latl+','+lonr+','+latu;
   uroAddLog('retrieving camera data around '+camPos.lon+','+camPos.lat);

   camReq = new XMLHttpRequest();
   camReq.open('GET',camURL,false);
   try
   {
      camReq.send();
      uroAddLog('response '+camReq.status+' received');
      if (camReq.status === 200)
      {
         camData = JSON.parse(camReq.responseText);
         for(var camIdx = 0; camIdx < camData.cameras.objects.length; camIdx++)
         {
            camObj = camData.cameras.objects[camIdx];
            var listIdx = uroIsCamOnWatchList(camObj.id);
            if(listIdx != -1)
            {
               camPos.lon = camObj.geometry.coordinates[0];
               camPos.lat = camObj.geometry.coordinates[1];
               camPos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
               camPos.lon = uroTruncate(camPos.lon);
               camPos.lat = uroTruncate(camPos.lat);
               camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated);
            }
            else if(camObj.validated == false)
            {

            }
         }  
      }
      else
      {
         uroAddLog('request failed (status != 200)');
      }
   }
   catch(err)
   {
      uroAddLog('camera load request failed (exception '+err+' caught)');
   }
   return camChanged;
}


function uroGetCurrentCamWatchListObjects()
{
   var camChanged = false;
   for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      camObj = uroCamWatchObjects[camidx];
      if(camObj.loaded == false)
      {
         if(typeof wazeModel.cameras.objects[camObj.fid] == 'object')
         {
            if(wazeModel.cameras.objects[camObj.fid].state != "Delete")
            {
               wazeObj = wazeModel.cameras.objects[camObj.fid];
               camChanged |= uroAddCurrentCamWatchData(camidx, wazeObj.geometry.y, wazeObj.geometry.x, wazeObj.attributes.type, wazeObj.attributes.azymuth, wazeObj.attributes.speed, wazeObj.attributes.validated);
            }
            else
            {
               camChanged |= uroRetrieveCameras(camObj.watchLat, camObj.watchLon);
            }
         }
         else
         {
            camChanged |= uroRetrieveCameras(camObj.watchLat, camObj.watchLon);
         }
      }
   }

   var allLoaded = true;
   for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      allLoaded &= uroCamWatchObjects[camidx].loaded;
   }

   if((camChanged)||(!allLoaded))
   {
      alert('One or more cameras on your watchlist have been modified or deleted!');
   }
}

function uroClearDeletedCameras()
{
   for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
   {
      if(uroCamWatchObjects[camidx].loaded == false)
      {
         uroShownFID = uroCamWatchObjects[camidx].fid;
         uroRemoveCamFromWatchList();
      }
   }
}

function uroRescanCamWatchList()
{
   for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      uroCamWatchObjects[camidx].loaded = false;
   }
   uroGetCurrentCamWatchListObjects();
   uroCWLUpdateHTML();
}


function uroGotoCam()
{
   var camidx = this.id.substr(13);
   var camPos = new OpenLayers.LonLat();
   camPos.lon = uroCamWatchObjects[camidx].watchLon;
   camPos.lat = uroCamWatchObjects[camidx].watchLat;
   wazeMap.setCenter(camPos,4);
   wazeMap.layers[uroCamLayer].setVisibility(true);
   return false;
}

function uroSetCamGroup()
{
   var camidx = this.id.substr(13);
   
   return false;
}

function uroHighlightCWLEntry()
{
   this.style.backgroundColor = '#FFFFAA';
   return false;
}

function uroUnhighlightCWLEntry()
{
   var camidx = this.id.substr(8);
   var changed = uroCamDataChanged(camidx);
   var deleted = (uroCamWatchObjects[camidx].loaded == false);

   if(changed) this.style.backgroundColor = '#AAAAFF';
   else if(deleted) this.style.backgroundColor = '#FFAAAA';
   else this.style.backgroundColor = '#FFFFFF';
   return false;
}

function uroCWLIconHighlight()
{
   iconType = this.id.substr(11,1);
   this.src = uroIcons[iconType][0];
   return false;
}

function uroCWLIconLowlight()
{
   iconType = this.id.substr(11,1);
   this.src = uroIcons[iconType][1];
   return false;
}

function uroRemoveFromCWL()
{
   uroShownFID = uroCamWatchObjects[this.id.substr(18)].fid;
   uroRemoveCamFromWatchList();
}  


function uroSetCamGroups()
{
   for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      camObj = uroCamWatchObjects[camidx];
      camGroup = parseInt(document.getElementById("_uroGroupSelect-"+camidx).value);
      camObj.groupID = camGroup;
   }  
}


function uroPopulateCWLGroupSelect()
{
   selector = document.getElementById('_uroCWLGroupSelect');
   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   } 
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      groupObj = uroCWLGroups[loop];
      if(groupObj.groupID != -1)
      {
         selector.options.add(new Option(groupObj.groupName,groupObj.groupID));
      }
   }
}

function uroGetNextCWLGroupID()
{
   var nextID = 1;
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      if(uroCWLGroups[loop].groupID >= nextID)
      {
         nextID = uroCWLGroups[loop].groupID + 1;
      }
   }
   return nextID;
}

function uroFindCWLGroupByName(groupName)
{
   var groupID = -1;
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      if((uroCWLGroups[loop].groupName == groupName) && (uroCWLGroups[loop].groupID != -1))
      {
         groupID = uroCWLGroups.groupID;
         break;
      }
   }
   return groupID;
}

function uroAddCWLGroup()
{
   var groupID = uroGetNextCWLGroupID();
   var groupName = document.getElementById('_uroCWLGroupEntry').value;
   if(uroFindCWLGroupByName(groupName) == -1)
   {  
      uroCWLGroups.push(new uroCWLGroupObj(groupID,groupName,false));
      uroPopulateCWLGroupSelect();
   }
}  

function uroRemoveCWLGroup()
{
   selector = document.getElementById('_uroCWLGroupSelect');
   var groupID = parseInt(selector.selectedOptions[0].value);
   if(groupID == 0) return false;   // prevent deletion of the default group
   
   for(var loop=0;loop<uroCamWatchObjects.length;loop++)
   {
      cwObj = uroCamWatchObjects[loop];
      if(cwObj.groupID == groupID)
      {
         cwObj.groupID = 0;
      }   
   }
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      groupObj = uroCWLGroups[loop];
      if(groupObj.groupID == groupID)
      {
         groupObj.groupID = -1;
      }
   }
   uroCWLUpdateHTML();
}

function uroAssignCameraToGroup()
{
   var camidx = this.id.substr(13);
   selector = document.getElementById('_uroCWLGroupSelect');
   uroCamWatchObjects[camidx].groupID = parseInt(selector.selectedOptions[0].value);
   uroCWLUpdateHTML();
   return false;
}   

function uroAddBtnEvl(btnID, evlType, evlFunction)
{
   btnObj = document.getElementById(btnID);
   if(btnObj != null)
   {
      btnObj.addEventListener(evlType, evlFunction, true);
   }
}

function uroCWLGroupCollapseExpand()
{
   var groupidx = this.id.substr(18);
   if(uroCWLGroups[groupidx].groupCollapsed == true) uroCWLGroups[groupidx].groupCollapsed = false;
   else uroCWLGroups[groupidx].groupCollapsed = true; 
   uroCWLUpdateHTML();
   return false;
}   

function uroCWLUpdateHTML()
{
   var camTypes = new Array("","","Speed", "Dummy", "Red Light");
   var selectedGroup = 0;
   iHTML = '';
   
   if(document.getElementById('_uroCWLGroupSelect') != null)
   {
      selectedGroup = document.getElementById('_uroCWLGroupSelect').selectedIndex;
   }

   
   iHTML = '<br><b>Camera Watchlist:</b><br><br>';
   iHTML += '<div id="_uroCWLCamList" style="height:65%;overflow:auto;">';
   for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
   {
      var groupObj = uroCWLGroups[groupidx];
      iHTML += '<div id="_uroCWLGroup-'+groupidx+'">';
      if(groupObj.groupCollapsed == true)
      {
         iHTML += '<img src="'+uroIcons[0][1]+'" id="_uroCWLGroupState-'+groupidx+'">';
      }
      else
      {
         iHTML += '<img src="'+uroIcons[0][0]+'" id="_uroCWLGroupState-'+groupidx+'">';   
      }
      iHTML += '<b>'+groupObj.groupName+'</b><br>';
      groupObj.groupCount = 0;
      for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
      {
         camObj = uroCamWatchObjects[camidx];
         if(camObj.groupID == groupObj.groupID)
         {
            groupObj.groupCount++;
            var changed = uroCamDataChanged(camidx);
            var deleted = (camObj.loaded == false);
            iHTML += '<div id="_uroCWL-'+camidx+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF;background-color:';
            if(changed) iHTML += '#AAAAFF;';
            else if(deleted) iHTML += '#FFAAAA;';
            else iHTML += '#FFFFFF;';
            
            if(groupObj.groupCollapsed == true) iHTML += 'display:none;">';
            else iHTML += 'display:block;">';

            iHTML += 'ID: '+camObj.fid;
            iHTML += ' Type: '+camTypes[camObj.watchType];
            if(deleted)
            {
               iHTML += '<br>DELETED';
            }
            if(changed) 
            {
               if(camObj.currentType != camObj.watchType) 
               {
                  iHTML += '<br>&nbsp;&nbsp;Type changed';
                  iHTML += ' ('+camObj.watchType+' to '+camObj.currentType+')';
               }   
               if(camObj.currentAzymuth != camObj.watchAzymuth)
               {
                  iHTML += '<br>&nbsp;&nbsp;Azimuth changed';
                  iHTML += ' ('+camObj.watchAzymuth+' to '+camObj.currentAzymuth+')';
               }   
               if(camObj.currentSpeed != camObj.watchSpeed)
               {
                  iHTML += '<br>&nbsp;&nbsp;Speed changed';
                  iHTML += ' ('+camObj.watchSpeed+' to '+camObj.currentSpeed+')';
               }   
               if(camObj.currentValidated != camObj.watchValidated)
               {
                  iHTML += '<br>&nbsp;&nbsp;Approval state changed';
                  iHTML += ' ('+camObj.watchValidated+' to '+camObj.currentValidated+')';
               }   
               if(camObj.currentLat != camObj.watchLat)
               {
                  iHTML += '<br>&nbsp;&nbsp;Latitude changed';
                  iHTML += ' ('+camObj.watchLat+' to '+camObj.currentLat+')';
               }   
               if(camObj.currentLon != camObj.watchLon)
               {
                  iHTML += '<br>&nbsp;&nbsp;Longitude changed';
                  iHTML += ' ('+camObj.watchLon+' to '+camObj.currentLon+')';
               }   
            }   
      
            iHTML += '&nbsp;<img id="_uroCWLIcon1-'+camidx+'" src="'+uroIcons[1][1]+'">';
            iHTML += '&nbsp;<img id="_uroCWLIcon2-'+camidx+'" src="'+uroIcons[2][1]+'">';
            iHTML += '</div>';
         }
      }
      iHTML += '</div>';
   }
   iHTML += '</div><div id="_uroCWLControls">';
   iHTML += '<hr>Group control:<br>';
   iHTML += '<select id="_uroCWLGroupSelect" style="width:40%;height:22px;"></select>&nbsp;<input type="button" id="_btnCWLGroupDel" value="Delete group"><br>';
   iHTML += '<input type="text" id="_uroCWLGroupEntry" style="width:40%;height:22px;">&nbsp;<input type="button" id="_btnCWLGroupAdd" value="Add group">';
   iHTML += '<hr><input type="button" id="_btnRescanCamWatchList" value="Rescan">';
   iHTML += '&nbsp;|&nbsp;<input type="button" id="_btnRemoveDeletedCameras" value="Remove deleted">';
   iHTML += '&nbsp;|&nbsp;<input type="button" id="_btnClearCamWatchList" value="Remove all">';
   iHTML += '</div>';
   uroCamWatchlist.innerHTML = iHTML;
   
   for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      document.getElementById("_uroCWL-"+camidx).onmouseover = uroHighlightCWLEntry;
      document.getElementById("_uroCWL-"+camidx).onmouseleave = uroUnhighlightCWLEntry;

      document.getElementById("_uroCWLIcon1-"+camidx).onmouseover = uroCWLIconHighlight;
      document.getElementById("_uroCWLIcon1-"+camidx).onmouseleave = uroCWLIconLowlight;
      document.getElementById("_uroCWLIcon1-"+camidx).onclick = uroAssignCameraToGroup;

      document.getElementById("_uroCWLIcon2-"+camidx).onmouseover = uroCWLIconHighlight;
      document.getElementById("_uroCWLIcon2-"+camidx).onmouseleave = uroCWLIconLowlight;
      document.getElementById("_uroCWLIcon2-"+camidx).onclick = uroGotoCam;
   }
   
   uroAddBtnEvl('_btnClearCamWatchList', 'click', uroClearCamWatchList);
   uroAddBtnEvl('_btnRemoveDeletedCameras', 'click', uroClearDeletedCameras);
   uroAddBtnEvl('_btnRescanCamWatchList', 'click', uroRescanCamWatchList);
   uroAddBtnEvl('_btnCWLGroupDel', 'click', uroRemoveCWLGroup);
   uroAddBtnEvl('_btnCWLGroupAdd', 'click', uroAddCWLGroup);
   if(document.getElementById('_uroCWLGroupSelect') != null)
   {
      uroAddLog('populating CWL group list');
      uroPopulateCWLGroupSelect();
      selector = document.getElementById('_uroCWLGroupSelect');
      if(selectedGroup >= selector.length)
      {
         selectedGroup = 0;
      }
      selector.selectedIndex = selectedGroup;
   }

   for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
   {   
      if(uroCWLGroups[groupidx].groupCount == 0)
      {
         document.getElementById('_uroCWLGroup-'+groupidx).style.display = 'none';
      }
      else
      {
         document.getElementById('_uroCWLGroupState-'+groupidx).onclick = uroCWLGroupCollapseExpand;
      }
   }
}


function uroIsOnIgnoreList(fid)
{
   if(sessionStorage.UROverview_FID_IgnoreList.indexOf('fid:'+fid) == -1) return false;
   else return true;
}

function uroEnableIgnoreListControls()
{
   var btnState = false;
   if(sessionStorage.UROverview_FID_IgnoreList == '')
   {
      btnState = true;
   }
   document.getElementById('_btnUndoLastHide').disabled = btnState;
   document.getElementById('_btnClearSessionHides').disabled = btnState;
   uroFilterURMarkers();
}

function uroAddToIgnoreList()
{
   if(!uroIsOnIgnoreList(uroShownFID))
   {
      sessionStorage.UROverview_FID_IgnoreList += 'fid:'+uroShownFID;
      uroAddLog('added fid '+uroShownFID+' to ignore list');
      uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
      document.getElementById('_btnUndoLastHide').disabled = false;
      document.getElementById('_btnClearSessionHides').disabled = false;
      uroDiv.style.visibility = 'hidden';
      uroEnableIgnoreListControls();
      wazeMap.events.register("mousemove", null, uroFilterURMarkers5);
   }
   return false;
}

function uroRemoveFromIgnoreList(fid)
{
   var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
   var fidpos = ignorelist.indexOf('fid:'+fid);
   if(fidpos != -1)
   {
      var preFID = ignorelist.slice(0,fidpos);
      ignorelist = ignorelist.slice(fidpos+1);
      fidpos = ignorelist.indexOf('fid:');
      if(fidpos == -1) ignorelist = '';
      else ignorelist = ignorelist.slice(fidpos);
      sessionStorage.UROverview_FID_IgnoreList = preFID + ignorelist;
      uroAddLog('removed fid '+fid+' from ignore list');
      uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
      uroEnableIgnoreListControls();
   }
}

function uroRemoveLastAddedIgnore()
{
   var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
   var fidpos = ignorelist.lastIndexOf('fid:');
   if(fidpos != -1)
   {
      ignorelist = ignorelist.slice(0,fidpos);
      sessionStorage.UROverview_FID_IgnoreList = ignorelist;
      uroAddLog('removed last fid from ignore list');
      uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
      uroEnableIgnoreListControls();
   }
}

function uroRemoveAllIgnores()
{
   sessionStorage.UROverview_FID_IgnoreList = '';
   uroEnableIgnoreListControls();
}


function uroKeywordPresent(desc, keyword)
{
   if(document.getElementById('_cbCaseInsensitive').checked == true) re = RegExp(keyword,'i'); 
   else re = RegExp(keyword);
   if(desc.search(re) == -1) return false;
   else return true;
}


function uroMaskTest()
{
   if(wazeMap.layers[uroMaskLayer].div == null)
   {
      if(uroMaskActive == false)
      {
         uroAddLog('mask layer not found');
         uroMaskActive = true;
      }   
      return true;
   }
   if(wazeMap.layers[uroMaskLayer].div.innerHTML.indexOf('fill="black"') != -1)
   {
      if(uroMaskActive == false)
      {
         uroAddLog('mask layer active');
         uroMaskActive = true;
      }
      return true;
   }
   uroMaskActive = false;
   return false;
}


function uroRefreshUpdateRequestSessions()
{
   var idList = [];
   for (var urID in wazeModel.mapUpdateRequests.objects)
   {
      if(wazeModel.updateRequestSessions.objects[urID] == null) idList.push(urID);
   }
   if(idList.length > 0)
   {
      uroAddLog('grabbing updateRequestSessions with IDs '+idList);
      wazeModel.updateRequestSessions.get(idList);
   }
}

function uroURHasMyComments(fid)
{
   var nComments = wazeModel.updateRequestSessions.objects[fid].comments.length;
   if(nComments == 0) return false;

   for(var cidx=0; cidx<nComments; cidx++)
   {
      if(wazeModel.updateRequestSessions.objects[fid].comments[cidx].userID == uroUserID) return true;
   }
   
   return false;
}
 
function uroAddCommentMarkers(urID, hasMyComments, nComments)
{
   var useDefaultMarker = false;
   
   if((document.getElementById('_cbNativeConvoMarkers').checked) && (uroBetaEditor == false)) useDefaultMarker = true;
   if((document.getElementById('_cbNativeBetaConvoMarkers').checked) && (uroBetaEditor == true)) useDefaultMarker = true;
   
   var divElem = document.getElementById(wazeMap.layers[uroURLayerIdx].id);
   if(divElem.childNodes.length > 0)
   {
      for(var nodeIdx = 0; nodeIdx < divElem.childNodes.length; nodeIdx++)
      {
         if(divElem.childNodes[nodeIdx].getAttribute("data-id") == urID)
         {
            var divHTML = divElem.childNodes[nodeIdx].innerHTML;
            if(divHTML.indexOf('conehead_') == -1)
            {
               divHTML = '';
            }
            
            if(document.getElementById('_cbCommentCount').checked)
            {
               divHTML += '<div style="position:absolute;top:-9px;left:-11px;pointer-events:none;">';
               divHTML += '<img src="https://www.chizzum.com/greasemonkey/images/ur_comment_count.png">';
               divHTML += '</div>';
               divHTML += '<div style="position:absolute;top:-6px;left:-';
               if(nComments < 10) divHTML += '0';
               else if(nComments < 100) divHTML += '3';
               else divHTML += '6';
               divHTML += 'px;font-size:11px;;pointer-events:none;">'+nComments+'</div>';
            }

            if(useDefaultMarker == false)
            {
               divHTML += '<div style="position:absolute;top:-9px;left:18px;pointer-events:none;">';
               if(hasMyComments) divHTML += '<img src="https://www.chizzum.com/greasemonkey/images/ur_own_comment_marker.png">';
               else divHTML += '<img src="https://www.chizzum.com/greasemonkey/images/ur_comment_marker.png">';
               divHTML += '</div>';
               wazeMap.layers[uroURLayerIdx].markers[urID].icon.imageDiv.classList.remove("has-comments")
            }
            else
            {
               wazeMap.layers[uroURLayerIdx].markers[urID].icon.imageDiv.classList.add("has-comments")
            }

            divElem.childNodes[nodeIdx].innerHTML = divHTML;
            return;
         }
      }
   }
}


function uroAddRoadworksMarkers(urID)
{
   var useCustomMarkers = (document.getElementById('_cbCustomRoadworksMarkers').checked);
   
   var divElem = document.getElementById(wazeMap.layers[uroURLayerIdx].id);
   if(divElem.childNodes.length > 0)
   {
      for(var nodeIdx = 0; nodeIdx < divElem.childNodes.length; nodeIdx++)
      {
         if(divElem.childNodes[nodeIdx].getAttribute("data-id") == urID)
         {
            var divHTML = '';
            if(useCustomMarkers == true)
            {
               divHTML += '<div id="conehead_'+urID+'" style="position:absolute;pointer-events:none;">';
               divHTML += '<img src="'+uroIcons[3][0]+'">';
               divHTML += '</div>';
            }
            divElem.childNodes[nodeIdx].innerHTML = divHTML;
            return;
         }
      }
   }
}

function uroChangeRoadworksMarkers(urID,isHighlighted)
{
   if(document.getElementById('conehead_'+urID) != null)
   {
      if(isHighlighted == true)
      {
         document.getElementById('conehead_'+urID).innerHTML = '<img src="'+uroIcons[3][1]+'">';
      }
      else
      {
         document.getElementById('conehead_'+urID).innerHTML = '<img src="'+uroIcons[3][0]+'">';
      }
   }
}


function uroFilterURMarkers()
{
   var mapviewport = document.getElementsByClassName("olMapViewport")[0];
   if(mapviewport == null)
   {
      if(uroNullMapViewport == false)
      {
         uroAddLog('caught null mapviewport');
         uroNullMapViewport = true;
      }
      return;
   }
   uroNullMapViewport = false;
  
   if(document.getElementById('_cbWhiteBackground').checked)
   {
      mapviewport.style.backgroundColor = "#FFFFFF";
   }
   else
   {
      mapviewport.style.backgroundColor = "#555555";
   }
 
     
   if(uroMaskTest() == true) return;

   var camLayer = document.getElementById(uroRootContainer+'_svgRoot');
   if(camLayer == null)
   {
      if(uroNullCamLayer == false)
      {
         uroAddLog('caught null camLayer');
         uroNullCamLayer = true;
      }
      return;
   }
   uroNullCamLayer = false;

   uroRefreshUpdateRequestSessions();

   for (var uroCamObj in wazeModel.cameras.objects)
   {
      var uroCam = wazeModel.cameras.objects[uroCamObj];
      var uroCamStyle = 'visible';
      if(wazeModel.users.objects[uroCam.attributes.createdBy] != null)
      {
         var uroCamCreator = wazeModel.users.objects[uroCam.attributes.createdBy].userName;
         var uroCamCreatorRank = wazeModel.users.objects[uroCam.attributes.createdBy].rank;
      }
      else
      {
         var uroCamCreator = '';
         var uroCamCreatorRank = -1;
      }
      if(wazeModel.users.objects[uroCam.attributes.updatedBy] != null)
      {
         var uroCamUpdater = wazeModel.users.objects[uroCam.attributes.updatedBy].userName;
         var uroCamUpdaterRank = wazeModel.users.objects[uroCam.attributes.updatedBy].rank;
      }
      else
      {
         var uroCamUpdater = '';
         var uroCamUpdaterRank = -1;
      }

      var uroCamApproved = uroCam.attributes.validated;
      var uroCamType = uroCam.attributes.type;


      if(document.getElementById('_cbShowOnlyMyCams').checked == true)
      {
         if((uroUserID != uroCam.attributes.createdBy)&&(uroUserID != uroCam.attributes.updatedBy)) uroCamStyle = 'hidden';
      }

      if((document.getElementById('_cbShowWorldCams').checked == false) || (document.getElementById('_cbShowUSACams').checked == false) || (document.getElementById('_cbShowNonWorldCams').checked == false))
      {
         var posWorld = uroCamCreator.indexOf('world_');
         var posUSA = uroCamCreator.indexOf('usa_');

         if((document.getElementById('_cbShowWorldCams').checked == false) && (posWorld == 0)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowUSACams').checked == false) && (posUSA == 0)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowNonWorldCams').checked == false) && (posWorld != 0) && (posUSA != 0)) uroCamStyle = 'hidden';
      }

      if((document.getElementById('_cbShowApprovedCams').checked == false) || (document.getElementById('_cbShowNonApprovedCams').checked == false))
      {
         if((document.getElementById('_cbShowApprovedCams').checked == false) && (uroCamApproved == true)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowNonApprovedCams').checked == false) && (uroCamApproved == false)) uroCamStyle = 'hidden';
      }

      if((document.getElementById('_cbShowNonApprovedCams').checked == true) && (uroCamApproved == false))
      {
         if(((document.getElementById('_cbShowOlderCreatedNonApproved').checked == true)) && (uroGetCameraAge(uroCam,1) <= document.getElementById('_inputCameraMinCreatedDays').value)) uroCamStyle = 'hidden';
         if(((document.getElementById('_cbShowOlderUpdatedNonApproved').checked == true)) && (uroGetCameraAge(uroCam,0) <= document.getElementById('_inputCameraMinUpdatedDays').value)) uroCamStyle = 'hidden';
      }

      if((document.getElementById('_cbShowSpeedCams').checked == false) || (document.getElementById('_cbShowRedLightCams').checked == false) || (document.getElementById('_cbShowDummyCams').checked == false))
      {
         if((document.getElementById('_cbShowSpeedCams').checked == false) && (uroCamType == 2)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowRedLightCams').checked == false) && (uroCamType == 4)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowDummyCams').checked == false) && (uroCamType == 3)) uroCamStyle = 'hidden';
      }

      if(document.getElementById('_cbShowSpeedCams').checked == true)
      {
         if((document.getElementById('_cbShowIfMPHSpeedSet').checked == false) && (uroIsCameraSpeedValid(uroCam) == 1)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowIfNoSpeedSet').checked == false) && (uroIsCameraSpeedValid(uroCam) == 0)) uroCamStyle = 'hidden';
         if((document.getElementById('_cbShowIfKPHSpeedSet').checked == false) && (uroIsCameraSpeedValid(uroCam) == -1)) uroCamStyle = 'hidden';
      }

      if(document.getElementById('_cbHideCreatedByMe').checked == true)
      {
         if(uroUserID == uroCam.attributes.createdBy) uroCamStyle = 'hidden';
      }
      if((document.getElementById('_cbHideCreatedByRank0').checked == true) && (uroCamCreatorRank == 0)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideCreatedByRank1').checked == true) && (uroCamCreatorRank == 1)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideCreatedByRank2').checked == true) && (uroCamCreatorRank == 2)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideCreatedByRank3').checked == true) && (uroCamCreatorRank == 3)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideCreatedByRank4').checked == true) && (uroCamCreatorRank == 4)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideCreatedByRank5').checked == true) && (uroCamCreatorRank == 5)) uroCamStyle = 'hidden';

      if(document.getElementById('_cbHideUpdatedByMe').checked == true)
      {
         if(uroUserID == uroCam.attributes.updatedBy) uroCamStyle = 'hidden';
      }
      if((document.getElementById('_cbHideUpdatedByRank0').checked == true) && (uroCamUpdaterRank == 0)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideUpdatedByRank1').checked == true) && (uroCamUpdaterRank == 1)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideUpdatedByRank2').checked == true) && (uroCamUpdaterRank == 2)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideUpdatedByRank3').checked == true) && (uroCamUpdaterRank == 3)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideUpdatedByRank4').checked == true) && (uroCamUpdaterRank == 4)) uroCamStyle = 'hidden';
      if((document.getElementById('_cbHideUpdatedByRank5').checked == true) && (uroCamUpdaterRank == 5)) uroCamStyle = 'hidden';

      if((document.getElementById('_cbHideCWLCams').checked == true) && (uroIsCamOnWatchList(uroCam.fid) != -1)) uroCamStyle = 'hidden';

      var uroCamGeometryID = uroCam.geometry.id;
      if(camLayer.getElementById(uroCamGeometryID) != null)
      {
         camLayer.getElementById(uroCamGeometryID).style.visibility = uroCamStyle;
      }
   }

   for (var urobj in wazeModel.mapUpdateRequests.objects)
   {
      var ureq = wazeModel.mapUpdateRequests.objects[urobj];
      var urStyle = 'visible';
      var cryosphere_link = false;
      var wazeauto_ur = false;
      var ukroadworks_ur = false;
      var hasMyComments = false;
      var nComments = 0;
      var commentDaysOld = -1;

      var desc = '';
      if(ureq.attributes.description != null) desc = ureq.attributes.description;

      // check UR against current session ignore list...
      if(uroIsOnIgnoreList(ureq.fid)) urStyle = 'hidden';

      // check against closed/not identified filtering if enabled...
      if(document.getElementById('_cbFilterSolved').checked == true)
      {
         if(ureq.attributes.resolution == 0) urStyle = 'hidden';
      }
      if(document.getElementById('_cbFilterUnidentified').checked == true)
      {
         if(ureq.attributes.resolution == 1) urStyle = 'hidden';
      }
      
      if((ureq.attributes.resolvedOn != null) && (document.getElementById('_cbFilterClosedUR').checked == true))
      {
         urStyle = 'hidden';
      }

      if(urStyle == 'visible')
      {
         // check UR against keyword filtering if enabled...
         if(document.getElementById('_cbEnableKeywordMustBePresent').checked == true)
         {
            if(!uroKeywordPresent(desc,document.getElementById('_textKeywordPresent').value)) urStyle = 'hidden';
         }
         if(document.getElementById('_cbEnableKeywordMustBeAbsent').checked == true)
         {
            if(uroKeywordPresent(desc,document.getElementById('_textKeywordAbsent').value)) urStyle = 'hidden';
         }
      }

      if(urStyle == 'visible')
      {
         // do age-based filtering if enabled
         if(document.getElementById('_cbEnableMinAgeFilter').checked == true)
         {
            if(uroGetURAge(ureq,0) < document.getElementById('_inputFilterMinDays').value) urStyle = 'hidden';
         }
         if(document.getElementById('_cbEnableMaxAgeFilter').checked == true)
         {
            if(uroGetURAge(ureq,0) > document.getElementById('_inputFilterMaxDays').value) urStyle = 'hidden';
         }
      }
      
      if(urStyle == 'visible')
      {
         // do comments/following filtering
         if(wazeModel.updateRequestSessions.objects[ureq.fid] != null)
         {
            nComments = wazeModel.updateRequestSessions.objects[ureq.fid].comments.length;
            var commentDaysOld = -1;
            
            
            if(document.getElementById('_cbEnableMinCommentsFilter').checked == true)
            {
               if(nComments < document.getElementById('_inputFilterMinComments').value) urStyle = 'hidden';
            }
            if(document.getElementById('_cbEnableMaxCommentsFilter').checked == true)
            {
               if(nComments > document.getElementById('_inputFilterMaxComments').value) urStyle = 'hidden';
            }
            
              
            if(nComments > 0)
            {
               var reporterIsLastCommenter = false;
               if(wazeModel.updateRequestSessions.objects[ureq.fid].comments[nComments-1].userID == -1) reporterIsLastCommenter = true;
               
               if(document.getElementById('_cbHideIfReporterLastCommenter').checked == true)
               {
                  if(reporterIsLastCommenter == true) urStyle = 'hidden';
               }
               else if(document.getElementById('_cbHideIfReporterNotLastCommenter').checked == true)
               {
                  if(reporterIsLastCommenter == false) urStyle = 'hidden';
               }
               
               hasMyComments = uroURHasMyComments(ureq.fid);
               if(hasMyComments == false)
               { 
                  if(document.getElementById('_cbHideAnyComments').checked == true) urStyle = 'hidden';
                  if(document.getElementById('_cbHideIfNotLastCommenter').checked == true) urStyle = 'hidden';
               }
               else
               {
                  if(document.getElementById('_cbHideMyComments').checked == true) urStyle = 'hidden';
                  
                  var userIsLastCommenter = false;
                  if(wazeModel.updateRequestSessions.objects[ureq.fid].comments[nComments-1].userID == uroUserID) userIsLastCommenter = true;
                  
                  if(document.getElementById('_cbHideIfLastCommenter').checked == true)
                  {
                     if(userIsLastCommenter == true) urStyle = 'hidden';
                  }  
                  else if(document.getElementById('_cbHideIfNotLastCommenter').checked == true)
                  {
                     if(userIsLastCommenter == false) urStyle = 'hidden';
                  }
               }
               commentDaysOld = uroGetCommentAge(wazeModel.updateRequestSessions.objects[ureq.fid].comments[nComments-1]);
               if((document.getElementById('_cbEnableCommentAgeFilter').checked == true) && (commentDaysOld != -1))
               {
                  if(document.getElementById('_inputFilterCommentDays').value < commentDaysOld) urStyle = 'hidden';
               }
               if((document.getElementById('_cbEnableCommentAgeFilter2').checked == true) && (commentDaysOld != -1))
               {
                  if(document.getElementById('_inputFilterCommentDays2').value > commentDaysOld) urStyle = 'hidden';
               }            
            }
            
            
            if(wazeModel.updateRequestSessions.objects[ureq.fid].isFollowing == true)
            {
               if(document.getElementById('_cbHideMyFollowed').checked == true) urStyle = 'hidden';
            }
            else   
            {            
               if(document.getElementById('_cbHideMyUnfollowed').checked == true) urStyle = 'hidden';
            }              
         }
      }

      if(urStyle == 'visible')
      {
         // for type-based filtering, we need to handle Petrol Station Checker URs first - these (currently)
         // appear as URs of either general error or undefined type, and so can't be detected just by type alone.
         if(desc.indexOf('cryosphere') != -1)
         {
            cryosphere_link = true;
         }
         // Waze automatic URs are next - these always (?) get inserted as General Error URs, so we can't filter
         // them by type either.
         else if(desc.indexOf('Waze Automatic:') != -1)
         {
            wazeauto_ur = true;
         }
         // Finally (for now?) UK roadworks URs - provided the editor setting the UR has abided by the guidelines
         // in the UK forum, the description should always include the text '[ROADWORKS]'...
         else if(desc.indexOf('[ROADWORKS]') != -1)
         {
            ukroadworks_ur = true;
         }

         if(cryosphere_link == true)
         {
            if(document.getElementById('_cbFilterCryosphere').checked == true) urStyle = 'hidden';
         }
         else if(wazeauto_ur == true)
         {
            if(document.getElementById('_cbFilterWazeAuto').checked == true) urStyle = 'hidden';
         }
         else if(ukroadworks_ur == true)
         {
            if(document.getElementById('_cbFilterRoadworks').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 6)
         {
            if(document.getElementById('_cbFilterIncorrectTurn').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 7)
         {
            if (document.getElementById('_cbFilterIncorrectAddress').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 8)
         {
            if(document.getElementById('_cbFilterIncorrectRoute').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 9)
         {
            if(document.getElementById('_cbFilterMissingRoundabout').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 10)
         {
            if(document.getElementById('_cbFilterGeneralError').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 11)
         {
            if(document.getElementById('_cbFilterTurnNotAllowed').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 12)
         {
            if(document.getElementById('_cbFilterIncorrectJunction').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 13)
         {
            if(document.getElementById('_cbFilterMissingBridgeOverpass').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 14)
         {
            if(document.getElementById('_cbFilterWrongDrivingDirection').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 15)
         {
            if(document.getElementById('_cbFilterMissingExit').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 16)
         {
            if(document.getElementById('_cbFilterMissingRoad').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 18)
         {
            if(document.getElementById('_cbFilterMissingLandmark').checked == true) urStyle = 'hidden';
         }
         else if(ureq.attributes.type == 19)
         {
            if(document.getElementById('_cbFilterBlockedRoad').checked == true) urStyle = 'hidden';
         }
         else if(document.getElementById('_cbFilterUndefined').checked == true) urStyle = 'hidden';
         
         if(document.getElementById('_cbInvertURFilter').checked == true)
         {
           if(urStyle == 'hidden') urStyle = 'visible';
           else urStyle = 'hidden';
         }
      }
      wazeMap.layers[uroURLayerIdx].markers[urobj].icon.imageDiv.style.visibility = urStyle;
      if(urStyle != 'hidden')
      {
         if(ukroadworks_ur == true)
         {
            uroAddRoadworksMarkers(ureq.fid);
         }
         if(nComments > 0)
         {
            uroAddCommentMarkers(ureq.fid, hasMyComments, nComments);
         }
      }
   }
   
   
   for (var urobj in wazeModel.problems.objects)
   {
      var problem = wazeModel.problems.objects[urobj];
      var problemStyle = 'visible';

      // check problem against current session ignore list...
      if(uroIsOnIgnoreList(problem.fid)) problemStyle = 'hidden';

      // check against closed/not identified filtering if enabled...
      var problem_marker_img = '';
      if(problem.geometry.id != null)
      {
         if(document.getElementById(problem.geometry.id) != null)
         {
            problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
            if(document.getElementById('_cbMPFilterSolved').checked == true)
            {
               if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
            }
            if(document.getElementById('_cbMPFilterUnidentified').checked == true)
            {
               if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
            }
         }
      }
      
      if((problem.attributes.resolvedOn != null) && (document.getElementById('_cbMPFilterClosed').checked == true))
      {
         problemStyle = 'hidden';
      }
            
      if(problemStyle == 'visible')
      {
         if(problem.attributes.problemType == 101)
         {
            if(document.getElementById('_cbMPFilterDrivingDirectionMismatch').checked == true) problemStyle = 'hidden';
         }  
         else if(problem.attributes.problemType == 102)
         {
            if(document.getElementById('_cbMPFilterMissingJunction').checked == true) problemStyle = 'hidden';
         }  
         else if(problem.attributes.problemType == 103)
         {
            if(document.getElementById('_cbMPFilterMissingRoad').checked == true) problemStyle = 'hidden';
         }  
         else if(problem.attributes.problemType == 104)
         {
            if(document.getElementById('_cbMPFilterCrossroadsJunctionMissing').checked == true) problemStyle = 'hidden';
         }  
         else if(problem.attributes.problemType == 105)
         {
            if(document.getElementById('_cbMPFilterRoadTypeMismatch').checked == true) problemStyle = 'hidden';
         }  
         else if(problem.attributes.problemType == 106)
         {
            if(document.getElementById('_cbMPFilterRestrictedTurn').checked == true) problemStyle = 'hidden';
         }
         else if(document.getElementById('_cbMPFilterUnknownProblem').checked == true) problemStyle = 'hidden';
             
         if(document.getElementById('_cbInvertMPFilter').checked == true)
         {
            if(problemStyle == 'hidden') problemStyle = 'visible';
            else problemStyle = 'hidden';
         }
        
              
         if(problem.attributes.weight <= 3)
         {
            if(document.getElementById('_cbMPFilterLowSeverity').checked == true) problemStyle = 'hidden';
         }  
         else if(problem.attributes.weight <= 7)
         {
            if(document.getElementById('_cbMPFilterMediumSeverity').checked == true) problemStyle = 'hidden';
         }
         else if(document.getElementById('_cbMPFilterHighSeverity').checked == true) problemStyle = 'hidden'; 
      }  
      
      wazeMap.layers[uroProblemLayerIdx].markers[urobj].icon.imageDiv.style.visibility = problemStyle;
   }

   for (var urobj in wazeModel.turnProblems.objects)
   {
      var problem = wazeModel.turnProblems.objects[urobj];
      var problemStyle = 'visible';

      // check problem against current session ignore list...
      if(uroIsOnIgnoreList(problem.fid)) problemStyle = 'hidden';

      // check against closed/not identified filtering if enabled...
      var problem_marker_img = '';
      if(problem.geometry.id != null)
      {
         if(document.getElementById(problem.geometry.id) != null)
         {
            problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
            if(document.getElementById('_cbMPFilterSolved').checked == true)
            {
               if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
            }
            if(document.getElementById('_cbMPFilterUnidentified').checked == true)
            {
               if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
            }
         }
      }

      if((problem.attributes.resolvedOn != null) && (document.getElementById('_cbMPFilterClosed').checked == true))
      {
         problemStyle = 'hidden';
      }
      
      if(document.getElementById('_cbMPFilterTurnProblem').checked == true) problemStyle = 'hidden';
             
      if(document.getElementById('_cbInvertMPFilter').checked == true)
      {
         if(problemStyle == 'hidden') problemStyle = 'visible';
         else problemStyle = 'hidden';
      }
                  
      wazeMap.layers[uroProblemLayerIdx].markers[urobj].icon.imageDiv.style.visibility = problemStyle;
   }
}


function uroFilterURMarkers2a()
{
   uroAddLog('catch UR layer change');
   uroFilterURMarkers();
}
function uroFilterURMarkers2b()
{
   uroAddLog('catch UR layer add');
   uroFilterURMarkers();
}
function uroFilterURMarkers2c()
{
   uroAddLog('catch UR layer remove');
   uroFilterURMarkers();
}
function uroFilterURMarkers3a()
{
   uroAddLog('catch camera layer change');
   uroFilterURMarkers();
}
function uroFilterURMarkers3b()
{
   uroAddLog('catch camera layer add');
   uroFilterURMarkers();
}
function uroFilterURMarkers3c()
{
   uroAddLog('catch camera layer remove');
   uroFilterURMarkers();
}
function uroFilterURMarkers4a()
{
   uroAddLog('catch problems layer change');
   uroFilterURMarkers();
}
function uroFilterURMarkers4b()
{
   uroAddLog('catch problems layer add');
   uroFilterURMarkers();
}
function uroFilterURMarkers4c()
{
   uroAddLog('catch problems layer remove');
   uroFilterURMarkers();
}
function uroFilterURMarkers5()
{
   uroAddLog('catch mouse move');
   wazeMap.events.unregister('mousemove',null,uroFilterURMarkers5);
   uroFilterURMarkers();
}


function uroDeleteObject()
{
   uroAddLog('delete camera ID '+uroShownFID);
   if(wazeModel.cameras.objects[uroShownFID] == null) 
   {
      uroAddLog('camera object not found...');
      return false;
   }   

   uroRemoveCamFromWatchList();

   deleteAction = new Waze.Action.DeleteObject(wazeModel.cameras.objects[uroShownFID], null);
   wazeModel.actionManager.add(deleteAction);
   uroExitPopup();
   return false;
}


function uroGetUserNameAndRank(userID)
{
   var userName = wazeModel.users.objects[userID].userName;
   var userLevel = wazeModel.users.objects[userID].rank + 1;
   return userName + ' (' + userLevel + ')';
}
                     
                     
function uroNewLookHighlightedItemsCheck()
{
   if(uroMaskTest() == true) return;

   if(OpenLayers == null) 
   {
      if(uroNullOpenLayers == false)
      {
         uroAddLog('caught null OpenLayers');
         uroNullOpenLayers = true;
      }
      return;
   }
   uroNullOpenLayers = false;

   var rc = document.getElementById(uroRootContainer);
   if(rc == null) 
   {
      if(uroNullRootContainer == false)
      {
         uroAddLog('caught null rootContainer');
         uroNullRootContainer = true
      }
      return;
   }
   uroNullRootContainer = false;
   
   if(wazeMap.layers[uroURLayerIdx] == null) 
   {
      if(uroNullURLayer == false)
      {
         uroAddLog('caught null UR layer');
         uroNullURLayer = true;
      }
      return;
   }
   uroNullURLayer = false;

   if(wazeMap.layers[uroProblemLayerIdx] == null) 
   {
      if(uroNullProblemLayer == false)
      {
         uroAddLog('caught null problem layer');
         uroNullProblemLayer = true;
      }
      return;
   }
   uroNullProblemLayer = false;

   var currentItems = rc.getElementsByTagName('g');

   var result = '';
   var rw;
   var rh;
   var doPopUp = false;
   var popup_loc = new OpenLayers.LonLat(0,0);
   
   var objHasIgnoreLink = false;
   var objHasDeleteLink = false;

   var markerx = null;
   var markery = null;
   var offsetx = rc.getBoundingClientRect().left - rc.offsetLeft;
   var offsety = rc.getBoundingClientRect().top - rc.offsetTop;
   
   var objHasIgnoreLink = false;
   var objHasDeleteLink = false;
   var objHasAddWatchLink = false;
   var objHasRemoveWatchLink = false;
   var objHasUpdateWatchLink = false;

   // look for URs and problems
   var idSrc = null;
   var divIdx = -1;
   var isUR = false;
   var isProblem = false;
   var isTurnProb = false;

   if(document.getElementById('_cbInhibitURPopup').checked == false)
   {
      for(var marker in wazeMap.layers[uroURLayerIdx].markers)
      {
         markerObj = wazeMap.layers[uroURLayerIdx].markers[marker];
         markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
         markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
         markerPos = markerPos.split(' ');
         markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));

         var hovered = false;
         
         // fix for new WME - what possessed the Waze programmers to place the highlighted icon imagery at
         // seemingly random offsets within the iconstrip, rather than having them all grouped neatly together
         // as in previous versions of WME, is yet another design decision that seems to have been made purely
         // for the sake of changing stuff around, rather than for any obviously good reason...
         if(markerImg.indexOf('problems-se224ab677e.png') != -1)
         {
            if((markerPos == -40) || (markerPos == -160) || (markerPos == -200) || (markerPos == -240)) hovered = true;
         }
         else
         {
            if(markerPos > -200) hovered = true;
         }
         if(hovered == true)
         {
            idSrc = markerObj.model.fid;
            markerx = markerObj.icon.imageDiv.offsetLeft;
            markery = markerObj.icon.imageDiv.offsetTop;
            isUR = true;
            uroAddLog('hover over UR ID '+idSrc);
            
            if(idSrc != uroCrushedConeFID)
            {
               if(uroCrushedConeFID != null)
               {
                  uroChangeRoadworksMarkers(uroCrushedConeFID,false);
                  uroCrushedConeFID = null;
               }
               var ureq = wazeModel.mapUpdateRequests.objects[idSrc];
               var desc = '';
               if(ureq.attributes.description != null) 
               {
                  desc = ureq.attributes.description;
                  if(desc.indexOf('[ROADWORKS]') != -1)
                  {
                     uroCrushedConeFID = idSrc;
                     uroChangeRoadworksMarkers(idSrc,hovered);
                  }
               }
            }
         }
      }
      
      if((idSrc == null) && (uroCrushedConeFID != null))
      {
         uroChangeRoadworksMarkers(uroCrushedConeFID,false);
         uroCrushedConeFID = null;
      }
   }
   
   if((isUR == false) && (document.getElementById('_cbInhibitMPPopup').checked == false))
   {
      for(var marker in wazeMap.layers[uroProblemLayerIdx].markers)
      {
         markerObj = wazeMap.layers[uroProblemLayerIdx].markers[marker];
         markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
         markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
         markerPos = markerPos.split(' ');
         markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
         
         var hovered = false;
         if(markerImg.indexOf('problems-se224ab677e.png') != -1)
         {
            if((markerPos == -320) || (markerPos == -560) || (markerPos == -520) || (markerPos == -440)) hovered = true;
         }
         else
         {
            if(markerPos > -200) hovered = true;
         }
         if(hovered == true)
         {
            idSrc = markerObj.model.fid;
            markerx = markerObj.icon.imageDiv.offsetLeft;
            markery = markerObj.icon.imageDiv.offsetTop;
            isProblem = true;
            uroAddLog('hover over problem ID '+idSrc);            
         }
      }
   }

   if (idSrc != null)
   {
      if(isUR) var ureq = wazeModel.mapUpdateRequests.objects[idSrc];
      else if(isProblem) 
      {
         var ureq = wazeModel.problems.objects[idSrc];
         if(ureq == undefined)
         {
            var ureq = wazeModel.turnProblems.objects[idSrc];
            if(ureq != undefined) isTurnProb = true;
         }
      }
      uroFID = ureq.fid;
      doPopUp = true;
   }
   else
   {
      uroFID = -1;
   }
   if((uroFID != uroShownFID) && (uroFID != -1))
   {
      if(isUR)
      {
         uroAddLog('building popup for UR '+idSrc);
         result = '<b>Update Request ('+idSrc+'): ' + I18n.translations[I18n.locale].update_requests.types[ureq.attributes.type] + '</b><br>';
         if(ureq.attributes.description != null)
         {
            var desc = ureq.attributes.description;
            if(desc != "null")
            {
               var linkStartPos = desc.indexOf('http://');
               if(linkStartPos == -1) linkStartPos = desc.indexOf('https://');
               if(linkStartPos != -1)
               {
                  var descPreLink = desc.slice(0,linkStartPos);
                  var descURL = desc.slice(linkStartPos);
                  var linkEndPos = descURL.indexOf(' ');
                  var descPostLink = '';
                  if(linkEndPos != -1)
                  {
                     descPostLink = descURL.slice(linkEndPos);
                     descURL = descURL.slice(0,linkEndPos);
                  }
                  var linkTarget = '';
                  if(descURL.indexOf('cryosphere') != -1) linkTarget = '_cryosphere';
                  else if(descURL.indexOf('waze.com') != -1) linkTarget = '_wazeUR';
                  desc = descPreLink + '<a target="'+linkTarget+'" href="'+descURL+'">here</a>' + descPostLink;
               }
               result += desc + '<br>';
            }
         }

         var uroDaysOld = uroGetURAge(ureq,0);
         if(uroDaysOld != -1)
         {
            result += '<i>Submitted ' + uroParseDaysAgo(uroDaysOld) + ' ';
            if(ureq.attributes.guestUserName != null)
            {
               result += 'via Livemap';
               if(ureq.attributes.guestUserName != '')
               {
                 result += ' by '+ureq.attributes.guestUserName;
               }
            }
            result += '</i>';
         }
         if(ureq.attributes.resolvedOn != null)
         {
            var uroDaysResolved = uroGetURAge(ureq,1);
            if(uroDaysResolved != -1)
            {
               result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
               if(ureq.attributes.resolvedBy != null)
               {
                  result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
               }
               result += '</i>';
            }
         }
         
         if(wazeModel.updateRequestSessions.objects[ureq.fid] != null)
         {
            var hasMyComments = uroURHasMyComments(ureq.fid);
            var nComments = wazeModel.updateRequestSessions.objects[ureq.fid].comments.length;
            result += '<br>' + nComments + ' comment';
            if(nComments != 1) result += 's';
            if((hasMyComments == false) && (nComments > 0)) result += ' (none by me)';
            if(nComments > 0)
            {
               var commentDaysOld = uroGetCommentAge(wazeModel.updateRequestSessions.objects[ureq.fid].comments[nComments-1]);
               if(commentDaysOld != -1)
               {
                  result += ', last update '+uroParseDaysAgo(commentDaysOld);
               }
            }
         }
   
      }
      else if(isProblem)
      {
         uroAddLog('building popup for problem '+idSrc);
         if(isTurnProb) result = '<b>Turn Problem ('+idSrc+'): ' + I18n.translations[I18n.locale].problems.types["turn"].title;
         else
         {
            result = '<b>Map Problem ('+idSrc+'): ';
            if(I18n.translations[I18n.locale].problems.types[ureq.attributes.problemType] == undefined) result += 'Unknown problem type ('+ureq.attributes.problemType+')';
            else result += I18n.translations[I18n.locale].problems.types[ureq.attributes.problemType].title;
         }
         result += '</b><br>';
         if(ureq.attributes.resolvedOn != null)
         {
            var uroDaysResolved = uroGetURAge(ureq,1);
            if(uroDaysResolved != -1)
            {
               result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
               if(ureq.attributes.resolvedBy != null)
               {
                  result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
               }
               result += '</i>';
            }
         }         
      }

      // add "open new WME tab" link
      var urPos=new OpenLayers.LonLat(ureq.geometry.x,ureq.geometry.y);
      urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
      var urLink = document.location.href;
      if(urLink.indexOf('&layers') != -1)
      {
         var urLayers = urLink.substr(urLink.indexOf('&layers'));
         if(urLayers.indexOf('&show') != -1) urLayers = urLayers.substr(0,urLayers.indexOf('&show'));
      }
      else var urLayers = '';      
      urLink = urLink.substr(0,urLink.indexOf('?zoom'));      
      if(isUR) urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers+'&showur='+idSrc+'&endshow';
      else if(isTurnProb) urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers+'&showturn='+idSrc+'&endshow';
      else if(isProblem) urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers+'&showproblem='+idSrc+'&endshow';      
      result += '<hr><ul><li><a href="'+urLink+'" target="_urTab">Open in new WME tab</a>';
      // add "open new livemap tab" link
      var lmLink = null;
      if(document.getElementsByClassName("waze-header-menu").length == 0)
      {      
         uroAddLog('Livemap link in livemap element');
         lmLink = document.getElementById('livemap').href;     
      }
      else
      {
         uroAddLog('Livemap link in header menu, locating...');
         var menuItems = document.getElementsByClassName("waze-header-menu")[0];
         for(var miloop = 0; miloop<menuItems.childElementCount; miloop++)
         {
            if(menuItems.children[miloop].innerHTML.indexOf('livemap') != -1)
            {
               uroAddLog('found link in menu entry '+miloop);
               lmLink = menuItems.children[miloop].getElementsByTagName('a')[0].href;
               uroAddLog(lmLink);
            }
         }  
      }
      if(lmLink != null)
      {  
         var zpos = lmLink.indexOf('?');      
         if(zpos > -1) lmLink = lmLink.substr(0,zpos);      
         lmLink += '?zoom=17&lat='+urPos.lat+'&lon='+urPos.lon+'&layers=BTTTT';      
         result += '<li><a href="'+lmLink+'" target="_lmTab">Open in new livemap tab</a>';      
      }
      // add "ignore for this session" link
      result += '<li><a href="#" id="_addtoignore">Hide for this session</a></ul>';      
      objHasIgnoreLink = true;      
      //uroFID = ureq.fid;
   }

   // look for cameras
   var vroot = uroCamvroot;
   if((currentItems[vroot] != null) && (doPopUp == false) && (document.getElementById('_cbInhibitCamPopup').checked == false))
   {
      // check for a highlighted camera...
      var currentCameras = currentItems[vroot].getElementsByTagName('image');
      var camIndex = -1;
      for(var loop=0;loop<currentCameras.length;loop++)
      {
          if(currentCameras[loop].getAttribute('width') == 44) camIndex = loop;
      }

      if(camIndex != -1)
      {
         var idSrc = currentCameras[camIndex].id;
         markerx = Math.round(currentCameras[camIndex].getBoundingClientRect().left - offsetx);
         markery = Math.round(currentCameras[camIndex].getBoundingClientRect().bottom - offsety - 25);
         for (var urobj in wazeModel.cameras.objects)
         {
            var ureq = wazeModel.cameras.objects[urobj];
            // test isSelected() so that we only do overview data on cameras that are being hovered over
            if((idSrc == ureq.geometry.id)&&(ureq.isSelected() == false))
            {
               doPopUp = true;
               //if(uroPopupShown == false)
               {
                  uroFID = ureq.fid;
                  uroAddLog('generating popup for camera '+uroFID);
                  result += '<b>Camera: ' + ureq.TYPES[ureq.attributes.type] + '</b><br>';
                  result += 'ID: '+uroFID+'<br>';
                  result += 'Created by ';
                  if(wazeModel.users.get(ureq.attributes.createdBy) != null)
                  {
                     userID = ureq.attributes.createdBy;
                     result += uroGetUserNameAndRank(userID);
                  }
                  else result += 'unknown';
                  result += ', ';
                  var camAge = uroGetCameraAge(ureq,1);
                  if(camAge != -1)
                  {
                     result += uroParseDaysAgo(camAge);
                  }
                  else result += 'unknown days ago';

                  result += '<br>Updated by ';
                  if(wazeModel.users.get(ureq.attributes.updatedBy) != null)
                  {
                     userID = ureq.attributes.updatedBy;
                     userName = wazeModel.users.objects[userID].userName;
                     userLevel = wazeModel.users.objects[userID].rank + 1;
                     result += userName + ' (' + userLevel + ')';
                  }
                  else result += 'unknown';
                  result += ', ';
                  var camAge = uroGetCameraAge(ureq,0);
                  if(camAge != -1)
                  {
                     result += uroParseDaysAgo(camAge);
                  }
                  else result += 'unknown days ago';
                  
                  result += '<br>Speed data: ';

                  if(ureq.attributes.speed != null)
                  {
                     result += ureq.attributes.speed + 'km/h';
                     var speedInMPH = Math.round(ureq.attributes.speed / 1.609);
                     result += ' (' + speedInMPH + 'mph';
                     if((speedInMPH % 10) != 0) result += ' - not valid?';
                     result += ')</i>';
                  }
                  else result += 'unknown';

                  var uid = wazeModel.loginManager.getLoggedInUser().id;
                  
                  result += '<hr><ul>';
                  if(uroIsCamOnWatchList(uroFID) != -1)
                  {
                     result += '<li><a href="#" id="_updatewatchlist">Update watchlist entry</a>';
                     result += '<li><a href="#" id="_removefromwatchlist">Remove from watchlist</a>';
                     objHasUpdateWatchLink = true;
                     objHasRemoveWatchLink = true;
                  }
                  else
                  {
                     result += '<li><a href="#" id="_addtowatchlist">Add to watchlist</a>';
                     objHasAddWatchLink = true;
                  }

                  if(ureq.attributes.permissions != 0)
                  {
                     result += '<li><a href="#" id="_deleteobject">Delete Camera</a>';
                     objHasDeleteLink = true;
                  }
                  result += '</ul>';
               }
            }
         }
      }
   }


   if(doPopUp == true)
   {
      uroPopupX = markerx + offsetx + 15;
      uroPopupY = markery + offsety + 25;
      if(uroFID != uroShownFID)
      {
         uroAddLog('FID mismatch, show popup: '+uroFID+'/'+uroShownFID);
         uroShownFID = uroFID;
         uroPopupShown = false;
      }

      if(uroPopupShown == false)
      {
         uroAddLog('display popup at '+uroPopupX+','+uroPopupY);
         uroPopupShown = true;
         uroDiv.innerHTML = result;
         if((uroFID != -1) && (objHasIgnoreLink == true))
         {
            document.getElementById('_addtoignore').addEventListener('click', uroAddToIgnoreList, true);
         }
         if(objHasDeleteLink == true)
         {
            document.getElementById('_deleteobject').addEventListener('click', uroDeleteObject, true);
         }  
         if(objHasRemoveWatchLink == true)
         {
            document.getElementById('_removefromwatchlist').addEventListener('click', uroRemoveCamFromWatchList, true);
         }  
         if(objHasAddWatchLink == true)
         {
            document.getElementById('_addtowatchlist').addEventListener('click', uroAddCamToWatchList, true);
         }
         if(objHasUpdateWatchLink == true)
         {
            document.getElementById('_updatewatchlist').addEventListener('click', uroUpdateCamWatchList, true);
         }  
         rw = parseInt(uroDiv.clientWidth);
         rh = parseInt(uroDiv.clientHeight);

         if(rw > (window.innerWidth / 2)) rw = (window.innerWidth / 2);
         if(rh > (window.innerHeight / 2)) rh = (window.innerHeight / 2);

         if((uroPopupX + rw) > window.innerWidth)
         {
            uroPopupX = window.innerWidth - (rw + 50);
            if(uroPopupX < 0) uroPopupX = 0;
         }
         if((uroPopupY + rh) > window.innerHeight)
         {
            uroPopupY = window.innerHeight - (rh + 50);
            if(uroPopupY < 0) uroPopupY = 0;
         }
         
         var popupX1 = (uroPopupX - offsetx);
         var popupX2 = (popupX1 + rw);
         var popupY1 = (uroPopupY - offsety);
         var popupY2 = (popupY1 + rh);
         console.log(popupX1+' '+popupX2+' '+popupY1+' '+popupY2+' '+markerx+' '+markery);
         if((popupX1 < markerx) && (popupX2 > markerx) && (popupY1 < markery) && (popupY2 > markery))
         {
            uroPopupY = (markery + offsety - rh);
         }

         uroDiv.style.top = uroPopupY+'px';
         uroDiv.style.left = uroPopupX+'px';
         uroDiv.clientWidth = rw+'px';
         uroDiv.clientHeight = rh+'px';
         uroDiv.style.visibility = 'visible';
      }
      uroPopupTimer = -1;
   }
   else
   {
      if(uroPopupTimer == -1)
      {
         uroPopupTimer = 2;
      }
   }

   if(uroPopupTimer > 0)
   {
      if(uroMouseInPopup == false) uroPopupTimer--;
   }
   if(uroPopupTimer == 0)
   {
      uroDiv.style.visibility = 'hidden';
      uroPopupShown = false;
      uroPopupTimer = -2;
      uroShownFID = -1;
   }
}

function uroRestyleWMETabs()
{
   var navTabs = document.getElementById(uroUserTabId).children[1].children;
   for(var loop = 0; loop<navTabs.length; loop++)
   {
      navTabs[loop].children[0].style.padding = "4px";
   }
   setTimeout(uroRestyleWMETabs,1000);
}

function uroExclusiveCB()
{
   cbChecked = document.getElementById(this.id).checked;
   
   if(cbChecked == true)
   {
      if(this.id == '_cbHideMyComments') document.getElementById('_cbHideAnyComments').checked = false;
      if(this.id == '_cbHideAnyComments') document.getElementById('_cbHideMyComments').checked = false;
      if(this.id == '_cbHideIfLastCommenter') document.getElementById('_cbHideIfNotLastCommenter').checked = false;
      if(this.id == '_cbHideIfNotLastCommenter') document.getElementById('_cbHideIfLastCommenter').checked = false;
      if(this.id == '_cbHideIfReporterLastCommenter') document.getElementById('_cbHideIfReporterNotLastCommenter').checked = false;
      if(this.id == '_cbHideIfReporterNotLastCommenter') document.getElementById('_cbHideIfReporterLastCommenter').checked = false;
   }
}

function uroTenthSecondTick()
{
   if(uroSetupListeners)
   {
      if(loginManager.isLoggedIn())
      {
         uroSetupListeners = false;
         
         // filter markers when the marker objects are modified (this happens whenever WME needs to load fresh marker data
         // due to having panned/zoomed the map beyond the extents of the previously loaded data)
         wazeModel.mapUpdateRequests.events.register("objectschanged", null, uroFilterURMarkers2a);
         wazeModel.mapUpdateRequests.events.register("objectsadded", null, uroFilterURMarkers2b);
         wazeModel.mapUpdateRequests.events.register("objectsremoved", null, uroFilterURMarkers2c);
         wazeModel.cameras.events.register("objectschanged", null, uroFilterURMarkers3a);
         wazeModel.cameras.events.register("objectsadded", null, uroFilterURMarkers3b);
         wazeModel.cameras.events.register("objectsremoved", null, uroFilterURMarkers3c);
         wazeModel.problems.events.register("objectschanged", null, uroFilterURMarkers4a);
         wazeModel.problems.events.register("objectsadded", null, uroFilterURMarkers4b);
         wazeModel.problems.events.register("objectsremoved", null, uroFilterURMarkers4c);

         var userTabs = document.getElementById(uroUserTabId);
         var navTabs = uroTimbonesGetElementsByClassName('nav-tabs', userTabs)[0];
         var tabContent = uroTimbonesGetElementsByClassName('tab-content', userTabs)[0];
         newtabUR = document.createElement('li');
         newtabUR.innerHTML = '<a href="#sidepanel-uroverview" data-toggle="tab">URO+</a>';
         navTabs.appendChild(newtabUR);
         uroControls.id = "sidepanel-uroverview";
         uroControls.className = "tab-pane";
         tabContent.appendChild(uroControls);

         document.getElementById('_btnUndoLastHide').addEventListener("click", uroRemoveLastAddedIgnore, true);
         document.getElementById('_btnClearSessionHides').addEventListener("click", uroRemoveAllIgnores, true);
         uroEnableIgnoreListControls();

         document.getElementById('_btnClearCamWatchList').addEventListener("click", uroClearCamWatchList, true);
         
         document.getElementById('_btnSettingsToText').addEventListener("click", uroSettingsToText, true);
         document.getElementById('_btnTextToSettings').addEventListener("click", uroTextToSettings, true);
         document.getElementById('_btnClearSettingsText').addEventListener("click", uroClearSettingsText, true);

         document.getElementById("_linkSelectUserRequests").onclick = uroShowURTab;
         document.getElementById("_linkSelectMapProblems").onclick = uroShowMPTab;
         document.getElementById("_linkSelectCameras").onclick = uroShowCameraTab;
         document.getElementById("_linkSelectMisc").onclick = uroShowMiscTab;
         document.getElementById("_linkSelectCWL").onclick = uroShowCamWatchlistTab;
         
         document.getElementById('_cbHideMyComments').onclick = uroExclusiveCB;
         document.getElementById('_cbHideAnyComments').onclick = uroExclusiveCB;
         document.getElementById('_cbHideIfLastCommenter').onclick = uroExclusiveCB;
         document.getElementById('_cbHideIfNotLastCommenter').onclick = uroExclusiveCB;
         document.getElementById('_cbHideIfReporterLastCommenter').onclick = uroExclusiveCB;
         document.getElementById('_cbHideIfReporterNotLastCommenter').onclick = uroExclusiveCB;        

         uroAddLog('finalise onload');
         uroLoadSettings();
         uroNewLookCheckDetailsRequest();
         
         if(document.getElementById('_cbEnableDTE').checked)
         {
            if(dteControlsIdx != -1) dteSetNewTabLength();
            else
            {
               uroAddLog('ERROR - archive panel not found!');
               document.getElementById(uroUserTabId).style.display = '';
            }      
         }
         
         if(document.getElementById('_cbEnableSRS').checked)
         {
            selectionManager.events.register("selectionchanged", null, srsCheckSidePanel);
            uroAddLog('added SRS event handler');           
         }  

         // filter markers as and when the map is moved
         wazeMap.events.register("move", null, uroFilterURMarkers);

         uroSetStyles(uroCtrlURs);
         uroSetStyles(uroCtrlMPs);
         uroSetStyles(uroCtrlCameras);
         uroSetStyles(uroCtrlMisc);
         uroSetStyles(uroCamWatchlist);

         uroShowURTab();
         uroRestyleWMETabs();
         uroUserID = loginManager.getLoggedInUser().id;
         uroFilterURMarkers();
      }
   }
   else
   {
      uroNewLookHighlightedItemsCheck();
      uroURSCurrentCount = Object.keys(wazeModel.updateRequestSessions.objects).length;
      if(uroURSCurrentCount != uroURSPrevCount)
      {
         uroFilterURMarkers();
         uroURSPrevCount = uroURSCurrentCount;
      }
   }
}

function uroToggleURCtrls()
{
   uroCtrlsHidden = !uroCtrlsHidden;
   if (!uroCtrlsHidden)
   {
      document.getElementById('_hideUCCtrl').innerHTML = "hide";
      if(uroCurrentTab == 1) uroShowURTab();
      else if(uroCurrentTab == 2) uroShowMPTab();
      else if(uroCurrentTab == 3) uroShowCameraTab();
      else if(uroCurrentTab == 4) uroShowCamWatchlistTab();
      else if(uroCurrentTab == 5) uroShowMiscTab();
   }
   else
   {
      document.getElementById('_hideUCCtrl').innerHTML = "show";
      document.getElementById('uroCtrlURs').style.display = 'none';
      document.getElementById('uroCtrlMPs').style.display = 'none';
      document.getElementById('uroCtrlCameras').style.display = 'none';
      document.getElementById('uroCtrlMisc').style.display = 'none';
      document.getElementById('uroCamWatchlist').style.display = 'none';
   }

   return false;
}

function uroActiveTab(_id)
{
   var e = document.getElementById(_id);
   e.style.backgroundColor = "aliceblue";
   e.style.borderTop = "1px solid";
   e.style.borderLeft = "1px solid";
   e.style.borderRight = "1px solid";
   e.style.borderBottom = "0px solid";
}

function uroInactiveTab(_id)
{
   var e = document.getElementById(_id);
   e.style.backgroundColor = "white";
   e.style.borderTop = "0px solid";
   e.style.borderLeft = "0px solid";
   e.style.borderRight = "0px solid";
   e.style.borderBottom = "1px solid";
}


function uroInactiveAllTabs()
{
   uroInactiveTab("_tabSelectCameras");
   uroInactiveTab("_tabSelectMapProblems");
   uroInactiveTab("_tabSelectMisc");
   uroInactiveTab("_tabSelectUserRequests");
   uroInactiveTab("_tabSelectCWL");
   
   if(!uroCtrlsHidden)
   {
      document.getElementById('uroCtrlURs').style.display = 'none';
      document.getElementById('uroCtrlMPs').style.display = 'none';
      document.getElementById('uroCtrlCameras').style.display = 'none';
      document.getElementById('uroCtrlMisc').style.display = 'none';
      document.getElementById('uroCamWatchlist').style.display = 'none';
   }   
}

  
function uroShowURTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectUserRequests");
   uroCurrentTab = 1;
   if(!uroCtrlsHidden) document.getElementById('uroCtrlURs').style.display = 'block';
   return false;
}


function uroShowMPTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectMapProblems");
   uroCurrentTab = 2;
   if(!uroCtrlsHidden) document.getElementById('uroCtrlMPs').style.display = 'block';
   return false;
}


function uroShowCameraTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectCameras");
   uroCurrentTab = 3;
   if(!uroCtrlsHidden) document.getElementById('uroCtrlCameras').style.display = 'block';
   return false;
}

function uroShowCamWatchlistTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectCWL");
   uroCurrentTab = 4;
   if(!uroCtrlsHidden) document.getElementById('uroCamWatchlist').style.display = 'block';
   uroCWLUpdateHTML();
   return false;
}
 
function uroShowMiscTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectMisc");
   uroCurrentTab = 5;
   if(!uroCtrlsHidden) document.getElementById('uroCtrlMisc').style.display = 'block';
   return false;
}


function uroTimbonesGetElementsByClassName(classname, node) {
  if(!node) node = document.getElementsByTagName("body")[0];
  var a = [];
  var re = new RegExp('\\b' + classname + '\\b');
  var els = node.getElementsByTagName("*");
  for (var i=0,j=els.length; i<j; i++)
    if (re.test(els[i].className)) a.push(els[i]);
  return a;
}

function uroNewLookCheckDetailsRequest()
{
   var thisurl = document.location.href;
   var doRetry = true;
   showurpos = thisurl.indexOf('&showur=');
   showproblempos = thisurl.indexOf('&showproblem=');
   showturnpos = thisurl.indexOf('&showturn=');
   endmarkerpos = thisurl.indexOf('&endshow');
   if(endmarkerpos != -1)
   {
      if(showurpos != -1)
      {
         showurpos += 8;
         uroAddLog('showur tab opened');
         var urID = thisurl.substr(showurpos,endmarkerpos-showurpos);
         uroAddLog(' UR ID = '+urID);
         if(wazeMap.layers[uroURLayerIdx].markers == null)
         {
            uroAddLog('wazeMap.layers not loaded, retrying...');
         }
         else
         {
            for(var marker in wazeMap.layers[uroURLayerIdx].markers)
            {
               markerObj = wazeMap.layers[uroURLayerIdx].markers[marker];
               if (urID == markerObj.model.fid)
               {
                  doRetry = false;
                  markerObj.icon.imageDiv.click();
               }
            }
         }
      }

      else if((showproblempos != -1) || (showturnpos != -1))
      {
         if(showproblempos != -1)
         {
            showproblempos += 13;
            uroAddLog('showproblem tab opened');
            var urID = thisurl.substr(showproblempos,endmarkerpos-showproblempos);
            uroAddLog(' problem ID = '+urID);
         }
         else
         {
            showturnpos += 10;
            uroAddLog('showturn tab opened');
            var urID = thisurl.substr(showturnpos,endmarkerpos-showturnpos);
            uroAddLog(' turn problem ID = '+urID);
         }
         if(wazeMap.layers[uroProblemLayerIdx].markers == null)
         {
            uroAddLog('wazeMap.layers not loaded, retrying...');
         }
         else
         {
            for(var marker in wazeMap.layers[uroProblemLayerIdx].markers)
            {
               markerObj = wazeMap.layers[uroProblemLayerIdx].markers[marker];
               if (urID == markerObj.model.fid)
               {
                  doRetry = false;
                  markerObj.icon.imageDiv.click();
               }
            }
         }
      }
   }

   if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
}


function uroSetStyles(obj)
{
   obj.style.fontSize = '12px';
   obj.style.lineHeight = '100%';
   obj.style.overflow = 'auto';
   obj.style.height = (window.innerHeight * 0.55) + 'px';
}


function uroWazeBits()
{
   uroAddLog('adding WazeBits...');   
   if((uroWazeBitsPresent & 0x01) == 0)
   {
      if(typeof unsafeWindow.wazeMap != "undefined")
      {
         uroAddLog('   wazeMap OK');
         wazeMap = unsafeWindow.wazeMap;
         uroWazeBitsPresent |= 0x01;
      }
      else if(typeof unsafeWindow.W != "undefined")
      {
         if(typeof unsafeWindow.W.controller != "undefined")
         {
            if(typeof unsafeWindow.W.controller.map != "undefined")
            {
               uroAddLog('   wazeMap OK');
               wazeMap = unsafeWindow.W.controller.map;
               uroWazeBitsPresent |= 0x01;
            }
         }
      }
   }  
   if((uroWazeBitsPresent & 0x02) == 0)
   {
      if(typeof unsafeWindow.wazeModel != "undefined")
      {
         uroAddLog('   wazeModel OK');
         wazeModel = unsafeWindow.wazeModel;
         uroWazeBitsPresent |= 0x02;
      }
      else if(typeof unsafeWindow.W != "undefined")
      {
         if(typeof unsafeWindow.W.controller != "undefined")
         {
            if(typeof unsafeWindow.W.controller.model != "undefined")
            {
               uroAddLog('   wazeModel OK');
               wazeModel = unsafeWindow.W.controller.model;
               uroWazeBitsPresent |= 0x02;
            }
         }
      }
   }
   if((uroWazeBitsPresent & 0x04) == 0)
   {
      if(typeof unsafeWindow.loginManager != "undefined")
      {
         uroAddLog('   loginManager OK');
         loginManager = unsafeWindow.loginManager;
         uroWazeBitsPresent |= 0x04;
      }
      else if(typeof unsafeWindow.W != "undefined")
      {
         if(typeof unsafeWindow.W.app != "undefined")
         {
            if(typeof unsafeWindow.W.app.loginManager != "undefined")
            {
               uroAddLog('   loginManager OK');
               loginManager = unsafeWindow.W.app.loginManager;
               uroWazeBitsPresent |= 0x04;
            }
         }
      }
   }
   if((uroWazeBitsPresent & 0x08) == 0)
   {
      if(typeof unsafeWindow.selectionManager != "undefined")
      {
         uroAddLog('   selectionManager OK');
         selectionManager = unsafeWindow.selectionManager;
         uroWazeBitsPresent |= 0x08;
      }
      else if(typeof unsafeWindow.W != "undefined")
      {
         if(typeof unsafeWindow.W.geometryEditing != "undefined")
         {
            if(typeof unsafeWindow.W.geometryEditing.selectionManager != "undefined")
            {
               uroAddLog('   selectionManager OK');
               selectionManager = unsafeWindow.W.geometryEditing.selectionManager;
               uroWazeBitsPresent |= 0x08;
            }
         }
      }
   }
   if((uroWazeBitsPresent & 0x10) == 0)
   {
      if(typeof unsafeWindow.OpenLayers != "undefined")
      {
         uroAddLog('   OpenLayers OK');
         OpenLayers = unsafeWindow.OpenLayers;
         uroWazeBitsPresent |= 0x10;
      }
   }
   if((uroWazeBitsPresent & 0x20) == 0)
   {
      if(typeof unsafeWindow.Waze != "undefined")
      {
         uroAddLog('   Waze OK');
         Waze = unsafeWindow.Waze;
         uroWazeBitsPresent |= 0x20;
      }
   }
   if((uroWazeBitsPresent & 0x40) == 0)
   {
      if(document.getElementById('user-tabs') != null)
      {
         uroUserTabId = 'user-tabs';
         uroAddLog('   user-tabs OK');
         uroWazeBitsPresent |= 0x40;
      }
      else if(document.getElementById('user-info') != null)
      {
         uroUserTabId = 'user-info';
         uroAddLog('   user-info OK');
         uroWazeBitsPresent |= 0x40;
      }
   }
   if((uroWazeBitsPresent & 0x80) == 0)
   {
      if(document.getElementById('sidepanel-drives') != null)
      {
         uroAddLog('   sidepanel-drives OK');
         uroWazeBitsPresent |= 0x80;
      }
   }

   if(uroWazeBitsPresent != 0xFF) setTimeout(uroWazeBits,250);
   else if(loginManager.isLoggedIn() == false)
   {
      uroAddLog('Waiting for user log-in...');
      setTimeout(uroWazeBits,1000);
   }
   else
   {
      uroAddLog('All WazeBits present and correct...');
      uroControls.appendChild(uroCtrlURs);
      uroControls.appendChild(uroCtrlMPs);
      uroControls.appendChild(uroCtrlCameras);
      uroControls.appendChild(uroCamWatchlist);
      uroControls.appendChild(uroCtrlMisc);
      uroControls.appendChild(uroCtrlHides);

      uroCtrlURs.onclick = uroFilterURMarkers;
      uroCtrlMPs.onclick = uroFilterURMarkers;
      uroCtrlCameras.onclick = uroFilterURMarkers;
      uroCtrlMisc.onclick = uroFilterURMarkers;

      for(i=0;i<wazeMap.layers.length;i++)
      {
         if(wazeMap.layers[i].uniqueName == 'update_requests') uroURLayerIdx = i;
         if(wazeMap.layers[i].uniqueName == 'problems') uroProblemLayerIdx = i;
         if(wazeMap.layers[i].name == 'Spotlight') uroMaskLayer = i;
         if(wazeMap.layers[i].uniqueName == 'speed_cameras') 
         {
            uroCamvroot = wazeMap.layers[i].div.id + '_vroot';
            uroCamLayer = i;
         }
         if(wazeMap.layers[i].name.indexOf('Waze.Control.SelectHighlightFeature') != -1) uroRootContainer = wazeMap.layers[i].div.id;
      }

      for(i=0;i<wazeMap.controls.length;i++)
      {
         if(wazeMap.controls[i].CLASS_NAME == 'Waze.View.ArchivePanel') dteControlsIdx = i;
         else if(wazeMap.controls[i].CLASS_NAME == 'Waze.Control.Archive') dteControlsIdx = i;

         if(wazeMap.controls[i].id != null) 
         {
            if(wazeMap.controls[i].id.indexOf('UpdateRequests') != -1) uroURControlsIdx = i;
            if(wazeMap.controls[i].id.indexOf('MapProblems') != -1) uroProblemControlsIdx = i;
         }
      }
      uroAddLog('UR layer at idx '+uroURLayerIdx);
      uroAddLog('Problem layer at idx '+uroProblemLayerIdx);
      uroAddLog('uroMaskLayer at idx '+uroMaskLayer);
      uroAddLog('Camera layer at idx '+uroCamLayer);
      uroAddLog('uroCamvroot = '+uroCamvroot);
      uroAddLog('uroRootContainer = '+uroRootContainer);

      uroDiv.addEventListener("mouseover", uroEnterPopup, false);
      uroDiv.addEventListener("mouseout", uroExitPopup, false);

      if(sessionStorage.UROverview_FID_IgnoreList == null) sessionStorage.UROverview_FID_IgnoreList = '';
      if(sessionStorage.UROverview_FID_WatchList == null) sessionStorage.UROverview_FID_WatchList = '';

      setInterval(uroTenthSecondTick,100);
   }
}

function uroEnterPopup()
{
   uroMouseInPopup = true;
}

function uroExitPopup()
{
   uroMouseInPopup = false;
}

function uroInitialise()
{
   uroGlobals();
   
   if(document.URL.indexOf('editor-beta') != -1) uroBetaEditor = true;

   // create a new div to display the UR details floaty-box
   uroDiv = document.createElement('div');
   uroDiv.id = "uroDiv";
   uroDiv.style.position = 'absolute';
   uroDiv.style.visibility = 'hidden';
   uroDiv.style.top = '0';
   uroDiv.style.left = '0';
   uroDiv.style.zIndex = 100;
   uroDiv.style.backgroundColor = 'aliceblue';
   uroDiv.style.borderWidth = '3px';
   uroDiv.style.borderStyle = 'ridge';
   uroDiv.style.borderRadius = '10px';
   uroDiv.style.boxShadow = '5px 5px 10px Silver';
   uroDiv.style.padding = '4px';
   document.body.appendChild(uroDiv);


   uroControls = document.createElement('section');
   uroControls.style.fontSize = '12px';
   uroControls.id = 'uroControls'; 
   tabbyHTML = '<b><a href="http://userscripts.org/scripts/show/145186" target="_blank">UROverview Plus</a></b> '+uroVersion;
   tabbyHTML += '<p><table border=0 width="100%"><tr>';
   tabbyHTML += '<td valign="center" align="center" id="_tabSelectUserRequests"><a href="#" id="_linkSelectUserRequests" style="text-decoration:none;font-size:12px">URs</a></td>';
   tabbyHTML += '<td valign="center" align="center" id="_tabSelectMapProblems"><a href="#" id="_linkSelectMapProblems" style="text-decoration:none;font-size:12px">MPs</a></td>';
   tabbyHTML += '<td valign="center" align="center" id="_tabSelectCameras"><a href="#" id="_linkSelectCameras" style="text-decoration:none;font-size:12px">Cams</a></td>';
   tabbyHTML += '<td valign="center" align="center" id="_tabSelectCWL"><a href="#" id="_linkSelectCWL" style="text-decoration:none;font-size:12px">CWL</a></td>';   
   tabbyHTML += '<td valign="center" align="center" id="_tabSelectMisc"><a href="#" id="_linkSelectMisc" style="text-decoration:none;font-size:12px">Misc</a></td>';
   tabbyHTML += '</tr></table>';
   uroControls.innerHTML = tabbyHTML;


   uroCtrlURs = document.createElement('p');
   uroCtrlMPs = document.createElement('p');
   uroCtrlCameras = document.createElement('p');
   uroCamWatchlist = document.createElement('p');
   uroCtrlMisc = document.createElement('p');
   uroCtrlHides = document.createElement('div');

   // UR controls tab
   uroCtrlURs.id = "uroCtrlURs";
   uroCtrlURs.innerHTML = '<br>';

   uroCtrlURs.innerHTML += '<b>Hide URs by type:</b><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWazeAuto">Waze Automatic</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectTurn">Incorrect turn</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectAddress">Incorrect address</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectRoute">Incorrect route</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoundabout">Missing roundabout</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterGeneralError">General error</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterTurnNotAllowed">Turn not allowed</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectJunction">Incorrect junction</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingBridgeOverpass">Missing bridge overpass</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWrongDrivingDirection">Wrong driving direction</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingExit">Missing exit</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoad">Missing road</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterBlockedRoad">Blocked road</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingLandmark">Missing Landmark</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUndefined">Undefined</input><br>';

   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<i>UK Specific types</i><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterCryosphere">Petrol Station Checker</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterRoadworks">Roadworks</input><br><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbInvertURFilter">Invert operation of type filters?</input><br>';
   
   uroCtrlURs.innerHTML += '<br><b>Hide closed/solved/unidentified URs:</b><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterClosedUR">Closed</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterSolved">Solved</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUnidentified">Not identified</input><br><br>';


   uroCtrlURs.innerHTML += '<br><b>Filter URs by age of submission:</b><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinAgeFilter">Hide URs less than </input>';
   uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinDays"> days old<br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxAgeFilter">Hide URs more than </input>';
   uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxDays"> days old<br>';

   uroCtrlURs.innerHTML += '<br><b>Filter URs by description keyword:</b><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBePresent">Hide URs not including </input>';
   uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPresent"><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBeAbsent">Hide URs including </input>';
   uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordAbsent"><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbCaseInsensitive">Case-insensitive matches?</input><br>';
   
   uroCtrlURs.innerHTML += '<br><b>Hide URs by comments/following:</b><br>';
   uroCtrlURs.innerHTML += '<i>With comments from me?</i><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyComments">Yes </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideAnyComments">No</input><br>';
   
   uroCtrlURs.innerHTML += '<i>If last comment made by me?</i><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfLastCommenter">Yes </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfNotLastCommenter">No </input><br>';
   
   uroCtrlURs.innerHTML += '<i>If last comment made by UR reporter?</i><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterLastCommenter">Yes </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterNotLastCommenter">No</input><br>';

   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinCommentsFilter">With less than </input>';
   uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinComments"> comments<br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxCommentsFilter">With more than </input>';
   uroCtrlURs.innerHTML += '<input type="number" min="0" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxComments"> comments<br>';
   
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyFollowed">Ones I am or </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyUnfollowed">am not following</input><br>';

   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter2">Last comment less than </input>';
   uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays2"> days ago<br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter">Last comment more than </input>';
   uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays"> days ago<br>';


   // Map problems controls tab
   uroCtrlMPs.id = "uroCtrlMPs";
   uroCtrlMPs.innerHTML = '<br>';

   uroCtrlMPs.innerHTML += '<b>Filter MPs by type:</b><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingJunction">Missing junction</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingRoad">Missing road</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterCrossroadsJunctionMissing">Missing crossroads</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterDrivingDirectionMismatch">Driving direction mismatch</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRoadTypeMismatch">Road type mismatch</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRestrictedTurn">Restricted turn might be allowed</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnknownProblem">Unknown problem type</input><br><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterTurnProblem">Turn Problems</input><br><br>';
   
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbInvertMPFilter">Invert operation of type filters?</input><br>';

   uroCtrlMPs.innerHTML += '<br><b>Hide closed/solved/unidentified Problems:</b><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterClosed">Closed</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterSolved">Solved</input><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnidentified">Not identified</input><br><br>';

   uroCtrlMPs.innerHTML += '<br><b>Hide problems (not turn) by severity:</b><br>';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterLowSeverity">Low</input>&nbsp;&nbsp;';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMediumSeverity">Medium</input>&nbsp;&nbsp;';
   uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterHighSeverity">High</input><br>';



   // Camera controls tab
   uroCtrlCameras.id = "uroCtrlCameras";
   uroCtrlCameras.innerHTML = '<br><b>Show Cameras by creator:</b><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowWorldCams" checked>world_* users</input><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowUSACams" checked>usa_* users</input><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonWorldCams" checked>other users</input><br>';
   uroCtrlCameras.innerHTML += '<br><input type="checkbox" id="_cbShowOnlyMyCams">Show ONLY cameras created/edited by me</input><br>';


   uroCtrlCameras.innerHTML += '<br><b>Show Cameras by approval status:</b><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowApprovedCams" checked>approved</input><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonApprovedCams" checked>non-approved</input><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowOlderCreatedNonApproved"> if created more than </input>';
   uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinCreatedDays"> days ago<br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowOlderUpdatedNonApproved"> if updated more than </input>';
   uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinUpdatedDays"> days ago<br>';

   uroCtrlCameras.innerHTML += '<br><b>Show Cameras by type:</b><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowSpeedCams" checked>Speed</input><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfMPHSpeedSet" checked> with MPH speeds</input><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfKPHSpeedSet" checked> with KM/H speeds</input><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfNoSpeedSet" checked> with no speed</input><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowRedLightCams" checked>Red Light</input><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowDummyCams" checked>Dummy</input><br>';

   uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by creator:</b><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByMe">me</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank0">L1</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank1">L2</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank2">L3</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank3">L4</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank4">L5</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank5">L6</input>';

   uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by updater:</b><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByMe">me</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank0">L1</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank1">L2</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank2">L3</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank3">L4</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank4">L5</input>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank5">L6</input>';

   uroCtrlCameras.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideCWLCams">Hide cameras on CWL</input></b><br>';

   
   // Camera watchlist tab
   uroCamWatchlist.id = "uroCamWatchlist";
   uroCWLUpdateHTML();
   

   // Misc controls tab
   uroCtrlMisc.id = "uroCtrlMisc";
   uroCtrlMisc.innerHTML = '<br><b>Use default conversation markers:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeConvoMarkers" checked>in public WME</input><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeBetaConvoMarkers" checked>in beta WME</input><br>';
   
   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCommentCount">Show comment count on UR markers</input></b><br>';
   
   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCustomRoadworksMarkers">Use custom marker for [ROADWORKS] URs</input></b><br>';
   
   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbInhibitURPopup">Disable popup for URs</input></b><br>';
   uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbInhibitMPPopup">Disable popup for MPs</input></b><br>';
   uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbInhibitCamPopup">Disable popup for cameras</input></b><br>';

   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbWhiteBackground">Use white background</input></b><br>';
   
   uroCtrlMisc.innerHTML += '<br><b>Enable integrated scripts:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableDTE">Drive Tab Enhancement</input><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableSRS">Select Roundabout Segments</input><br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Settings backup/restore:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="button" id="_btnSettingsToText" value="Backup">&nbsp;&nbsp;&nbsp;';
   uroCtrlMisc.innerHTML += '<input type="button" id="_btnTextToSettings" value="Restore">&nbsp;&nbsp;|&nbsp;&nbsp;';
   uroCtrlMisc.innerHTML += '<input type="button" id="_btnClearSettingsText" value="Clear"><br>';
   uroCtrlMisc.innerHTML += '<textarea id="_txtSettings" value="">';
   


   // footer for tabs container
   uroCtrlHides.id = 'uroCtrlHides';
   uroCtrlHides.innerHTML = '<input type="button" id="_btnUndoLastHide" value="Undo last hide">&nbsp;&nbsp;&nbsp;';
   uroCtrlHides.innerHTML += '<input type="button" id="_btnClearSessionHides" value="Undo all hides">';


   window.addEventListener("beforeunload", uroSaveSettings, false);
   
   uroWazeBits();
}


function dteAddHeader()
{                   
   rlcObj = document.getElementsByClassName("result-list-container");
   if(typeof rlcObj == "undefined") return;
   if(typeof rlcObj[0].children[0] == "undefined") return;
   if(typeof rlcObj[0].children[0].innerHTML == "undefined") return;
   
   var thtml = rlcObj[0].children[0].innerHTML;
   if(thtml.indexOf('Full drive history') == -1)
   {
      thtml += '<br><br><i><small>Full drive history goes back to '+dteOldestFullDrive.toDateString()+'</small></i>';
      rlcObj[0].children[0].innerHTML = thtml;
   }
}


function dteSetNewTabLength()
{
   uroAddLog('altering ResultsPerPage parameter...');

   var t = document.getElementById('sidepanel-drives');
 	t.style.overflow = 'auto';
	t.style.height = (window.innerHeight * 0.6) + 'px';

   baseloc = 'https://'+window.location.hostname+Waze.Config.api_base+'/Archive/MyList?minDistance=1000';

   var a = new XMLHttpRequest();
   var idxCheckFullDrive = 0;
   var fullDrives = 0;
   var foundMissingDrive = false;

   while(!foundMissingDrive)
   {
      document.getElementById(uroUserTabId).style.display = 'none';
      var loc = baseloc+'&offset='+fullDrives+'&count=5';
      uroAddLog('requesting '+loc);
      a.open('GET',loc,false);
      a.send();
      var b = JSON.parse(a.responseText);
      var loadedDrives = b.archives.objects.length;
      uroAddLog('received '+loadedDrives+' drives');
      if(loadedDrives != 5) foundMissingDrive = true;

      for(var loop=0; loop < loadedDrives; loop++)
      {
         if(b.archives.objects[loop].hasFullSession == false) foundMissingDrive = true;
         else
         {
            fullDrives++;
            dteOldestFullDrive = new Date(b.archives.objects[loop].startTime);
         }
      }
   }

   uroAddLog(fullDrives+' full drives in history');
   uroAddLog('oldest drives are on '+dteOldestFullDrive.toDateString());
   if(fullDrives < 5)
   {
      fullDrives = 5;
      uroAddLog('insufficient full drives, using standard drives tab');
   }
   else if(fullDrives > 50)
   {
      uroAddLog('too many full drives for a single tab page, splitting over multiple pages...');
      fullDrives = Math.ceil(fullDrives/Math.ceil(fullDrives/50));
   }
   document.getElementById(uroUserTabId).style.display = '';
   if((dteOldestFullDrive - dteEpoch) > 0)
   {
      uroAddLog('updating drives tab...');
      wazeMap.controls[dteControlsIdx].sidePanelView.ResultsPerPage = fullDrives;
      setInterval(dteAddHeader,250);
   }
}


function srsSelect()
{
   rbtID = selectionManager.selectedItems[0].attributes.junctionID;
   uroAddLog('selecting roundabout ID '+rbtID);
   selectionManager.selectControl.unselectAll();

   for(var seg in wazeModel.segments.objects)
   {
      if(wazeModel.segments.objects[seg].attributes.junctionID == rbtID)
      {
         uroAddLog('...adding segment '+seg);
         selectionManager.selectControl.select(wazeModel.segments.objects[seg]);
      }
   }
}


function srsCheckSidePanel()
{
   if(selectionManager.selectedItems.length == 0) return;
   if(document.getElementById('srsCtrl') != null) return;
   if(selectionManager.selectedItems[0].attributes.junctionID == null) return;
   srsCtrl = document.createElement('section');
   srsCtrl.id = 'srsCtrl';
   srsCtrl.innerHTML = '<button id="srsButton" class="btn">Select roundabout</button>';
   document.getElementById('segment-edit-general').appendChild(srsCtrl);
   document.getElementById('srsButton').onclick = srsSelect;
}


uroBootstrap();