UROverview Plus (URO+)

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

目前為 2017-03-13 提交的版本,檢視 最新版本

// ==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://www.waze.com/*/editor/*
// @include             https://www.waze.com/editor/*
// @include             https://editor-beta.waze.com/*
// @include             https://beta.waze.com/*
// @exclude             https://www.waze.com/user/*editor/*
// @exclude             https://www.waze.com/*/user/*editor/*
// @grant               none
// @version             3.101
// ==/UserScript==

/*

TO-DO ITEMS
=======================================================================================================================
Bug fixes - MUST BE CLEARED BEFORE RELEASE
=======================================================================================================================



=======================================================================================================================
Things to be checked
=======================================================================================================================



=======================================================================================================================
Proposed functionality
=======================================================================================================================

Adjust default settings for places & MP tabs to account for dynamic nature of tab building

Restore custom icon functionality

Convert camera XHR code to async operation

"Hide All" button for feed - automatically clicks the trashcan on all visible feed entries

Allow custom alert box to be used as a confirm() replacement as well

Improve reliability of yellow/green comment marker choice

Implement some sort of UR "hotspot" marking to highlight areas of the map with significant clustering of URs

Flush settings to localStorage whenever a change is made, or at least before opening a new tab via a popup

User-defined setting presets

Extend unstacking to cameras

Place filtering
 - by last user to edit

More localisation

First-run information
 - show quickstart guide to URO features if no existing settings are present (i.e. new installation)

=======================================================================================================================
New functionality in progress
=======================================================================================================================

Addition of segment and place watchlist functionality
*/

/* JSHint Directives */
/* globals $: */
/* globals W: true */
/* globals I18n: */
/* globals OL: true */
/* globals OpenLayers: true */
/* globals Waze: true */
/* globals require: */
/* jshint bitwise: false */
/* jshint eqnull: true */


var uroVersion = "3.101";
var uroReleaseDate = "20170313";

// list of changes affecting all users
var uroChanges =
[
   "Fixed open in new tab links for URs, MPs and PURs"
];
// list of changes affecting only WME Beta users (at least until the next production release including these parts of the beta code...)
var uroBetaChanges =
[
];

// true enables debug output during script startup
var uroShowDebugOutput = true;
// true keeps debug output enabled after script startup
var uroPersistentDebugOutput = false;
/*
var uroRecentDebug = [];
*/
var uroCtrlsHidden = false;
var uroCurrentTab = 1;
var uroFID = -1;
var uroShownFID = -1;
var uroShownPopupType = null;
var uroInhibitSave = true;
var uroPopupTimer = -2;
var uroPopupDwellTimer = -1;
var uroPopupShown = false;
var uroPopupSuppressed = false;
var uroSetupListeners = true;
var uroRootContainer = null;
var uroPlacesRoot = null;
var uroConfirmIntercepted = false;
var uroCustomMarkerList = [];
var uroPendingURSessionIDs = [];
var uroRequestedURSessionIDs = [];
var uroPlacesGroupsCollapsed = [];
var uroKnownProblemTypeIDs = [];
var uroKnownProblemTypeNames = [];

var uroMouseInPopup = false;
var uroURControlsIdx = null;
var uroProblemControlsIdx = null;
var uroTurnsLayerIdx = null;
var uroMCLayerIdx = null;

var uroNullCamLayer = false;
var uroNullOpenLayers = false;
var uroNullURLayer = false;
var uroNullProblemLayer = false;
var uroNullMapViewport = false;

var uroURDialogIsOpen = false;
var uroHoveredURID = null;
var uroSelectedURID = null;
var uroURReclickAttempts = 0;
var uroPendingCommentDataRefresh = false;
var uroWaitingCommentDataRefresh = false;
var uroExpectedCommentCount = null;
var uroCachedLastCommentID = null;

var uroMCSelected = false;
var uroPlaceSelected = false;
var uroAutoCentreDisabledOn = [];
var uroMouseIsDown = false;
var uroBackfilling = false;
var uroHidePopupOnPanelOpen = false;

var uroUserID = -1;
var uroURIDInURL = null;

var uroDOMHasTurnProblems = false;
var uroBetaEditor = false;
var uroWazeBitsPresent = 0;
var uroMTEMode = false;
var uroFinalisingListenerSetup = false;
var uroInitialised = false;

var uroOWL = null;
var uroDiv = null;
var uroAlerts = null;
var uroControls = null;
var uroCtrlURs = null;
var uroCtrlMPs = null;
var uroCtrlPlaces = null;
var uroCtrlCameras = null;
var uroCtrlMisc = null;
var uroCtrlHides = null;
var uroAMList = [];

var uroCWLGroups = [];
var uroCamWatchObjects = [];
var uroSegWatchObjects = [];
var uroPlaceWatchObjects = [];

var uroFriendlyAreaNames = [];
var uroAreaNameHoverTime = -1;
var uroAreaNameHoverObj = null;
var uroAreaNameOverlayShown = false;
var uroANEditHovered = false;
var uroANEditBox = null;

var uroPrevMouseX = -1;
var uroPrevMouseY = -1;

var dteControlsIdx = -1;
var dteOldestFullDrive = new Date(0);
var dteEpoch = new Date(0);
var dteTopID = '';
var dteClearHighlightsOnPanelClose = false;
var dteArmClearHighlightsOnPanelClose = false;
var dteOffset = 0;

var uroUserTabId = '';
var uroShowFeedFilter = false;

var uroTBRObj = null;

var uroBackfillQueue = [];

var uroUnstackedMasterID = null;
var uroStackList = [];
var uroStackType = null;

var uroMousedOverMarkerID = null;
var uroMousedOverMarkerType = null;
var uroClickedOnMarkerID = null;
var uroClickedOnMarkerType = null;


var uroAlertBoxStack = [];
var uroAlertBoxTickAction = null;
var uroAlertBoxCrossAction = null;
var uroAlertBoxInUse = false;

var uroNativeMarkerImage = 'problems-sc703e224cf.png';

var uroCustomURTags = ['[ROADWORKS]','[CONSTRUCTION]','[CLOSURE]','[EVENT]','[NOTE]','[WSLM]','[BOG]','[DIFFICULT]'];
var uroAltMarkers =
[
   // 0 = closure
   "url('data:image/png;base64,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')",
   // 1 = cone
   "url('data:image/png;base64,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')",
   // 2 = custom text
   "url('data:image/png;base64,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')",
   // 3 = editor note
   "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAKrCAYAAAB/UOT4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AQYFRowNqTDfgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAABmJLR0QA/wD/AP+gvaeTAAAWoUlEQVR42u1ae3BUVZq//QhJP/J+dKfzMISEhHTe6aQfeZBACBNepibAEgngRmURMRVEh3XRcQooH6gplioU/lsKp2ZLxkdZQnCRslYLGEEZtnBlambkqSMoCoZHAknn7Pe73A5J091JpxOt2vp+Xadu7r3nnO+73/nOd8755ZMkBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGgzEBUFPR1NbWasvKysI8Bfd4rrwfd6jQMYRkZGRE0NVYVVUVS4ITXC5XUn5+vglX3OM53iv1tIpCqpCF4ytNJpPB6XTGUUmh+ynl5eVWm81WUllZaaNnFbjiHs/xHvVQH+3QfqzKqPAl1JEOndEXptPX5nd0dDQeO3as89KlSx/fuHHjG7fbfUsQcMU9nuM96qE+2inK6xTLjFoRFbSnr4uka7LD4Zi2adOmpvPnz3eRsD4RADdvXReKUn2ov2njxia0Rz9Kf2GjUURWwG63R9XU1KRRB6WHDx/u7O/v73EPuEUwcLv7Bdod/uijTvSD/tDvSIrIQwCNYcaGhgb7mTNn9opQcJ0ss2WLOP2HP+xtqK21o1/0H2hoNIoDpsDRSIF9YxY+MHDnumePEAsWCBETI07Pm7fPkZNjs5eVpUCOMp2HW6GxsTEcU620tLTw0KFD20So+OEHIZ56SojiYiEkSfRQ2e1ybSvMySmEHMgbZg0l8ESTFbI2bNjQQmPZG7ISBw4IMX++GNDrxQAp8DWVD/Pze9d3dLRADuQpwzIYD8KtVquZHtrOnj17MGQFuruF2LBBiLw8IdRq0U8K/DeVL5/+V4H+IQfyINdjDY0yfaY88cQTi0JWAP5w7JgQM2aIgbg4eShghQ9SUsS1L7/E9O2HHMiDXNk3YJKKior46upq+MLOkBUA2tuFKCqSreAmBQ6qVOLkypWD1SAH8iDXMyThCCb0wHnhwoWjIVviyBEh6urEgMkkW+F/qewjJXovXrwza3u6BeRAHuTKQ4KQSt563/Tp0+uuXbv2XchKPPigGHA6ZQVuUvkvKLJ6tWKoO5aCHMiDXMiXKCgZlEVnNo3X7ZCGATOisVGIpCRZiS+pdFHpu3bNK5q6b0Me5EI+fMJI4TSbQmtjSBbo7xeCvnigslJW4Dp8gcpff/e7YVbwAPIgF/JlJahk4SHFh9tjtkJXlxALFwoRHS3Hha+oHIiPFz1ff+1D3/7bkAe5shIwB8X0TFpgGn766aeLY44Lzz4rhM026Av7qfxt40YxQBbytgLkQB7kysMBx8DCQqX29OnTf+q9fXNsM6KpSYioKNkKf0V0TE8XPx0/fk9V9E/r0hHIU/YbusEpSuaxd3V17QhuJOgLr98QYvNmMVBYKIRGI/owJal8sWqV33aQA3mDU1TZQWH3U9DS0tIa7LrR/91Z4f4nWikj4wbjwgcJCeLq0aM+HbKvr68XciAPcj3BSq1sXjMpis08ceLE/mCU6Ln+hfi+q110P2CVZwSs8OfFi/3WR/+QA3myUyq7c3kBw64ZO6Dly5e39fb2do9aiZ5T4vyFfxN//5/l4qvNLnHkV5PF9b/8zacV0C/6hxzIG7qADS5iijVm7N69e+uAdw++/IHw7bd/Foc/eUT8/Z254ux//rO49cMFf/UH0C/JqYOcwcXLa3sPB03Atp3C6dy9e/e+u23btiFf3CNo8yrefPNNcerUKfHjjz+Ky5cvi/fee18U5k4V+3//7/co6AHtwMUnn3zyFvpVjgUJ3lYYPFnRSz2Nk5kqFlOD+/fs2fPH4zTNPvzwQ/Hcc8+JWbNmibVr18pXMqsgBxPr168Xn33+ecAh27hx46Xc3NyHqf8S9A85/k5q8kYXzqIcXkqWLl0676WXXupcsWJFD5lS3Lp1S7bIrl27aBi+RdARn376qV8LPP/88+4dO3a8T8rOR3/oV4nQ2hF33KiIOfzII48UtLW11be3tz+0bt26IyP5x1A8/fTTJx9//PGVra2t9ZiO6G80CgxTBCajDhIXL16cvWzZMvvs2bMX0Ob0sebm5q8CmZ6G5+qaNWs6qE0TLVCO4uLibHL2RGWogzuFKSfvCOokhjpLJT8ooDhfT2h78skn/+FLgSuEZ555Zi0WJ/gVlTS0Rz/KTAhKAVkJnJYQ27EzJitYSIn8urq6Bhrjju7u7qsYBoqw2B+guLds2dJJ028+FIDiUADtaVM7aQhtMPJQLFq0CJXDcUDBsQ2hFecEdErK5JKQKrpf8vLLL28nJdxXrl+WrXDw4MEPyAIr6N0MHIaxa0JAwj6SrBeNuDBEIb/KDPoCGkIozgc40GJTSrLLaPl1YQmm5zg7dBw4cOAjKHDu3Lkz9Hw9lCBhc6hUkxLl1KYIcYH6m0rvMrDNV6wa7m+K4mG4QgVkwqQkvBJxHmNMHS8gxZrp3QNU5ynq+EX6+zWKI+doeN6g+1fp/bP07iFqsxBxBsGJnkHp6VAKH0T9WAKd0DXKpjeJKuXAs0lIPcYYwqnjJfS1S6mjB+n+t1ReoY6203WnzWZ7nf7eStfN9L6d+lgGa1HbRdQO9EAjta1RguB9ZPEYf0rIlgDlg82GEr7LFdPOwBehM3wdrEJ//1oRsoT+XgxF8fUkfB7qYSMLK1KZju09FMB0hZ/QsGD19DldZafEdMK4oTI4hcLCwsnKmE6DYigIPsp4Fys0UTHu4TtwStShv/PQDjtqfD2GAb4GBYY4Z2CeCuSXEmCMyuE1BlZSNkBx6NC7eN6hYHqiHcZfoRzkmRFMwPLECpkuVCw0jDIcqXgoRWXKq8eDyWMek3nM8eExqd0vy2NSfZnHpPbDeMz8/J+Zx1SAfhpmzbLT8ptemZcXWZud/TPwmL4UOX16n9NqtdnT01NMRuPPxGP6oA8O/eY324qSkgpdKSlJv8rK+hl4TB8n9/5Zs3o32O0tToslq9BsjrZnZEwgj+mHy+p3OsXZwsKDNamptqyEhAnkMUfgstxqdf+/FBQssppMU1xO5wTwmKPksv7D4djpyM+fQB5zBC7rCyrvlpcftZWWTiCPOQou6+Tmzd9Nr6mZIB7TD5c14MVlXfnsM/885giUREhc1m0vLmtieMwguKyJ4TGD5LImhscMgstC/yTnXh6zsDBnkMcMxi981fXHZfVePu+fx7TbSmnveF9cUVFRwcKFC1u///77XnBS4KbAUYGZ8WLovb44MJfV9cbWYQr65THpxpiXl5eZnZ0989FHH90/lJsCVwXOCtyVRyFcx8plBeQxc3JycIwvXbJkSduuXbu6IQgcFbiqF154QbzzzjsUe7qVGNQt3+N5IC7LMzSe67jxmJ7hGPq6r++G6L/VLdx9vcOeD1XCw2M6HGV1zvL8THtJ3sTymDdv3hxWl/qCM75VVFQ8Ny011WqdljMxPGYgPyHTX6Kt48NZWVmgEYPjMSmszmtvb++kg82IPCb85O233x7mJ+vWrXOvWrXqfdo6guMooa1j8DymQgHUz5kzJyCP6T1tgdWrV59sbW1d2dzcHBqPCf4RxAYCC4gRWu4fo68KyGPSMF1tamrqIOHjz2N6rELXgDzmmjVrJo7HBNOC8yVoI+YxmcdkHpN5TOYxmcfkfEzOx+R8TM7H5HxMzsfkfEzOx+R8TM7H5HxMzsfkfEzOx+R8TOYxmcdkHpN5TOYxmcfkfEzOx+R8TM7H5HxMzsfkfEzOx+R8TM7H5HxMzsfkfEzOx+R8TOYxmcdkHpN5TOYxmcfkfEzOx+R8TM7H5HxMzsfkfEzOx+R8TM7H5HxMzsfkfEzOx2Qek3lM5jGZx2Qek3lMzsfkfEzOx+R8TM7H5HxMzsfkfEzOx+R8TM7H5HxMzsfkfEzOx2Qek3lM5jGZxxwFj5lRm6FNLksO8xTcTziPCSExGTER6bXpxrSqtFhzmTkhxZWSlJifaMIV93iO96inKDU+PCa+0mAyGFKcKXEWpyXFVGaaYi43W002U4ml0mJLdiZX4Ip7+Tm9Rz3UR7uQeEx8SaozVYfOUqpS0i0uS35hR2FjzbGazvxL+R8n3Uj6JswddksSksAV93iO96iH+mgXEo+ZWpkaSSZOTnYkTyvfVN5Uer60S+PW9EGo39+tO1fUQ/3yjbax85hGuzEqsiYyTe/Ql8YdjuuU+qUeaSCg+Ht/bkmE94ePLR8TFjBWGdMjGyLthjOGvUGKHv67LgWfjwlHglMZKg02/Rn9vjELV6wWdD5mVmNWOKZaUmlSYeyh2G0hWQC/H6Tg8zHJCaPJClnFG4pbyAd6Q1bigOQ3HxNyIE+JJXcPPgnWBHNqbaqt8GzhwZAV6Jb85mOif8iBvHt4TASZgicKFoWsAPzhmOQzH1P6UhJqt7ofciAPk2AYj5lSnVLoOOTYGbICcEgf+ZjSyrv1IAfyLBWWeM+QyDymqcLkzLmQczRkSxyRfOZjSheV9z2SmHRh0lF9hd5pKDMM5zEt0y11cdfivgtVCX/5mEMtpbqm+s4w3VBndBnvi3JG3eUxTU7TbK1bezuUYZBnhI98TOnaPdH0ts6pm60v00+JbYi9y2OaHKbGkGzQL/nMx5R+56Wo8tM5dI0GuyE7qjbqLo8JJbT9Y7CExxn95GNKX/tU+LbGoWmcVDspS1bCw2NaaiwNCT8lXBxzXPCTjwkL3bP4/SRd1NZoG8KqwjIjGiLu8pjJVcm1Oadz/iSNwSv85WNKx33Upv5VZ1RHtFXaWlIiPdwZfjcf0+ww221dth1BDwVWSh/5mNIq/+1UXaodKofKri5T35uPmdmS2Rr0ukGT2heHLR317ZBSH/XfIrWqnKoCtVMdp63VDs/HTK5Onqk6odof7J7BF4ftt/4Jab+qWjVTXaXOJMf0nY+pXa5tI127R60ERUBvDlv6ix8roN/lUhsNRakqX+WfxyRrzNDu1m6lDgZGFaC+lYZx2NhH+Kk/IO2WtkqVUp1UJWWqK9X+eUxs280u81z1XvW70rbhXyydp/ImlVNUfqRymcp70iCPeY+Cnh+tqtIn0luSS5orlUtWqUwKzGPS4cVsKjcVm1ym+/V79H+Up9mHVJ6jMovKWuW6nEoLlfVUPh9hyDZKl6Rc6WFVmapEXas2a8o0gXlMnKCwz6RDTUn20ux5eS/ldapXqHvIlHe29LDIrjvDQEFHSJ9K/i3wPK0SO6T31S3q+TQbSmg2pJASRmVGqAIeeqAIzhwFjxQUTGubVj+tfdpDmnWaIyP6x9Df09JJ1eOqlVKrVC85pQLEhNEoMEwROv7pra3WxJzFOdmxy2LthtmGBbpG3WOqZtVXAU2/XrqqXaPtUC9TN6nsNA+KVdlStZRIQ6EfrQLDeExSJsJQbIih1S41clZkgbHBWK+r17VJT0r/8KnAFemK6hnVWixO2nJtsbpcnaYuVseQ8LHzmDgMY9NBO6Do6MZoCx2I8g11hgZDi6GDZvxVeRj675y2qLg1WzSdmirNfCgQZg9LDSsOi9E4NTq1VR0ajykfiOk8kmxPTqXNaa6lylJFM2eJ4WXDdlLCjYgprwcHVR+QBVZoXdoZBpchP8wVdp82X2sKqwiL19RrohEXsFiFWcOC5zFxIJY3pVWWspSaFBeW/CRnUgt12KE6oPpIVuGcdEZdo14vK1GpnaOv1FeTIuW0UhaRVazaCu3UMEdYhs6qM8OqcY1xwfGYWE+w4TFXmhck2ZOaTVWmB+Kd8U/RF76oqlK9RnHknKpF9YaqQvWq2q5+lsz/kK5at1Dn0t1PZa7OrmvQO/XToZT8QZUpFmz1g+IxzVXm+RBurjYvMdeYlyY6Eh+Ms8f9lsb8FfL47TQDdqpsqtfp76103ax2qNsjXBHLIpwRLboq3SJSqEneytUYahAEaWiD5zGTyRYUxmeY7KYG2SIU0mWrOJJ+DSGaas0SGobFGrumWePS3E+WmAeh8ka2Wj/TUG2Yju09FEgqTho7j2muME+FKeV1hQpF0wLykSJ0rLfpSzAbMP5h1WGFcEp9ud5qrDbmkfCp2FHj6zEMIfOYFEVjQIzJswX8FZ2ePMVYYYzHLIh0RsZ5ihxfyAkx/uPKYw6lDL3LL8pjGsuMcompjflleEw6xiXp8/UmXMn0CVFVUbE4R0RkREQoSo1fPqYvHhMOCVrJ4DRUyPQS3cMh4YhGpzEFfhFmCjPASiHnY/rjMdU31N9Q0L6lnC1v4T7iUsTH8cfiO+M74hsxS2QCjpTB+qNQAKNfwDDWHh7T4DBMS9yUGBSPSUr1Gc4butAO7UEBBIqSPhWw2C1RaTVpaXQgGjuPeWeF7UF78KHob1T5mDKVTBrD/OkN6fbSM6V7QyZN6Ac+NH1W2ujyMT08JgjzkjMl+8ZDAc+v5HTJyPmYQ3lM1yHXtvFUwDOUAfMxMQxDecxJ/ZN6x1UJ5eQ+Yj7muPKYfrisgPmY8iIzXjymLxZnpHxMDAVWwnHhMUfJZfnMx0RQGjce0/tA1CX5zceEXHlI5H8x0aZjvHjM0XBZyMekDXMd5EK+NKVhigH+MC48pi9210c+pvYzzW3Ig1zIl7A005niDo85MI5D4cVl3fbisiAPciFfViKtNi1kHjMYLgtyIA9yZSVgDlorQuMxg+SyIAfyIFceDtkxacEKhccMisui/nNP5x6BPMiVHRNTJKkw7i6PORDiUPjjsi7frQM5kDc4RZGPGZ0RHZdQlFiQsTCjddL3tG6cUrip8woz4/X/Tu8vDsRlIR9zqIKT+ib1gi/F2QW7Ns8/XdS0cBnj8+Izo7OjZ5oeNe0fxk09p3BWx4co1KPcj4HLKjhRsB/nW/iD7JRDecy4nDgTRc3SyUsmt4XvCu+WBWG7Bq7qBSrv3Ak+niAk37+gvPfHZQ0MHyJDr6F7yvIpbdixIdvgHh5T2VHJPGbJ7hL/PKbbhz/0KYr0eT0fqgT1h35NjqS65PKETEtJgm8eE2cJD49p3WsdNY8p5VL5/ZC6N73q0ibR2mV9K74ofm5kaqQ1YVrc6HnMvD15o+cxA/iJJl9zKcIU8XB0VnQJ+Z8ZpNyI+ZgeHjPJnjRvcvvkTrVtFDwm/ORtLz9ZJ7lNq0zvpzemz6cJWUJbxxQ440hnkEFF5NwJmkYUVOpT56Q+lLAu4UigNAXvX/Tq6JOZrZkrpzRPqUc/6G80CtzDXaVWpyaC2JADS6V5gWm66bGIxojAPOZy6aq+Sd8xuXlyE7VyoD36wRAEfQrz8JjkHTFg7jxWSXQmtumf1PvkMaOuRF2JXBO5FkwN/Cq5PDkN7dFPSPmYiO3YiYNpwXkUtFFGS0ZHZHfkMB5T5Va587bkdeqqdPPpYFwsU46kANonWhMnhsfMfTl3u2pANchj5h7M/SDRkbgC/BYOw9g1ISDJ/w+vz5AZmyEKjQ+PmeBM6Mg+kC3zmMnnks8k1iSul5WoNMv5mMmu5HLwWnLcqTBPtTgsGThWwKo4aAWdj+mLx4ytiH0xtir2tcTjiedMLaY3YipiXo2zxw3Lx0TQw/CZnebpUGrMPKYnH9Obx4y1x74SVRa1PdoevTPaFv16dFn0z5OP6c1jmqvMi6Ac/c35mP9/8jH/Dwb5KMt4xKzwAAAAAElFTkSuQmCC')",
   // 4 = event
   "url('data:image/png;base64,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')",
   // 5 = wslm & native SL URs
   "url('data:image/png;base64,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')",
   // 6 = Elgin
   "url('data:image/png;base64,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')",
   // 7 = TrafficCast
   "url('data:image/png;base64,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')",
   // 8 = TrafficMaster
   "url('data:image/png;base64,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')",
   // 9 = CalTrans
   "url('data:image/png;base64,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')",
   // 10 = TfL
   "url('data:image/png;base64,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')",
   // 11 = boots on ground
   "url('data:image/png;base64,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')",
   // 12 = difficult turn
   "url('data:image/png;base64,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')",
];

 
var uroMarkers =
[
   // 0 = comment count circle
   ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90LCxYGJyle3m4AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAv1JREFUSMfFls1r3EYYxn+zo9XsqjuSxpBQU5OCDy0Y3JODs2Z36W6P/YBCk159s+/5F9Z/QsHkUAruZZ344Jx7KPTSa2/NwSdDE1ISf8SWI63k6UVLN8ZuZFnQ56IZDYwevR/P+wguh7jieXF9Gewla3vJWeELAfA8b9ZxnFWl1P0kST7NsswDkFJGrus+i+P4cZqmP0VR9JyKIWq12owx5kff95PBYBCPRiN7EaPRyA4Gg9j3/cQY80hK6VdFwFFK3TXGvOx0OoktiE6nExtjXjSbzYUb/T3QqNfrvSAITofDob0uhsOhDcPwTVkiAmgCC8aYV2UITBMxxrwok5oGcEdr/XR5eXlsb4g8NY+uVQPAh0KIr7XW6f7+vq0Cvu8nnufNvu/jtak03FZKfbe4uGjn5uYqqe6lpSXrOM5qERIS8IEZz/O66+vrTlUttra25iql7hfSImAB+DIIgrd7e3u2KhwcHNggCE6LREIBGlBZlqn5+fnK1C4MQybqWiQdKi/O/wWTwpSAkFLGWZZVdnkURUgpoyIk/t3Uas93dnYqI7G9vY3rus+KkLBABtgoin7f3NxMqyKxtbWVxHH8uIhUG+AT4CMhxK1Wq/XD8fGxrIJEEATjNE0/ft+IrwEx8AaIrbWH1tpfV1ZWbhyNbrc7llL+XMRjyDwdTt6mzSRJ/jw5Ofkiy7JGr9crRWBjY4Pd3d3XR0dH31hrz4pOTw18BnwFPBBCPPR9/6zsKA+C4FQpdbeoc3tngAErwLfA90KIh2EYHrbb7cITtd1uj40xr+r1eq+s7jSAO0A3J/IAWG21Wr9ordN+vz++yt71+/2x1jrVWj/NR0DjukbmHVcF3ALmgJl8L4UQoeu6n3ued+/8/Hw2yzKVG91YSvlXFEW/xXH8xFr7B/A38PYqZ13EbYtcwkPgdk7kgylZF1PWPc076xR4DbwEDvN3tmwkLtZIMx/xwWTA5d1ELm6T1j4CjoGznFgpX/lfZxJwpwhMR2JCJJkobllN+QeQNNGuneopoQAAAABJRU5ErkJggg=="],
   // 1 = green comment marker
   ["data:image/png;base64,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"],
   // 2 = yellow (own) comment marker
   ["data:image/png;base64,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"]
];

var uroFeedFilterReloads = 0;
var uroFeedFilterFilters =
[
   ['feed.issues.motivations.CAN_BE_SOLVED_BY_RANK',           'motivation'],
   ['feed.issues.motivations.CLOSE_TO_FAVORITES',              'motivation'],
   ['feed.issues.motivations.ISSUE_AGE',                       'motivation'],
   ['feed.issues.motivations.ISSUE_REOPENED',                  'motivation'],
   ['feed.issues.motivations.NEAR_DRIVES',                     'motivation'],
   ['feed.issues.motivations.REPORTED_BY_USER',                'motivation'],
   ['feed.issues.motivations.USER_FOLLOWS_ISSUE',              'motivation'],
   ['feed.issues.motivations.USER_FOLLOWS_ISSUE_LAST_COMMENT', 'motivation'],
   ['venues.update_requests.panel.flag_title.IMAGE',           'title'],
   ['venues.update_requests.panel.flag_title.VENUE',           'title'],
   ['venues.update_requests.panel.title.ADD_IMAGE',            'title'],
   ['venues.update_requests.panel.title.ADD_VENUE',            'title'],
   ['venues.update_requests.panel.title.DELETE_VENUE',         'title'],
   ['venues.update_requests.panel.title.UPDATE_VENUE',         'title']
];


/*
function uroAddDebug(debugtext)
{
   var ts = Math.round(performance.now());
   if(uroRecentDebug.length == 100)
   {
      uroRecentDebug.shift();
   }
   uroRecentDebug.push(ts+': '+debugtext);
   console.debug('URO+DBG '+ts+':'+debugtext);
}

function uroDumpDebug()
{
   if(uroRecentDebug.length > 0)
   {
      document.getElementById('WazeMap').innerHTML = '<textarea id="uroDbgOutput" style="width:100%;height:100%">';
      var dbgOutput = '';
      for(var i=0; i<uroRecentDebug.length; i++)
      {
         dbgOutput += uroRecentDebug[i]+'\n';
      }
      document.getElementById('uroDbgOutput').textContent = dbgOutput;
   }
}
*/

function uroTempFixMTEDropDown()
{
   // temporary fix for that bloody annoying bug in the closure event dropdown...  sort it out devs!
   // also removes the "Choose Event" non-option from the list, so that it now always starts with "None"
   if(document.getElementsByName('closure_eventId').length > 0)
   {
      if(document.getElementsByName('closure_eventId')[0].selectedOptions.length > 0)
      {
         document.getElementsByName('closure_eventId')[0].required = false;
         if(document.getElementsByName('closure_eventId')[0].selectedOptions[0].text == I18n.lookup('closures.choose_event'))
         {
            document.getElementsByName('closure_eventId')[0].selectedOptions[0].remove();
         }
      }
   }
}

function uroAddLog(logtext)
{
   if(uroShowDebugOutput) console.log('URO+: '+logtext);
}
function uroGetCBChecked(cbID)
{
   try
   {
      return(document.getElementById(cbID).checked);
   }
   catch(err)
   {
      return null;
   }
}
function uroSetCBChecked(cbID, state)
{
   try
   {
      document.getElementById(cbID).checked = state;
   }
   catch(err)
   {
   }
}
function uroGetElmValue(elmID)
{
   try
   {
      return(document.getElementById(elmID).value);
   }
   catch(err)
   {
      return null;
   }
}
function uroSetStyleDisplay(elm,style)
{
   try
   {
      document.getElementById(elm).style.display = style;
   }
   catch(err)
   {
   }
}
function uroSetOnClick(elm,fn)
{
   try
   {
      document.getElementById(elm).onclick = fn;
   }
   catch(err)
   {
   }
}
function uroAddEventListener(elm,eventType,eventFn,eventBool)
{
   try
   {
      document.getElementById(elm).addEventListener(eventType, eventFn, eventBool);
   }
   catch(err)
   {
   }
}


function uroAlertBoxObj(headericon, title, content, hasCross, tickText, crossText, tickAction, crossAction)
{
   this.headericon = headericon;
   this.title = title;
   this.content = content;
   this.hasCross = hasCross;
   this.tickText = tickText;
   this.crossText = crossText;
   this.tickAction = tickAction;
   this.crossAction = crossAction;
}
function uroCloseAlertBox()
{
   document.getElementById('uroAlerts').childNodes[0].innerHTML = '';
   document.getElementById('uroAlerts').childNodes[1].innerHTML = '';
   document.getElementById('uroAlertTickBtnCaption').innerHTML = '';
   document.getElementById('uroAlertCrossBtnCaption').innerHTML = '';
   uroAlertBoxTickAction = null;
   uroAlertBoxCrossAction = null;
   document.getElementById('uroAlerts').style.visibility = "hidden";
   document.getElementById('uroAlertCrossBtn').style.visibility = "hidden";
   uroAlertBoxInUse = false;
   if(uroAlertBoxStack.length > 0)
   {
      uroBuildAlertBoxFromStack();
   }
}
function uroCloseAlertBoxWithTick()
{
   if(typeof uroAlertBoxTickAction === 'function')
   {
      uroAlertBoxTickAction();
   }
   uroCloseAlertBox();
}
function uroCloseAlertBoxWithCross()
{
   if(typeof uroAlertBoxCrossAction === 'function')
   {
      uroAlertBoxCrossAction();
   }
   uroCloseAlertBox();
}
function uroShowAlertBox(headericon, title, content, hasCross, tickText, crossText, tickAction, crossAction)
{
   uroAlertBoxStack.push(new uroAlertBoxObj(headericon, title, content, hasCross, tickText, crossText, tickAction, crossAction));
   if(uroAlertBoxInUse === false)
   {
      uroBuildAlertBoxFromStack();
   }
}
function uroBuildAlertBoxFromStack()
{
   uroAlertBoxInUse = true;
   uroAlertBoxTickAction = null;
   uroAlertBoxCrossAction = null;
   var titleContent = '<span style="font-size:14px;padding:2px;">';
   titleContent += '<i class="fa '+uroAlertBoxStack[0].headericon+'"> </i>&nbsp;';
   titleContent += uroAlertBoxStack[0].title;
   titleContent += '</span>';
   document.getElementById('uroAlerts').childNodes[0].innerHTML = titleContent;
   document.getElementById('uroAlerts').childNodes[1].innerHTML = uroAlertBoxStack[0].content;
   document.getElementById('uroAlertTickBtnCaption').innerHTML = uroAlertBoxStack[0].tickText;
   if(uroAlertBoxStack[0].hasCross)
   {
      document.getElementById('uroAlertCrossBtnCaption').innerHTML = uroAlertBoxStack[0].crossText;
      document.getElementById('uroAlertCrossBtn').style.visibility = "visible";
      if(typeof uroAlertBoxStack[0].crossAction === "function")
      {
         uroAlertBoxCrossAction = uroAlertBoxStack[0].crossAction;
      }     
   }
   else
   {
      document.getElementById('uroAlertCrossBtn').style.visibility = "hidden";
   }
   if(typeof uroAlertBoxStack[0].tickAction === "function")
   {
      uroAlertBoxTickAction = uroAlertBoxStack[0].tickAction;
   }   
   document.getElementById('uroAlerts').style.visibility = "";
   uroAlertBoxStack.shift();
}


function uroFirstTimerWelcomePack()
{
   uroAddLog('welcome new users to Club URO...');

   // for now, just show the update notes...
   uroShowUpdateNotes();
}
function uroShowUpdateNotes()
{
   uroAddLog('let existing users know what\'s new in this release');

   var releaseNotes = '';
   releaseNotes += '<p>Thanks for upgrading to URO+ '+uroVersion+' ('+uroReleaseDate+').  What\'s changed?</p>';

   var loop;
   if(uroChanges.length > 0)
   {
      releaseNotes += '<ul>';
      for(loop=0; loop < uroChanges.length; loop++)
      {
         releaseNotes += '<li>'+uroChanges[loop];
      }
      releaseNotes += '</ul>';
   }
   if((uroBetaEditor) && (uroBetaChanges.length > 0))
   {
      releaseNotes += '<p>For WME Beta:<p>';
      releaseNotes += '<ul>';
      for(loop=0; loop < uroBetaChanges.length; loop++)
      {
         releaseNotes += '<li>'+uroBetaChanges[loop];
      }
      releaseNotes += '</ul>';
   }
   
   uroShowAlertBox('fa-info-circle', 'URO+ Release Notes', releaseNotes, false, "OK", "", null, null);
}
function uroAdvertiseCustomIcons()
{
   /*
   //// TEMPORARY REMOVAL UNTIL CUSTOM ICON SUPPORT IS FIXED IN NEW WME
   uroAddLog('advertise the benefits of custom UR icons...');

   var confirmMsg = '';
   confirmMsg += '<p>Hi there.  One of the features of URO+ that a lot of users find useful is the ability to use a custom marker for URs and MPs which have been tagged with a specific keyword in their description text.</p>';
   confirmMsg += '<p>Markers are defined for <b>[ROADWORKS]</b>, <b>[CONSTRUCTION]</b>, <b>[CLOSURE]</b>, <b>[EVENT]</b>, <b>[NOTE]</b>, <b>[WSLM]</b>, <b>[BOG]</b> and <b>[DIFFICULT]</b> tags in URs, and <b>[TfL Open Data]</b>, <b>[Elgin]</b>, <b>[TM]</b>, <b>[TrafficCast]</b> and <b>[Caltrans]</b> in MPs.</p>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[1]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[0]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[4]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[3]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[5]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[11]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[12]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[10]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[6]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[8]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[7]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<div style="background-image:'+uroAltMarkers[9]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
   confirmMsg += '<p style="clear:left;">Would you like me to automatically enable these custom markers?</p>';
   confirmMsg += '<p>If you change your mind later on, they can be enabled/disabled via the Misc tab within the URO+ settings</p>';
   
   uroShowAlertBox('fa-info-circle', 'URO+ Message to Users', confirmMsg, true, 'Yes please', 'No thanks', uroSetMarkerCBs, null);
   */
}

function uroSetMarkerCBs()
{
   uroSetCBChecked('_cbCustomRoadworksMarkers', true);
   uroSetCBChecked('_cbCustomConstructionMarkers', true);
   uroSetCBChecked('_cbCustomClosuresMarkers', true);
   uroSetCBChecked('_cbCustomEventsMarkers', true);
   uroSetCBChecked('_cbCustomNotesMarkers', true);
   uroSetCBChecked('_cbCustomBOGMarkers', true);
   uroSetCBChecked('_cbCustomDifficultMarkers', true);
   uroSetCBChecked('_cbCustomWSLMMarkers', true);
   uroSetCBChecked('_cbCustomNativeSLMarkers', true);
   uroSetCBChecked('_cbCustomElginMarkers', true);
   uroSetCBChecked('_cbCustomTrafficMasterMarkers', true);
   uroSetCBChecked('_cbCustomTrafficCastMarkers', true);
   uroSetCBChecked('_cbCustomCaltransMarkers', true);
   uroSetCBChecked('_cbCustomTFLMarkers', true);
}

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++)
   {
      var camObj = uroCamWatchObjects[loop];
      if((camObj.fid != null) && (camObj.persistent === true))
      {
         if(loop > 0) liststr += ':';

         liststr += camObj.fid+',';
         liststr += camObj.watch.lon+',';
         liststr += camObj.watch.lat+',';
         liststr += camObj.watch.type+',';
         liststr += camObj.watch.azymuth+',';
         liststr += camObj.watch.speed+',';
         liststr += camObj.watch.validated+',';
         liststr += camObj.groupID+',';
         liststr += camObj.server;
      }
   }
   return liststr;
}
function uroGatherSegWatchList()
{
   var liststr = '';
   for(var loop=0;loop<uroSegWatchObjects.length;loop++)
   {
      var segObj = uroSegWatchObjects[loop];
      if((segObj.fid != null) && (segObj.persistent === true))
      {
         if(loop > 0) liststr += ':';

         liststr += segObj.fid+',';
         liststr += segObj.watch.left+',';
         liststr += segObj.watch.right+',';
         liststr += segObj.watch.bottom+',';
         liststr += segObj.watch.top+',';
         liststr += segObj.watch.fromNode+',';
         liststr += segObj.watch.toNode+',';
         liststr += segObj.watch.fwdDir+',';
         liststr += segObj.watch.revDir+',';
         liststr += segObj.watch.length+',';
         liststr += segObj.watch.level+',';
         liststr += segObj.watch.rank+',';
         liststr += segObj.watch.roadType+',';
         liststr += segObj.watch.updatedOn+',';
         liststr += segObj.groupID+',';
         liststr += segObj.server;
      }
   }
   return liststr;
}
function uroGatherPlaceWatchList()
{
   var liststr = '';
   for(var loop=0;loop<uroPlaceWatchObjects.length;loop++)
   {
      var placeObj = uroPlaceWatchObjects[loop];
      if((placeObj.fid != null) && (placeObj.persistent === true))
      {
         if(loop > 0) liststr += ':';

         liststr += placeObj.fid+',';
         liststr += placeObj.watch.left+',';
         liststr += placeObj.watch.right+',';
         liststr += placeObj.watch.bottom+',';
         liststr += placeObj.watch.top+',';
         liststr += placeObj.watch.name+',';
         liststr += placeObj.watch.imageCount+',';
         liststr += placeObj.watch.residential+',';
         liststr += placeObj.watch.updatedOn+',';
         liststr += placeObj.groupID+',';
         liststr += placeObj.server;
      }
   }
   return liststr;
}
function uroGatherCWLGroups()
{
   var liststr = '';
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      var groupObj = uroCWLGroups[loop];
      if(groupObj.groupID != -1)
      {
         if(loop > 0) liststr += ':';

         liststr += groupObj.groupID+',';
         liststr += groupObj.groupName+',';
         liststr += groupObj.groupCollapsed;
      }
   }
   return liststr;
}
function uroGatherPlacesGroups()
{
   var liststr = '';
   for(var loop=0;loop<uroPlacesGroupsCollapsed.length;loop++)
   {
      if(loop > 0) liststr += ':';
      liststr += uroPlacesGroupsCollapsed[loop];
   }
   return liststr;
}
function uroGatherFriendlyAreaNames()
{
   var liststr = '';
   for(var loop=0;loop<uroFriendlyAreaNames.length;loop++)
   {
      var fnObj = uroFriendlyAreaNames[loop];
      if(loop > 0) liststr += ':';

      liststr += fnObj.fName+',';
      liststr += fnObj.area+',';
      liststr += fnObj.server;
   }
   return liststr;
}
function uroSaveSettings()
{
   if(uroInhibitSave)
   {
      uroAddLog('save inhibited');
      return;
   }

   if (localStorage)
   {
      localStorage.UROverviewUROptions = uroGatherSettings('uroCtrlURs');
      localStorage.UROverviewMPOptions = uroGatherSettings('uroCtrlMPs');
      localStorage.UROverviewCameraOptions = uroGatherSettings('uroCtrlCameras');
      localStorage.UROverviewMiscOptions = uroGatherSettings('uroCtrlMisc');
      localStorage.UROverviewPlacesOptions = uroGatherSettings('uroCtrlPlaces');
      localStorage.UROverviewCamWatchList = uroGatherCamWatchList();
      localStorage.UROverviewSegWatchList = uroGatherSegWatchList();
      localStorage.UROverviewPlaceWatchList = uroGatherPlaceWatchList();
      localStorage.UROverviewCWLGroups = uroGatherCWLGroups();
      localStorage.UROverviewFriendlyAreaNames = uroGatherFriendlyAreaNames();
      localStorage.UROverviewPlacesGroups = uroGatherPlacesGroups();

      localStorage.UROverviewMasterEnable = uroGetCBChecked('_cbMasterEnable');
      localStorage.UROverviewCurrentVersion = uroVersion;

      uroAddLog('save complete');
   }
   else
   {
      uroAddLog('no localStorage, save blocked');
   }
}
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)
         {
            uroSetCBChecked(fields[0], (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 = [];
   if(objects.length > 0)
   {    
      for(var objIdx=0;objIdx<objects.length;objIdx++)
      {
         var fields = objects[objIdx].split(',');
         if(fields.length >= 7)
         {
            // following two bits of code add in blank fields if the user has updated their copy of URO+ from an
            // older version which didn't include support for either of these field types

            // add default groupID field
            if(fields.length == 7)
            {
               fields.push(0);
            }
            // set default groupID value to 0 (no group)
            if(fields[7] == -1)
            {
               fields[7] = 0;
            }

            // add default server field
            if(fields.length == 8)
            {
               fields.push('??');
            }
            // set default server value to unknown
            if(fields[8] === 0)
            {
               fields[8] = '??';
            }

            uroCamWatchObjects.push(new uroCamWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8]));
         }
      }
   }
}
/*
function uroApplySegWatchList()
{
   var objects = localStorage.UROverviewSegWatchList.split(':');
   uroSegWatchObjects = [];

   for(var objIdx=0;objIdx<objects.length;objIdx++)
   {
      var fields = objects[objIdx].split(',');
      uroSegWatchObjects.push(new uroSegWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8],fields[9],fields[10],fields[11],fields[12],fields[13],fields[14],fields[15]));
   }
}
function uroApplyPlaceWatchList()
{
   var objects = localStorage.UROverviewPlaceWatchList.split(':');
   uroPlaceWatchObjects = [];

   for(var objIdx=0;objIdx<objects.length;objIdx++)
   {
      var fields = objects[objIdx].split(',');
      uroPlaceWatchObjects.push(new uroPlaceWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8],fields[9],fields[10]));
   }
}
*/
function uroApplyCWLGroups()
{
   var objects = localStorage.UROverviewCWLGroups.split(':');
   uroCWLGroups = [];
   
   if(objects.length === 0)
   {
      uroCWLGroups.push(new uroOWLGroupObj(0,'No group',false));
   }
   else
   {
      for(var objIdx=0;objIdx<objects.length;objIdx++)
      {
         var fields = objects[objIdx].split(',');
         if(fields.length < 2)
         {
            fields.push(false);
         }
         uroCWLGroups.push(new uroOWLGroupObj(fields[0],fields[1],(fields[2] == 'true')));
      }
   }
}
/*
function uroApplyPlacesGroups()
{
   var t = localStorage.UROverviewPlacesGroups.split(':');
   for(var i=0;i<t.length;i++)
   {
      uroPlacesGroupsCollapsed[i] = (t[i] == "true");
   }
}
*/
function uroApplyFriendlyAreaNames()
{
   var objects = localStorage.UROverviewFriendlyAreaNames.split(':');
   uroFriendlyAreaNames = [];

   for(var objIdx=0;objIdx<objects.length;objIdx++)
   {
      var fields = objects[objIdx].split(',');
      uroFriendlyAreaNames.push(new uroAFNObj(fields[0],parseFloat(fields[1]),fields[2]));
   }

   uroReplaceAreaNames(true);
}
function uroTranslateLegacyMPTabSettings()
{
   var options = localStorage.UROverviewMPOptions.split(':');
   for(var optIdx=0;optIdx<options.length;optIdx++)
   {
      var fields = options[optIdx].split(',');
      if(fields[0].indexOf('_cb') === 0)
      {
         if(fields[0] == '_cbMPFilterParkingLotInputAsPoint') uroSetCBChecked('_cbMPFilter_T50', (fields[1] == 'true'));
         if(fields[0] == '_cbMPMissingPLP_T70') uroSetCBChecked('_cbMPFilter_T70', (fields[1] == 'true'));
         if(fields[0] == '_cbMPMissingPLP_T71') uroSetCBChecked('_cbMPFilter_T71', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterDrivingDirectionMismatch') uroSetCBChecked('_cbMPFilter_T101', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterMissingJunction') uroSetCBChecked('_cbMPFilter_T102', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterMissingRoad') uroSetCBChecked('_cbMPFilter_T103', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterCrossroadsJunctionMissing') uroSetCBChecked('_cbMPFilter_T104', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterRoadTypeMismatch') uroSetCBChecked('_cbMPFilter_T105', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterRestrictedTurn') uroSetCBChecked('_cbMPFilter_T106', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterTurnProblem') uroSetCBChecked('_cbMPFilter_T200', (fields[1] == 'true'));
         if(fields[0] == '_cbMPFilterRoadClosureProblem') uroSetCBChecked('_cbMPFilter_T300', (fields[1] == 'true'));
      }
   }
   
}
function uroLoadSettings()
{
   var isNewInstall = true;
   var isUpgradeInstall = true;
   var notifyAboutCustomIcons = true;

   uroAddLog('loadSettings()');
   if (localStorage.UROverviewUROptions != null)
   {
      uroAddLog('recover UR tab settings');
      uroApplySettings(localStorage.UROverviewUROptions);
      isNewInstall = false;
   }

   if (localStorage.UROverviewCameraOptions != null)
   {
      uroAddLog('recover camera tab settings');
      uroApplySettings(localStorage.UROverviewCameraOptions);
      isNewInstall = false;
   }

   if (localStorage.UROverviewMPOptions != null)
   {
      uroAddLog('recover MP tab settings');
      uroTranslateLegacyMPTabSettings();
      uroApplySettings(localStorage.UROverviewMPOptions);
      isNewInstall = false;
   }

   if (localStorage.UROverviewPlacesOptions != null)
   {
      uroAddLog('recover Places tab settings');
      uroApplySettings(localStorage.UROverviewPlacesOptions);
      isNewInstall = false;
   }

   if (localStorage.UROverviewMiscOptions != null)
   {
      uroAddLog('recover misc tab settings');
      uroApplySettings(localStorage.UROverviewMiscOptions);
      isNewInstall = false;

      if(localStorage.UROverviewCurrentVersion != null)
      {
         notifyAboutCustomIcons = false;
      }
      else
      {
         if(uroGetCBChecked('_cbCustomRoadworksMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomConstructionMarkers')=== true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomClosuresMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomEventsMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomNotesMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomWSLMMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomBOGMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomDifficultMarkers') === true) notifyAboutCustomIcons = false;
         if(uroGetCBChecked('_cbCustomNativeSLMarkers') === true) notifyAboutCustomIcons = false;
      }
   }

   if(localStorage.UROverviewCWLGroups != null)
   {
      uroAddLog('recover CWL groups');
      uroApplyCWLGroups();
      isNewInstall = false;
   }
   else
   {
      uroAddLog('set default CWL group');
      uroCWLGroups.push(new uroOWLGroupObj(0,'No group',false));
   }

   if(localStorage.UROverviewCamWatchList != null)
   {
      uroAddLog('recover camera watchlist');
      uroApplyCamWatchList();
      uroGetCurrentCamWatchListObjects();    
      isNewInstall = false;
   }
/*
   if(localStorage.UROverviewSegWatchList != null)
   {
      uroAddLog('recover segment watchlist');
      uroApplySegWatchList();
      uroGetCurrentSegWatchListObjects();
      isNewInstall = false;
   }

   if(localStorage.UROverviewPlaceWatchList != null)
   {
      uroAddLog('recover places watchlist');
      uroApplyPlaceWatchList();
      //uroGetCurrentPlaceWatchListObjects();
      isNewInstall = false;
   }

   if(localStorage.UROverviewPlacesGroups != null)
   {
      uroAddLog('recover places groups');
      uroApplyPlacesGroups();
      isNewInstall = false;
   }
*/
   if(localStorage.UROverviewCurrentVersion != null)
   {
      uroAddLog('comparing install versions');
      if(localStorage.UROverviewCurrentVersion == uroVersion)
      {
         isUpgradeInstall = false;
      }
   }

   if(localStorage.UROverviewFriendlyAreaNames != null)
   {
      uroAddLog('recover friendly area names');
      uroApplyFriendlyAreaNames();
      isNewInstall = false;
   }

   if(localStorage.UROverviewMasterEnable != null)
   {
      uroAddLog('recover master enable state');
      document.getElementById('_cbMasterEnable').checked = (localStorage.UROverviewMasterEnable == "true");
   }

   if(isNewInstall)
   {
      uroFirstTimerWelcomePack();
   }
   else if(isUpgradeInstall)
   {
      uroShowUpdateNotes();
   }

   if(notifyAboutCustomIcons)
   {
      uroAdvertiseCustomIcons();  
   }

   uroInhibitSave = false;
}
function uroDefaultSettings()
{
   uroShowAlertBox("fa-warning", "URO+ Warning", "Resetting URO+ settings <b>cannot</b> be undone.<br>Are you <i>sure</i> you want to do this?", true, "Reset settings", "Keep settings", uroDefaultSettingsAction, null);
}
function uroDefaultSettingsAction()
{
   var defaultSettings = '';
   
   defaultSettings += '[UROverviewMPOptions][len=788]:_cbMPFilterParkingLotInputAsPoint,false:_cbMPFilterMissingJunction,false:_cbMPFilterMissingRoad,false:_cbMPFilterCrossroadsJunctionMissing,false:_cbMPFilterDrivingDirectionMismatch,false:_cbMPFilterRoadTypeMismatch,false:_cbMPFilterRestrictedTurn,false:_cbMPFilterRoadClosureProblem,false:_cbMPFilterUnknownProblem,false:_cbMPFilterTurnProblem,false:_cbFilterElgin,false:_cbFilterTrafficCast,false:_cbFilterTrafficMaster,false:_cbFilterCaltrans,false:_cbFilterTFL,false:_cbMPFilterReopenedProblem,false:_cbInvertMPFilter,false:_cbMPFilterOutsideArea,false:_cbMPFilterClosed,false:_cbMPFilterSolved,false:_cbMPFilterUnidentified,false:_cbMPClosedUserIDFilter,false:_cbMPNotClosedUserIDFilter,false:_cbMPFilterLowSeverity,false:_cbMPFilterMediumSeverity,false:_cbMPFilterHighSeverity,false[END]';
   defaultSettings += '[UROverviewPlaceWatchList][len=0][END]';
   defaultSettings += '[UROverviewSegWatchList][len=0][END]';
   defaultSettings += '[UROverviewPlacesGroups][len=65]false:false:false:false:false:false:false:false:false:false:false[END]';
   defaultSettings += '[UROverviewMasterEnable][len=4]true[END]';
   defaultSettings += '[UROverviewFriendlyAreaNames][len=0][END]';
   defaultSettings += '[UROverviewMiscOptions][len=1337]:_cbNativeConvoMarkers,true:_cbNativeBetaConvoMarkers,true:_cbCommentCount,false:_cbURBackfill,false:_inputUnstackSensitivity,15:_inputUnstackZoomLevel,3:_cbCustomRoadworksMarkers,false:_cbCustomConstructionMarkers,false:_cbCustomClosuresMarkers,false:_cbCustomEventsMarkers,false:_cbCustomNotesMarkers,false:_cbCustomBOGMarkers,false:_cbCustomDifficultMarkers,false:_cbCustomWSLMMarkers,false:_cbCustomNativeSLMarkers,false:_cbCustomKeywordMarkers,false:_textCustomKeyword,:_cbCustomElginMarkers,false:_cbCustomTrafficMasterMarkers,false:_cbCustomTrafficCastMarkers,false:_cbCustomCaltransMarkers,false:_cbCustomTFLMarkers,false:_inputPopupDwellTimeout,2:_inputPopupEntryTimeout,2:_inputMaxJitter,2:_cbInhibitURPopup,false:_cbInhibitMPPopup,false:_cbInhibitCamPopup,false:_cbInhibitSegPopup,false:_cbInhibitSegGenericPopup,false:_cbInhibitTurnsPopup,false:_cbInhibitLandmarkPopup,false:_cbInhibitPUPopup,false:_cbDateFmtDDMMYY,true:_cbDateFmtMMDDYY,false:_cbDateFmtYYMMDD,false:_cbTimeFmt24H,true:_cbTimeFmt12H,false:_cbWhiteBackground,false:_inputCustomBackgroundRed,255:_inputCustomBackgroundGreen,255:_inputCustomBackgroundBlue,255:_cbInhibitNURButton,false:_cbInhibitNMPButton,false:_cbInhibitNPURButton,false:_cbHideAMLayer,false:_cbDisablePlacesFiltering,false:_cbDisableTabStyling,false:_cbHideEditorInfo,false:_cbEnableDTE,false[END]';
   defaultSettings += '[UROverviewUROptions][len=1756]:_cbURFilterOutsideArea,false:_cbNoFilterForURInURL,false:_cbFilterWazeAuto,false:_cbFilterIncorrectTurn,false:_cbFilterIncorrectAddress,false:_cbFilterIncorrectRoute,false:_cbFilterMissingRoundabout,false:_cbFilterGeneralError,false:_cbFilterTurnNotAllowed,false:_cbFilterIncorrectJunction,false:_cbFilterMissingBridgeOverpass,false:_cbFilterWrongDrivingDirection,false:_cbFilterMissingExit,false:_cbFilterMissingRoad,false:_cbFilterBlockedRoad,false:_cbFilterMissingLandmark,false:_cbFilterSpeedLimits,false:_cbFilterUndefined,false:_cbFilterRoadworks,false:_cbFilterConstruction,false:_cbFilterClosure,false:_cbFilterEvent,false:_cbFilterNote,false:_cbFilterBOG,false:_cbFilterDifficult,false:_cbFilterWSLM,false:_cbInvertURFilter,false:_cbFilterOpenUR,false:_cbFilterClosedUR,false:_cbFilterSolved,false:_cbFilterUnidentified,false:_cbEnableMinAgeFilter,false:_inputFilterMinDays,:_cbEnableMaxAgeFilter,false:_inputFilterMaxDays,:_cbHideMyFollowed,false:_cbHideMyUnfollowed,false:_cbURDescriptionMustBePresent,false:_cbURDescriptionMustBeAbsent,false:_cbEnableKeywordMustBePresent,false:_textKeywordPresent,:_cbEnableKeywordMustBeAbsent,false:_textKeywordAbsent,:_cbCaseInsensitive,false:_cbHideMyComments,false:_cbHideAnyComments,false:_cbHideIfLastCommenter,false:_cbHideIfNotLastCommenter,false:_cbHideIfReporterLastCommenter,false:_cbHideIfReporterNotLastCommenter,false:_cbEnableMinCommentsFilter,false:_inputFilterMinComments,:_cbEnableMaxCommentsFilter,false:_inputFilterMaxComments,:_cbEnableCommentAgeFilter2,false:_inputFilterCommentDays2,:_cbEnableCommentAgeFilter,false:_inputFilterCommentDays,:_cbIgnoreOtherEditorComments,false:_cbURUserIDFilter,false:_cbURResolverIDFilter,false:_cbInvertURStateFilter,false:_cbNoFilterForTaggedURs,false[END]';
   defaultSettings += '[UROverviewCameraOptions][len=878]:_cbShowWorldCams,true:_cbShowUSACams,true:_cbShowNonWorldCams,true:_cbShowOnlyCamsCreatedBy,false:_cbShowOnlyCamsEditedBy,false:_textCameraEditor,:_cbShowOnlyMyCams,false:_cbShowApprovedCams,true:_cbShowNonApprovedCams,true:_cbShowOlderCreatedNonApproved,false:_inputCameraMinCreatedDays,:_cbShowOlderUpdatedNonApproved,false:_inputCameraMinUpdatedDays,:_cbShowSpeedCams,true:_cbShowIfSpeedSet,true:_cbShowIfNoSpeedSet,true:_cbShowRedLightCams,true:_cbShowDummyCams,true:_cbHideCreatedByMe,false:_cbHideCreatedByRank0,false:_cbHideCreatedByRank1,false:_cbHideCreatedByRank2,false:_cbHideCreatedByRank3,false:_cbHideCreatedByRank4,false:_cbHideCreatedByRank5,false:_cbHideUpdatedByMe,false:_cbHideUpdatedByRank0,false:_cbHideUpdatedByRank1,false:_cbHideUpdatedByRank2,false:_cbHideUpdatedByRank3,false:_cbHideUpdatedByRank4,false:_cbHideUpdatedByRank5,false:_cbHideCWLCams,false[END]';
   defaultSettings += '[UROverviewCamWatchList][len=0][END]';
   defaultSettings += '[UROverviewPlacesOptions][len=5421]:_cbFilterUneditablePlaceUpdates,false:_cbFilterLockRankedPlaceUpdates,false:_cbFilterNewPlacePUR,false:_cbFilterUpdatedDetailsPUR,false:_cbFilterNewPhotoPUR,false:_cbFilterFlaggedPUR,false:_cbLeavePURGeos,false:_cbInvertPURFilters,false:_cbPURFilterLowSeverity,false:_cbPURFilterMediumSeverity,false:_cbPURFilterHighSeverity,false:_cbEnablePURMinAgeFilter,false:_inputPURFilterMinDays,:_cbEnablePURMaxAgeFilter,false:_inputPURFilterMaxDays,:_cbPlaceFilterEditedLessThan,false:_inputFilterPlaceEditMinDays,:_cbPlaceFilterEditedMoreThan,false:_inputFilterPlaceEditMaxDays,:_cbHidePlacesL0,false:_cbHidePlacesL1,false:_cbHidePlacesL2,false:_cbHidePlacesL3,false:_cbHidePlacesL4,false:_cbHidePlacesL5,false:_cbHidePlacesStaff,false:_cbHidePlacesAdLocked,false:_cbHideAreaPlaces,false:_cbHidePointPlaces,false:_cbHidePhotoPlaces,false:_cbHideNoPhotoPlaces,false:_cbHideLinkedPlaces,false:_cbHideNoLinkedPlaces,false:_cbHideKeywordPlaces,false:_cbHideNoKeywordPlaces,false:_textKeywordPlace,:_cbShowOnlyPlacesCreatedBy,false:_cbShowOnlyPlacesEditedBy,false:_textPlacesEditor,:_cbPlacesFilter-CAR_SERVICES,false:_cbPlacesFilter-GAS_STATION,false:_cbPlacesFilter-GARAGE_AUTOMOTIVE_SHOP,false:_cbPlacesFilter-CAR_WASH,false:_cbPlacesFilter-CHARGING_STATION,false:_cbPlacesFilter-TRANSPORTATION,false:_cbPlacesFilter-AIRPORT,false:_cbPlacesFilter-BUS_STATION,false:_cbPlacesFilter-FERRY_PIER,false:_cbPlacesFilter-SEAPORT_MARINA_HARBOR,false:_cbPlacesFilter-SUBWAY_STATION,false:_cbPlacesFilter-TRAIN_STATION,false:_cbPlacesFilter-BRIDGE,false:_cbPlacesFilter-TUNNEL,false:_cbPlacesFilter-TAXI_STATION,false:_cbPlacesFilter-JUNCTION_INTERCHANGE,false:_cbPlacesFilter-PROFESSIONAL_AND_PUBLIC,false:_cbPlacesFilter-COLLEGE_UNIVERSITY,false:_cbPlacesFilter-SCHOOL,false:_cbPlacesFilter-CONVENTIONS_EVENT_CENTER,false:_cbPlacesFilter-GOVERNMENT,false:_cbPlacesFilter-LIBRARY,false:_cbPlacesFilter-CITY_HALL,false:_cbPlacesFilter-ORGANIZATION_OR_ASSOCIATION,false:_cbPlacesFilter-PRISON_CORRECTIONAL_FACILITY,false:_cbPlacesFilter-COURTHOUSE,false:_cbPlacesFilter-CEMETERY,false:_cbPlacesFilter-FIRE_DEPARTMENT,false:_cbPlacesFilter-POLICE_STATION,false:_cbPlacesFilter-MILITARY,false:_cbPlacesFilter-HOSPITAL_MEDICAL_CARE,false:_cbPlacesFilter-OFFICES,false:_cbPlacesFilter-POST_OFFICE,false:_cbPlacesFilter-RELIGIOUS_CENTER,false:_cbPlacesFilter-KINDERGARDEN,false:_cbPlacesFilter-FACTORY_INDUSTRIAL,false:_cbPlacesFilter-EMBASSY_CONSULATE,false:_cbPlacesFilter-INFORMATION_POINT,false:_cbPlacesFilter-SHOPPING_AND_SERVICES,false:_cbPlacesFilter-ARTS_AND_CRAFTS,false:_cbPlacesFilter-BANK_FINANCIAL,false:_cbPlacesFilter-SPORTING_GOODS,false:_cbPlacesFilter-BOOKSTORE,false:_cbPlacesFilter-PHOTOGRAPHY,false:_cbPlacesFilter-CAR_DEALERSHIP,false:_cbPlacesFilter-FASHION_AND_CLOTHING,false:_cbPlacesFilter-CONVENIENCE_STORE,false:_cbPlacesFilter-PERSONAL_CARE,false:_cbPlacesFilter-DEPARTMENT_STORE,false:_cbPlacesFilter-PHARMACY,false:_cbPlacesFilter-ELECTRONICS,false:_cbPlacesFilter-FLOWERS,false:_cbPlacesFilter-FURNITURE_HOME_STORE,false:_cbPlacesFilter-GIFTS,false:_cbPlacesFilter-GYM_FITNESS,false:_cbPlacesFilter-SWIMMING_POOL,false:_cbPlacesFilter-HARDWARE_STORE,false:_cbPlacesFilter-MARKET,false:_cbPlacesFilter-SUPERMARKET_GROCERY,false:_cbPlacesFilter-JEWELRY,false:_cbPlacesFilter-LAUNDRY_DRY_CLEAN,false:_cbPlacesFilter-SHOPPING_CENTER,false:_cbPlacesFilter-MUSIC_STORE,false:_cbPlacesFilter-PET_STORE_VETERINARIAN_SERVICES,false:_cbPlacesFilter-TOY_STORE,false:_cbPlacesFilter-TRAVEL_AGENCY,false:_cbPlacesFilter-ATM,false:_cbPlacesFilter-CURRENCY_EXCHANGE,false:_cbPlacesFilter-CAR_RENTAL,false:_cbPlacesFilter-FOOD_AND_DRINK,false:_cbPlacesFilter-RESTAURANT,false:_cbPlacesFilter-BAKERY,false:_cbPlacesFilter-DESSERT,false:_cbPlacesFilter-CAFE,false:_cbPlacesFilter-FAST_FOOD,false:_cbPlacesFilter-FOOD_COURT,false:_cbPlacesFilter-BAR,false:_cbPlacesFilter-ICE_CREAM,false:_cbPlacesFilter-CULTURE_AND_ENTERTAINEMENT,false:_cbPlacesFilter-ART_GALLERY,false:_cbPlacesFilter-CASINO,false:_cbPlacesFilter-CLUB,false:_cbPlacesFilter-TOURIST_ATTRACTION_HISTORIC_SITE,false:_cbPlacesFilter-MOVIE_THEATER,false:_cbPlacesFilter-MUSEUM,false:_cbPlacesFilter-MUSIC_VENUE,false:_cbPlacesFilter-PERFORMING_ARTS_VENUE,false:_cbPlacesFilter-GAME_CLUB,false:_cbPlacesFilter-STADIUM_ARENA,false:_cbPlacesFilter-THEME_PARK,false:_cbPlacesFilter-ZOO_AQUARIUM,false:_cbPlacesFilter-RACING_TRACK,false:_cbPlacesFilter-THEATER,false:_cbPlacesFilter-OTHER,false:_cbPlacesFilter-CONSTRUCTION_SITE,false:_cbPlacesFilter-LODGING,false:_cbPlacesFilter-HOTEL,false:_cbPlacesFilter-HOSTEL,false:_cbPlacesFilter-CAMPING_TRAILER_PARK,false:_cbPlacesFilter-COTTAGE_CABIN,false:_cbPlacesFilter-BED_AND_BREAKFAST,false:_cbPlacesFilter-OUTDOORS,false:_cbPlacesFilter-PARK,false:_cbPlacesFilter-PLAYGROUND,false:_cbPlacesFilter-BEACH,false:_cbPlacesFilter-SPORTS_COURT,false:_cbPlacesFilter-GOLF_COURSE,false:_cbPlacesFilter-PLAZA,false:_cbPlacesFilter-PROMENADE,false:_cbPlacesFilter-POOL,false:_cbPlacesFilter-SCENIC_LOOKOUT_VIEWPOINT,false:_cbPlacesFilter-SKI_AREA,false:_cbPlacesFilter-NATURAL_FEATURES,false:_cbPlacesFilter-ISLAND,false:_cbPlacesFilter-SEA_LAKE_POOL,false:_cbPlacesFilter-RIVER_STREAM,false:_cbPlacesFilter-FOREST_GROVE,false:_cbPlacesFilter-FARM,false:_cbPlacesFilter-CANAL,false:_cbPlacesFilter-SWAMP_MARSH,false:_cbPlacesFilter-DAM,false:_cbPlacesFilter-PARKING_LOT,false:_cbFilterPrivatePlaces,false:_cbInvertPlacesFilter,false[END]';
   defaultSettings += '[UROverviewCurrentVersion][len=0][END]';
   defaultSettings += '[UROverviewCWLGroups][len=16]0,No group,false[END]'; 
   
   document.getElementById('_txtSettings').value = defaultSettings;
   uroTextToSettings();
   document.getElementById('_txtSettings').value = '';
}
function uroSettingsToText()
{
   var txtSettings = '';

   uroSaveSettings();

   for(var lsEntry in localStorage)
   {
      if(lsEntry.indexOf('UROverview') === 0)
      {
         txtSettings += '['+lsEntry+'][len=' + localStorage[lsEntry].length + ']' + localStorage[lsEntry] + '[END]\n';
      }
   }

   document.getElementById('_txtSettings').value = txtSettings;
   document.getElementById('_txtSettings').focus();
   document.getElementById('_txtSettings').select();
}
function uroTextToSettings()
{
   var txtSettings = '';
   txtSettings = uroGetElmValue('_txtSettings');
   if(txtSettings.indexOf('[END]') == -1) return;

   var subText = txtSettings.split('[END]');
   for(var i=0;i<subText.length;i++)
   {
      var aPos = subText[i].indexOf('[');
      var bPos = subText[i].indexOf(']');
      if((aPos != -1) && (bPos != -1))
      {
         var settingID = subText[i].substr(aPos+1,bPos-1-aPos);
         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)
            {
               localStorage[settingID] = subText[i];
            }
         }
      }
   }
   uroLoadSettings();
}
function uroClearSettingsText()
{
   document.getElementById('_txtSettings').value = '';
}


function uroDateToDays(dateToConvert)
{
   var dateNow = new Date();

   var elapsedSinceEpoch = dateNow.getTime();
   var elapsedSinceEvent = elapsedSinceEpoch - dateToConvert;

   dateNow.setHours(0);
   dateNow.setMinutes(0);
   dateNow.setSeconds(0);
   dateNow.setMilliseconds(0);

   var elapsedSinceMidnight = elapsedSinceEpoch - dateNow.getTime();

   if(elapsedSinceEvent < elapsedSinceMidnight)
   {
      // event occurred today...
      return 0;
   }
   else
   {
      // event occurred at some point prior to midnight this morning, so return a minimum value of 1...
      return 1 + Math.floor((elapsedSinceEvent - elapsedSinceMidnight) / 86400000);
   }
}
function uroGetURAge(urObj,ageType,getRaw)
{
   if(ageType === 0)
   {
      if((urObj.attributes.driveDate === null)||(urObj.attributes.driveDate === 0)) return -1;
      if(getRaw) return urObj.attributes.driveDate;
      else return uroDateToDays(urObj.attributes.driveDate);
   }
   else if(ageType === 1)
   {
      if((urObj.attributes.resolvedOn === null)||(urObj.attributes.resolvedOn === 0)) return -1;
      if(getRaw) return urObj.attributes.resolvedOn;
      else return uroDateToDays(urObj.attributes.resolvedOn);
   }
   else
   {
      return -1;
   }
}
function uroGetMCAge(mcObj,ageType,getRaw)
{
   if(ageType === 0)
   {
      if((mcObj.attributes.createdOn === null)||(mcObj.attributes.createdOn === 0)) return -1;
      if(getRaw) return mcObj.attributes.createdOn;
      else return uroDateToDays(mcObj.attributes.createdOn);
   }
   else if(ageType === 1)
   {
      if((mcObj.attributes.updatedOn === null)||(mcObj.attributes.updatedOn === 0)) return -1;
      if(getRaw) return mcObj.attributes.updatedOn;
      else return uroDateToDays(mcObj.attributes.updatedOn);
   }
   else
   {
      return -1;
   }
}
function uroGetPURAge(purObj)
{
   if(purObj.attributes.venueUpdateRequests[0].attributes.dateAdded !== null)
   {
      return uroDateToDays(purObj.attributes.venueUpdateRequests[0].attributes.dateAdded);
   }
   else
   {
      return -1;
   }
}
function uroGetCameraAge(camObj, mode)
{
   if(mode === 0)
   {
      if(camObj.attributes.updatedOn === null) return -1;
      return uroDateToDays(camObj.attributes.updatedOn);
   }
   if(mode === 1)
   {
      if(camObj.attributes.createdOn === null) return -1;
      return uroDateToDays(camObj.attributes.createdOn);
   }
}
function uroGetCommentAge(commentObj)
{
   if(commentObj.createdOn === null) return -1;
   return uroDateToDays(commentObj.createdOn);
}
function uroParseDaysAgo(days)
{
  if(days === 0) return 'today';
  else if(days === 1) return '1 day ago';
  else return days+' days ago';
}
function uroGetLocalisedSpeedString(camSpeed, includeValidity)
{
   if(camSpeed !== null)
   {
      var conversionFactor = 1;  // default to metric
      var multipleFactor = 10;   // default to limits being set in multiples of 10

      var country;
      if(W.model.countries.top === undefined)
      {
         country = W.model.countries.additionalInfo[0].name;
      }
      else
      {
         country = W.model.countries.top.name;
      }
      if(country !== null)
      {
         // country-specific deviations from the above...
         if
         (
            (country == "United Kingdom") ||
            (country == "Jersey") ||
            (country == "Guernsey") ||
            (country == "United States")
         )
         {
            // countries using MPH
            conversionFactor = 1.609;
         }
         if
         (
            (country == "United States") ||
            (country == "Guernsey")
         )
         {
            // countries with speed limits set in multiples of 5
            multipleFactor = 5;
         }
      }

      var speed = Math.round(camSpeed / conversionFactor);
      var retval = speed;
      if(conversionFactor == 1) retval += "KM/H";
      else retval += "MPH";
      
      if(includeValidity === true)
      {
         // special handling for the 7KM/H spielstrasse found in Germany...
         if(country == "Germany")
         {
            if(speed != 7)
            {
               if(speed % multipleFactor !== 0) retval += " (not valid?)";
            }
         }
         else
         {
            if(speed % multipleFactor !== 0) retval += " (not valid?)";
         }
      }
      
      return retval;
   }
   else return "not set";
}


// --------------------------------------------------------------------------------------------------------------------
// AREA FRIENDLYNAME STUFF
// --------------------------------------------------------------------------------------------------------------------
function uroAFNObj(fName, area, server)
{
   this.fName = fName;
   this.area = area;
   this.server = server;
}
function uroUpdateAreaName(name, server, area)
{
   var foundExisting = false;
   for(var i=0; i<uroFriendlyAreaNames.length; i++)
   {
      if((uroFriendlyAreaNames[i].server == server) && (uroFriendlyAreaNames[i].area == area))
      {
         if(name === "")
         {
            uroFriendlyAreaNames.splice(i,1);
            foundExisting = true;
         }
         else
         {
            uroFriendlyAreaNames[i].fName = name;
            foundExisting = true;
         }
      }
   }

   if((foundExisting === false) && (name !== ""))
   {
      uroFriendlyAreaNames.push(new uroAFNObj(name,area,server));
   }
   uroReplaceAreaNames(true);
}
function uroAreaNameHover()
{
   if((uroAreaNameHoverObj === null) || (uroAreaNameHoverObj != this))
   {
      uroAreaNameHoverTime = 0;
   }
   uroAreaNameHoverObj = this;
}
function uroAreaNameUnHover()
{
   if(uroANEditHovered === true)
   {
      return false;
   }
   if(uroAreaNameOverlayShown)
   {
      uroAreaNameHoverObj.removeChild(uroANEditBox);
   }
   uroAreaNameHoverObj = null;
   uroAreaNameHoverTime = -1;
   uroAreaNameOverlayShown = false;
}
function uroANEditHover()
{
   uroANEditHovered = true;
   uroAddEventListener('uroANEditBox','mouseout',uroANEditUnHover,false);
   uroAddEventListener('uroANEditBox','click',uroANEditClick,false);
}
function uroANEditUnHover()
{
   var newName = document.getElementById('_textAreaName').value;
   // sanitise name to avoid conflicts with config storage delimiters...
   newName = newName.replace(',','');
   newName = newName.replace(':','');
   var server = W.location.code;
   var area = uroGetAreaArea(uroAreaNameHoverObj.parentNode.children[1]);
   uroAreaNameHoverObj.removeChild(uroANEditBox);
   uroAreaNameOverlayShown = false;
   uroANEditHovered = false;
   uroUpdateAreaName(newName, server, area);
}
function uroANEditClick(e)
{
   // this traps the click to prevent it falling through to the underlying area name element and
   // potentially causing the map view to be relocated to that area...
   e.stopPropagation();
}
function uroGetAreaArea(listObj)
{
   var area = listObj.getElementsByTagName('span')[0].innerHTML;
   area = parseFloat(area.split(' ')[0]);
   return area;
}
function uroAreaNameOverlaySetup()
{
   uroAreaNameOverlayShown = true;

   uroANEditBox = document.createElement('div');
   uroANEditBox.id = "uroANEditBox";
   uroANEditBox.style.position = "absolute";
   uroANEditBox.style.top = '7px';
   uroANEditBox.style.left = '2px';
   uroANEditBox.style.width = "99%";
   uroAreaNameHoverObj.appendChild(uroANEditBox);
   uroANEditBox.onmouseover = uroANEditHover();
   var existingName = uroAreaNameHoverObj.innerHTML;
   var italicTagPos = existingName.indexOf(' <i>');
   if(italicTagPos == -1)
   {
      existingName = "";
   }
   else
   {
      existingName = existingName.substr(0,italicTagPos);
   }
   uroANEditBox.innerHTML = '<input type="text" style="font-size:14px; line-height:16px; height:22px; width:100%" id="_textAreaName" value="'+existingName+'">';
}

function uroReplaceAreaNames(replaceAfterNameChange)
{
   if(document.getElementById('sidepanel-areas') === undefined)
   {
      return;
   }

   if(replaceAfterNameChange === false)
   {
      if(document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0].id == "friendlyNamed")
      {
         return;
      }
   }

   var panelRootObj = document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0];
   if(panelRootObj === undefined)
   {
      // we get here if the user doesn't have any areas defined...
      return;
   }
   
   var areaCount = panelRootObj.children.length;
   if(areaCount === 0)
   {
      return;
   }

   var localisedManagedArea = I18n.lookup("user.areas.managed_area");
   for(var loop=0; loop < areaCount; loop++)
   {
      var childObjPElems = panelRootObj.children[loop].getElementsByTagName('p');
      var title = childObjPElems[0].innerHTML;
      if(title.indexOf(localisedManagedArea) > -1)
      {
         var area = uroGetAreaArea(childObjPElems[1]);
         childObjPElems[0].innerHTML = localisedManagedArea;

         for(var fnIdx=0; fnIdx < uroFriendlyAreaNames.length; fnIdx++)
         {
            var fnObj = uroFriendlyAreaNames[fnIdx];
            if((fnObj.area == area) && (fnObj.server == W.location.code))
            {
               childObjPElems[0].innerHTML = fnObj.fName +' <i>('+localisedManagedArea+')</i>';
               break;
            }
         }
         var titleObj = panelRootObj.getElementsByClassName('title')[loop];
         titleObj.addEventListener("mouseover", uroAreaNameHover, false);
         titleObj.addEventListener("mouseout", uroAreaNameUnHover, false);
         titleObj.style.cursor = "text";
      }
   }
   document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0].id = "friendlyNamed";
}

// --------------------------------------------------------------------------------------------------------------------
// WATCHLIST STUFF
// --------------------------------------------------------------------------------------------------------------------

// Generic Functions
function uroTypeCast(varin)
{
   if(varin == "null") return null;
   if(typeof varin == "string") return parseInt(varin);
   return varin;
}
function uroTruncate(val)
{
   if(val === null) return val;
   if(val < 0) return Math.ceil(val);
   return Math.floor(val);
}
function uroOWLGroupObj(groupID, groupName, groupCollapsed)
{
   groupID = uroTypeCast(groupID);
   this.groupID = groupID;
   this.groupName = groupName;
   this.groupCount = 0;
   this.groupCollapsed = groupCollapsed;
}

// Camera Functions
function uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon)
{
   if(type !== null) type = uroTypeCast(type);
   if(azymuth !== null) azymuth = uroTruncate(uroTypeCast(azymuth)%360);
   if(speed !== null) speed = uroTruncate(uroTypeCast(speed));
   if(typeof validated == "string") validated = (validated == "true");
   if(lat !== null) lat = uroTruncate(uroTypeCast(lat));
   if(lon !== null) lon = uroTruncate(uroTypeCast(lon));

   this.type = type;
   this.azymuth = azymuth;
   this.speed = speed;
   this.validated = validated;
   this.lat = lat;
   this.lon = lon;
}
function uroCamWatchObj(persistent, fid, lon, lat, type, azymuth, speed, validated, groupID, server)
{
   fid = uroTypeCast(fid);
   groupID = uroTypeCast(groupID);
   if(typeof persistent == "string") persistent = (persistent == "true");

   this.fid = fid;
   this.persistent = persistent;
   this.loaded = false;
   this.server = server;
   this.groupID = groupID;
   this.watch = new uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon);
   this.current = new uroCamWatchObjCheckProps(null, null, null, null, null, null);
}
function uroCamDataChanged(idx)
{
   var camObj = uroCamWatchObjects[idx];
   if(camObj.loaded === false) return false;
   if(camObj.current.type != camObj.watch.type) return true;
   if(camObj.current.azymuth != camObj.watch.azymuth) return true;
   if(camObj.current.speed != camObj.watch.speed) return true;
   if(camObj.current.validated != camObj.watch.validated) return true;
   if(camObj.current.lat != camObj.watch.lat) return true;
   if(camObj.current.lon != camObj.watch.lon) return true;
   return false;
}
function uroFindCWLGroupByIdx(groupIdx)
{
   var groupName = '';
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      if(uroCWLGroups[loop].groupID == groupIdx)
      {
         groupName = uroCWLGroups[loop].groupName;
         break;
      }
   }
   return groupName;
}
function uroIsCamOnWatchList(fid)
{
   for(var loop=0;loop<uroCamWatchObjects.length;loop++)
   {
      if(uroCamWatchObjects[loop].fid == fid) return loop;
   }
   return -1;
}
function uroAddCurrentCamWatchData(idx, lat, lon, type, azymuth, speed, validated, server)
{
   var camObj = uroCamWatchObjects[idx];
   camObj.loaded = true;
   camObj.server = server;
   camObj.current = new uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon);
   return(uroCamDataChanged(idx));
}
function uroAddCamToWatchList()
{
   if(uroIsCamOnWatchList(uroShownFID) == -1)
   {
      var camObj = W.model.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, W.location.code));
      uroAddCurrentCamWatchData(uroCamWatchObjects.length-1, camObj.geometry.y, camObj.geometry.x, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, W.location.code);
      uroAddLog('added camera '+uroShownFID+' to watchlist');
      uroOWLUpdateHTML();
   }
}
function uroRemoveCamFromWatchList()
{
   var camidx = uroIsCamOnWatchList(uroShownFID);
   if(camidx != -1)
   {
      uroCamWatchObjects.splice(camidx,1);
      uroAddLog('removed camera '+uroShownFID+' from watchlist');
      uroOWLUpdateHTML();
   }
}
function uroUpdateCamWatchList()
{
   var camIdx = uroIsCamOnWatchList(uroShownFID);
   if(camIdx != -1)
   {
      var camObj = W.model.cameras.objects[uroShownFID];
      uroCamWatchObjects[camIdx].watch = new uroCamWatchObjCheckProps(camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, camObj.geometry.y, camObj.geometry.x);
   }
}
function uroClearCamWatchList()
{
   uroShowAlertBox("fa-warning", "URO+ Warning", "Removing all cameras from the OWL <b>cannot</b> be undone.<br>Are you <i>sure</i> you want to do this?", true, "Delete ALL Cameras", "Keep Cameras", uroClearCamWatchListAction, null);
}
function uroClearCamWatchListAction()
{
   uroCamWatchObjects = [];
   uroOWLUpdateHTML();
}
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);

   var camReq = new XMLHttpRequest();
   camReq.open('GET',camURL,false);
   try
   {
      camReq.send();
      uroAddLog('response '+camReq.status+' received');
      if (camReq.status === 200)
      {
         var camData = JSON.parse(camReq.responseText);
         for(var camIdx = 0; camIdx < camData.cameras.objects.length; camIdx++)
         {
            var 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, W.location.code);
            }
            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;
   var camsChanged = [];
   var camsDeleted = [];
   var camidx;
   var camObj;
   for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      camObj = uroCamWatchObjects[camidx];
      if((camObj.loaded === false) && ((camObj.server == W.location.code) || (camObj.server == '??')))
      {
         if(typeof W.model.cameras.objects[camObj.fid] == 'object')
         {
            if(W.model.cameras.objects[camObj.fid].state != "Delete")
            {
               var wazeObj = W.model.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.watch.lat, camObj.watch.lon);
            }
         }
         else
         {
            camChanged |= uroRetrieveCameras(camObj.watch.lat, camObj.watch.lon);
         }
      }
   }

   if(camChanged)
   {
      for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
      {
         if(uroCamDataChanged(camidx))
         {
            camsChanged.push(uroCamWatchObjects[camidx]);
         }
      }
   }

   for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      camObj = uroCamWatchObjects[camidx];
      if((camObj.loaded === false) && (camObj.server == W.location.code))
      {
         camsDeleted.push(camObj);
      }
   }

   if((camsChanged.length > 0) || (camsDeleted.length > 0))
   {
      var alertStr = '';
      for(camidx=0;camidx<camsChanged.length;camidx++)
      {
         alertStr += 'Camera ID '+camsChanged[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsChanged[camidx].groupID)+'" has been changed<br>';
      }
      alertStr += '<br>';
      for(camidx=0;camidx<camsDeleted.length;camidx++)
      {
         alertStr += 'Camera ID '+camsDeleted[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsDeleted[camidx].groupID)+'" has been deleted<br>';
      }
      uroShowAlertBox("fa-info-circle", "URO+ Camera Watchlist Alert", alertStr, false, "OK", null, null, null);
   }
}
function uroClearDeletedCameras()
{
   for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
   {
      if(uroCamWatchObjects[camidx].loaded === false)
      {
         uroShownFID = uroCamWatchObjects[camidx].fid;
         uroRemoveCamFromWatchList();
      }
   }
}
function uroClearUnknownServerCameras()
{
   var confirmMsg = '<p>Cameras with an unknown server <i>cannot</i> be automatically verified by URO+</p>';
   confirmMsg += 'It is recommended that you manually load WME from each server (World, USA/Canada and Israel) to give URO+ a chance of locating these cameras.<br>';
   confirmMsg += 'If the cameras then continue to show up as an unknown server, it is safe to delete them...<br><br>';
   confirmMsg += 'Do you still wish to proceed with deleting all unknown server cameras?';

   uroShowAlertBox("fa-warning", "URO+ Warning", confirmMsg, true, "Delete unknown cameras", "Keep unknown cameras", uroClearUnknownServerCamerasAction, null);
}
function uroClearUnknownServerCamerasAction()
{
   for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
   {
      if(uroCamWatchObjects[camidx].server == '??')
      {
         uroShownFID = uroCamWatchObjects[camidx].fid;
         uroRemoveCamFromWatchList();
      }
   }
}
function uroRescanCamWatchList()
{
   for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
   {
      uroCamWatchObjects[camidx].loaded = false;
   }
   uroGetCurrentCamWatchListObjects();
   uroOWLUpdateHTML();
}
function uroGotoCam()
{
   var camidx = this.id.substr(13);
   var camPos = new OpenLayers.LonLat();
   camPos.lon = uroCamWatchObjects[camidx].watch.lon;
   camPos.lat = uroCamWatchObjects[camidx].watch.lat;
   W.map.setCenter(camPos,4);
   W.map.camerasLayer.setVisibility(true);
   return false;
}

// Segment Functions
/*
function uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn)
{
   if(left !== null) left = uroTruncate(uroTypeCast(left));
   if(right !== null) right = uroTruncate(uroTypeCast(right));
   if(bottom !== null) bottom = uroTruncate(uroTypeCast(bottom));
   if(top !== null) top = uroTruncate(uroTypeCast(top));
   if(fromNode !== null) fromNode = uroTypeCast(fromNode);
   if(toNode !== null) toNode = uroTypeCast(toNode);
   if(fwdDir !== null) fwdDir = uroTypeCast(fwdDir);
   if(revDir !== null) revDir = uroTypeCast(revDir);
   if(length !== null) length = uroTypeCast(length);
   if(level !== null) level = uroTypeCast(level);
   if(rank !== null) rank = uroTypeCast(rank);
   if(roadType !== null) roadType = uroTypeCast(roadType);
   if(updatedOn !== null) updatedOn = uroTypeCast(updatedOn);

   this.left = left;
   this.right = right;
   this.bottom = bottom;
   this.top = top;
   this.fromNode = fromNode;
   this.toNode = toNode;
   this.fwdDir = fwdDir;
   this.revDir = revDir;
   this.length = length;
   this.level = level;
   this.rank = rank;
   this.roadType = roadType;
   this.updatedOn = updatedOn;
}
function uroSegWatchObj(persistent, fid, left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn, groupID, server)
{
   fid = uroTypeCast(fid);
   groupID = uroTypeCast(groupID);
   if(typeof persistent == "string") persistent = (persistent == "true");

   this.fid = fid;
   this.persistent = persistent;
   this.loaded = false;
   this.server = server;
   this.groupID = groupID;

   this.watch = new uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn);
   this.current = new uroSegWatchObjCheckProps(null, null, null, null, null, null, null, null, null, null, null, null, null);
}
function uroSegDataChanged(idx)
{
   var segObj = uroSegWatchObjects[idx];
   if(segObj.loaded === false) return false;
   if(segObj.current.left != segObj.watch.left) return true;
   if(segObj.current.right != segObj.watch.right) return true;
   if(segObj.current.bottom != segObj.watch.bottom) return true;
   if(segObj.current.top != segObj.watch.top) return true;
   if(segObj.current.fromNode != segObj.watch.fromNode) return true;
   if(segObj.current.toNode != segObj.watch.toNode) return true;
   if(segObj.current.fwdDir != segObj.watch.fwdDir) return true;
   if(segObj.current.revDir != segObj.watch.revDir) return true;
   if(segObj.current.length != segObj.watch.length) return true;
   if(segObj.current.level != segObj.watch.level) return true;
   if(segObj.current.rank != segObj.watch.rank) return true;
   if(segObj.current.roadType != segObj.watch.roadType) return true;
   if(segObj.current.updatedOn != segObj.watch.updatedOn) return true;
   return false;
}
function uroIsSegOnWatchList(fid)
{
   for(var loop=0;loop<uroSegWatchObjects.length;loop++)
   {
      if(uroSegWatchObjects[loop].fid == fid) return loop;
   }
   return -1;
}
function uroAddCurrentSegWatchData(idx, left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn, server)
{
   var segObj = uroSegWatchObjects[idx];
   segObj.loaded = true;
   segObj.server = server;
   segObj.current = new uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn);
   return(uroSegDataChanged(idx));
}
function uroClearSegWatchList()
{
   if(confirm('Removing all segments from the OWL cannot be undone\nAre you sure you want to do this?') === true)
   {
      uroSegWatchObjects = [];
      uroOWLUpdateHTML();
   }
}
function uroAddUpdateSegWatchList()
{
   var selectedCount = W.selectionManager.selectedItems.length;
   if(selectedCount === 0)
   {
      return;
   }

   for(var loop=0;loop < selectedCount; loop++)
   {
      var segObj = W.selectionManager.selectedItems[loop].model.attributes;
      var fid = segObj.id;
      var idx = uroIsSegOnWatchList(fid);
      if(idx != -1)
      {
         uroSegWatchObjects[idx].watch = new uroSegWatchObjCheckProps(segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn);
         uroAddLog('updated watchlist details for segment '+fid);
      }
      else
      {
         uroSegWatchObjects.push(new uroSegWatchObj(true, fid, segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn, 0, W.location.code));
         uroAddCurrentSegWatchData(uroSegWatchObjects.length-1, segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn, W.location.code);
         uroAddLog('added segment '+fid+' to watchlist');
      }
   }
   //uroOWLUpdateHTML();
}
function uroRemoveSegFromWatchList()
{
   var selectedCount = W.selectionManager.selectedItems.length;
   if(selectedCount === 0)
   {
      return;
   }

   for(var loop=0;loop < selectedCount; loop++)
   {
      var fid = W.selectionManager.selectedItems[loop].model.attributes.id;
      var idx = uroIsSegOnWatchList(fid);
      if(idx != -1)
      {
         uroSegWatchObjects.splice(idx,1);
         uroAddLog('removed segment '+fid+' from watchlist');
      }
   }
   //uroOWLUpdateHTML();
}
function uroRetrieveSegments(lat, lon)
{
   var pos = new OpenLayers.LonLat();
   var changed = false;

   pos.lon = lon;
   pos.lat = lat;
   pos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));

   var URL = 'https://' + document.location.host;
   URL += Waze.Config.api_base;
   URL += '/Features?roadTypes=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20%2C21';
   URL += '&bbox=';
   var latl = pos.lat - 0.25;
   var latu = pos.lat + 0.25;
   var lonl = pos.lon - 0.25;
   var lonr = pos.lon + 0.25;
   URL += lonl+','+latl+','+lonr+','+latu;
   URL += '&language=en';
   uroAddLog('retrieving segment data around '+pos.lon+','+pos.lat);

   var req = new XMLHttpRequest();
   req.open('GET',URL,false);
   try
   {
      req.send();
      uroAddLog('response '+req.status+' received');
      if (req.status === 200)
      {
         var data = JSON.parse(req.responseText);
         for(var idx = 0; idx < data.segments.objects.length; idx++)
         {
            var obj = data.segments.objects[idx];
            var listIdx = uroIsSegOnWatchList(obj.id);
            if(listIdx != -1)
            {
               //pos.lon = obj.geometry.coordinates[0];
               //pos.lat = obj.geometry.coordinates[1];
               //pos.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, W.location.code);
            }
            else if(obj.validated === false)
            {

            }
         }
      }
      else
      {
         uroAddLog('request failed (status != 200)');
      }
   }
   catch(err)
   {
      uroAddLog('segment load request failed (exception '+err+' caught)');
   }
   return changed;
}
function uroGetCurrentSegWatchListObjects()
{
   var segChanged = false;
   var segsChanged = [];
   var segsDeleted = [];
   var idx;
   var segObj;

   for(idx=0;idx<uroSegWatchObjects.length;idx++)
   {
      segObj = uroSegWatchObjects[idx];
      if((segObj.loaded === false) && ((segObj.server == W.location.code) || (segObj.server == '??')))
      {
         var segLat = (segObj.watch.top + segObj.watch.bottom) / 2;
         var segLon = (segObj.watch.right + segObj.watch.left) / 2;
         if(typeof W.model.segments.objects[segObj.fid] == 'object')
         {
            if(W.model.segments.objects[segObj.fid].state != "Delete")
            {
               var wazeObj = W.model.segments.objects[segObj.fid];
               segChanged |= uroAddCurrentSegWatchData(idx, wazeObj.geometry.bounds.left, wazeObj.geometry.bounds.right, wazeObj.geometry.bounds.bottom, wazeObj.geometry.bounds.top, wazeObj.fromNodeID, wazeObj.toNodeID, wazeObj.fwdDirection, wazeObj.revDirection, wazeObj.length, wazeObj.level, wazeObj.rank, wazeObj.roadType, wazeObj.updatedOn, W.location.code);
            }
            else
            {
               segChanged |= uroRetrieveSegments(segLat, segLon);
            }
         }
         else
         {
            segChanged |= uroRetrieveSegments(segLat, segLon);
         }
      }
   }

   if(segChanged)
   {
      for(idx=0;idx<uroSegWatchObjects.length;idx++)
      {
         if(uroSegDataChanged(idx))
         {
            segsChanged.push(uroSegWatchObjects[idx]);
         }
      }
   }

   for(idx=0;idx<uroSegWatchObjects.length;idx++)
   {
      segObj = uroSegWatchObjects[idx];
      if((segObj.loaded === false) && (segObj.server == W.location.code))
      {
         segsDeleted.push(segObj);
      }
   }

   if((segsChanged.length > 0) || (segsDeleted.length > 0))
   {
      var alertStr = 'Segment WatchList Alert!!!\r\n';
      for(idx=0;idx<segsChanged.length;idx++)
      {
         alertStr += 'Segment ID '+segsChanged[idx].fid+' in group "'+uroFindCWLGroupByIdx(segsChanged[idx].groupID)+'" has been changed\r\n';
      }
      for(idx=0;idx<segsDeleted.length;idx++)
      {
         alertStr += 'Segment ID '+segsDeleted[idx].fid+' in group "'+uroFindCWLGroupByIdx(segsDeleted[idx].groupID)+'" has been deleted\r\n';
      }
      alert(alertStr);
   }
}

// Places Functions
function uroPlaceWatchObjCheckProps(left, right, bottom, top, name, imageCount, residential, updatedOn)
{
   if(left !== null) left = uroTruncate(uroTypeCast(left));
   if(right !== null) right = uroTruncate(uroTypeCast(right));
   if(bottom !== null) bottom = uroTruncate(uroTypeCast(bottom));
   if(top !== null) top = uroTruncate(uroTypeCast(top));
   if(imageCount !== null) imageCount = uroTypeCast(imageCount);
   if(typeof residential == "string") residential = (residential == "true");
   if(updatedOn !== null) updatedOn = uroTypeCast(updatedOn);

   this.left = left;
   this.right = right;
   this.bottom = bottom;
   this.top = top;
   this.name = name;
   this.imageCount = imageCount;
   this.residential = residential;
   this.updatedOn = updatedOn;
}
function uroPlaceWatchObj(persistent, fid, left, right, bottom, top, imageCount, name, residential, updatedOn, groupID, server)
{
   groupID = uroTypeCast(groupID);
   if(typeof persistent == "string") persistent = (persistent == "true");

   this.fid = fid;
   this.persistent = persistent;
   this.loaded = false;
   this.server = server;
   this.groupID = groupID;
   this.watch = new uroPlaceWatchObjCheckProps(left, right, bottom, top, name, imageCount, residential, updatedOn);
   this.current = new uroPlaceWatchObjCheckProps(null, null, null, null, null, null, null, null);
}
function uroPlaceDataChanged(idx)
{
   var placeObj = uroPlaceWatchObjects[idx];
   if(placeObj.loaded === false) return false;
   if(placeObj.current.left != placeObj.watch.left) return true;
   if(placeObj.current.right != placeObj.watch.right) return true;
   if(placeObj.current.bottom != placeObj.watch.bottom) return true;
   if(placeObj.current.top != placeObj.watch.top) return true;
   if(placeObj.current.name != placeObj.watch.name) return true;
   if(placeObj.current.imageCount != placeObj.watch.imageCount) return true;
   if(placeObj.current.residential != placeObj.watch.residential) return true;
   if(placeObj.current.updatedOn != placeObj.watch.updatedOn) return true;
   return false;
}
function uroIsPlaceOnWatchList(fid)
{
   for(var loop=0;loop<uroPlaceWatchObjects.length;loop++)
   {
      if(uroPlaceWatchObjects[loop].fid == fid) return loop;
   }
   return -1;
}
function uroClearPlaceWatchList()
{
   if(confirm('Removing all places from the OWL cannot be undone\nAre you sure you want to do this?') === true)
   {
      uroPlaceWatchObjects = [];
      uroOWLUpdateHTML();
   }
}
*/

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(uroCamWatchObjects[camidx].server != W.location.code)
   {
      if(uroCamWatchObjects[camidx].server == '??') this.style.backgroundColor = '#A0A0A0';
      else this.style.backgroundColor = '#AAFFAA';
   }
   else if(changed) this.style.backgroundColor = '#AAAAFF';
   else if(deleted) this.style.backgroundColor = '#FFAAAA';
   else this.style.backgroundColor = '#FFFFFF';
   return false;
}
function uroCWLIconHighlight()
{
   this.style.color="#0000ff";
   return false;
}
function uroCWLIconLowlight()
{
   this.style.color="#ccccff";
   return false;
}
function uroPopulateCWLGroupSelect()
{
   var selector = document.getElementById('_uroCWLGroupSelect');
   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   }
   for(var loop=0;loop<uroCWLGroups.length;loop++)
   {
      var 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[loop].groupID;
         break;
      }
   }
   return groupID;
}
function uroAddCWLGroup()
{
   var groupID = uroGetNextCWLGroupID();
   var groupName = uroGetElmValue('_uroCWLGroupEntry');
   if(uroFindCWLGroupByName(groupName) == -1)
   {
      uroCWLGroups.push(new uroOWLGroupObj(groupID,groupName,false));
      uroPopulateCWLGroupSelect();
   }
}
function uroRemoveCWLGroup()
{
   var loop;
   var selector = document.getElementById('_uroCWLGroupSelect');
   var groupID = parseInt(selector.selectedOptions[0].value);
   if(groupID === 0) return false;   // prevent deletion of the default group

   for(loop=0;loop<uroCamWatchObjects.length;loop++)
   {
      var cwObj = uroCamWatchObjects[loop];
      if(cwObj.groupID == groupID)
      {
         cwObj.groupID = 0;
      }
   }
   for(loop=0;loop<uroCWLGroups.length;loop++)
   {
      var groupObj = uroCWLGroups[loop];
      if(groupObj.groupID == groupID)
      {
         groupObj.groupID = -1;
      }
   }
   uroOWLUpdateHTML();
}
function uroAssignCameraToGroup()
{
   var camidx = this.id.substr(13);
   var selector = document.getElementById('_uroCWLGroupSelect');
   uroCamWatchObjects[camidx].groupID = parseInt(selector.selectedOptions[0].value);
   uroOWLUpdateHTML();
   return false;
}
function uroAddBtnEvl(btnID, evlType, evlFunction)
{
   var 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;
   uroOWLUpdateHTML();
   return false;
}

var uroSelectedOWLGroup = null;
function uroOWLUpdateHTML(doFullUpdate)
{
   var camTypes = new Array("","","Speed", "Dummy", "Red Light");
   var iHTML = '';

   if(document.getElementById('_uroCWLGroupSelect') !== null)
   {
      uroSelectedOWLGroup = document.getElementById('_uroCWLGroupSelect').selectedIndex;
   }   
   iHTML = '<br><b>Camera Watchlist:</b><br><br>';
   iHTML += '<div id="_uroCWLCamList" style="height:65%;overflow:auto;">';
   if(uroCWLGroups.length > 0)
   {
      var camidx;
      for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
      {
         var groupObj = uroCWLGroups[groupidx];
         iHTML += '<div id="_uroCWLGroup-'+groupidx+'">';
         if(groupObj.groupCollapsed === true)
         {
            iHTML += '<i class="fa fa-plus-square-o" style="cursor:pointer;font-size:14px;" id="_uroCWLGroupState-'+groupidx+'"></i>';
         }
         else
         {
            iHTML += '<i class="fa fa-minus-square-o" style="cursor:pointer;font-size:14px;" id="_uroCWLGroupState-'+groupidx+'"></i>';
         }
         iHTML += '<b>'+groupObj.groupName+'</b><br>';
         groupObj.groupCount = 0;
         if(uroCamWatchObjects.length > 0)
         {
            for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
            {
               var 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(camObj.server != W.location.code)
                  {
                     if(camObj.server == '??') iHTML += '#A0A0A0;';
                     else iHTML += '#AAFFAA;';
                  }
                  else 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 += ' ('+camObj.server+')';
                  iHTML += ' Type: '+camTypes[camObj.watch.type];
                  if(camObj.server != W.location.code)
                  {
                     if(camObj.server == '??')
                     {
                        iHTML += '<br><i>Unknown server</i>';
                     }
                     else
                     {
                        iHTML += '<br><i>Not on this server</i>';
                     }
                  }
                  else if(deleted)
                  {
                     iHTML += '<br>DELETED';
                  }
                  else if(changed)
                  {
                     if(camObj.current.type != camObj.watch.type)
                     {
                        iHTML += '<br>&nbsp;&nbsp;Type changed';
                        iHTML += ' ('+camObj.watch.type+' to '+camObj.current.type+')';
                     }
                     if(camObj.current.azymuth != camObj.watch.azymuth)
                     {
                        iHTML += '<br>&nbsp;&nbsp;Azimuth changed';
                        iHTML += ' ('+camObj.watch.azymuth+' to '+camObj.current.azymuth+')';
                     }
                     if(camObj.current.speed != camObj.watch.speed)
                     {
                        iHTML += '<br>&nbsp;&nbsp;Speed changed';
                        iHTML += ' ('+camObj.watch.speed+' to '+camObj.current.speed+')';
                     }
                     if(camObj.current.validated != camObj.watch.validated)
                     {
                        iHTML += '<br>&nbsp;&nbsp;Approval state changed';
                        iHTML += ' ('+camObj.watch.validated+' to '+camObj.current.validated+')';
                     }
                     if(camObj.current.lat != camObj.watch.lat)
                     {
                        iHTML += '<br>&nbsp;&nbsp;Latitude changed';
                        iHTML += ' ('+camObj.watch.lat+' to '+camObj.current.lat+')';
                     }
                     if(camObj.current.lon != camObj.watch.lon)
                     {
                        iHTML += '<br>&nbsp;&nbsp;Longitude changed';
                        iHTML += ' ('+camObj.watch.lon+' to '+camObj.current.lon+')';
                     }
                  }

                  if(camObj.server == W.location.code)
                  {
                     if(deleted === false)
                     {
                        iHTML += '&nbsp;<i class="fa fa-group" style="cursor:pointer;font-size:14px;color:#ccccff;" id="_uroCWLIcon1-'+camidx+'"></i>';
                     }
                     iHTML += '&nbsp;<i class="fa fa-arrow-circle-right" style="cursor:pointer;font-size:14px;color:#ccccff;" id="_uroCWLIcon2-'+camidx+'"></i>';
                  }
                  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 += '<br><input type="button" id="_btnRescanCamWatchList" value="Refresh Camera Data"><br><br>';
   iHTML += '<b>Remove cameras from OWL:</b><br>';
   iHTML += '<input type="button" id="_btnRemoveDeletedCameras" value="Deleted">&nbsp;&nbsp;';
   iHTML += '<input type="button" id="_btnRemoveUnknownServerCameras" value="Unknown Server">&nbsp;&nbsp;';
   iHTML += '<input type="button" id="_btnClearCamWatchList" value="ALL Cameras">';
   iHTML += '</div>';
   uroOWL.innerHTML = iHTML;

   uroFinaliseOWLHTMLUpdate();
}
function uroFinaliseOWLHTMLUpdate()
{
   if(uroCamWatchObjects.length > 0)
   {
      if(document.getElementById("_uroCWL-0") == null)
      {
         setTimeout(uroFinaliseOWLHTMLUpdate,100);
         return;
      }
      
      for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
      {
         document.getElementById("_uroCWL-"+camidx).onmouseover = uroHighlightCWLEntry;
         document.getElementById("_uroCWL-"+camidx).onmouseleave = uroUnhighlightCWLEntry;

         if(uroCamWatchObjects[camidx].server == W.location.code)
         {
            var icon1 = document.getElementById("_uroCWLIcon1-"+camidx);
            var icon2 = document.getElementById("_uroCWLIcon2-"+camidx);
            if(icon1 !== null)
            {
               icon1.onmouseover = uroCWLIconHighlight;
               icon1.onmouseleave = uroCWLIconLowlight;
               icon1.onclick = uroAssignCameraToGroup;
            }
            if(icon2 !== null)
            {
               icon2.onmouseover = uroCWLIconHighlight;
               icon2.onmouseleave = uroCWLIconLowlight;
               icon2.onclick = uroGotoCam;
            }
         }
      }
   }

   if(document.getElementById('_btnClearCamWatchList') == null)
   {
      setTimeout(uroFinaliseOWLHTMLUpdate,100);
      return;
   }
      
   uroAddBtnEvl('_btnClearCamWatchList', 'click', uroClearCamWatchList);
   uroAddBtnEvl('_btnRemoveDeletedCameras', 'click', uroClearDeletedCameras);
   uroAddBtnEvl('_btnRemoveUnknownServerCameras', 'click', uroClearUnknownServerCameras);
   uroAddBtnEvl('_btnRescanCamWatchList', 'click', uroRescanCamWatchList);
   uroAddBtnEvl('_btnCWLGroupDel', 'click', uroRemoveCWLGroup);
   uroAddBtnEvl('_btnCWLGroupAdd', 'click', uroAddCWLGroup);
   if(document.getElementById('_uroCWLGroupSelect') !== null)
   {
      uroAddLog('populating CWL group list');
      uroPopulateCWLGroupSelect();
      var selector = document.getElementById('_uroCWLGroupSelect');
      if(uroSelectedOWLGroup >= selector.length)
      {
         uroSelectedOWLGroup = 0;
      }
      selector.selectedIndex = uroSelectedOWLGroup;
   }

   if(uroCWLGroups.length > 0)
   {
      for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
      {
         if(uroCWLGroups[groupidx].groupCount === 0)
         {
            uroSetStyleDisplay('_uroCWLGroup-'+groupidx,'none');
         }
         else
         {
            uroSetOnClick('_uroCWLGroupState-'+groupidx,uroCWLGroupCollapseExpand);
         }
      }
   }   
}

// --------------------------------------------------------------------------------------------------------------------
// END OF WATCHLIST STUFF
// --------------------------------------------------------------------------------------------------------------------


function uroIsOnIgnoreList(fid)
{
   if(sessionStorage.UROverview_FID_IgnoreList.indexOf('fid:'+fid) == -1) return false;
   else return true;
}
function uroEnableIgnoreListControls()
{
   var btnState = "visible";
   if(sessionStorage.UROverview_FID_IgnoreList === '')
   {
      btnState = "hidden";
   }
   document.getElementById('_btnUndoLastHide').style.visibility = btnState;
   document.getElementById('_btnClearSessionHides').style.visibility = btnState;
   uroFilterItems();
}
function uroAddToIgnoreList()
{
   if(!uroIsOnIgnoreList(uroShownFID))
   {
      sessionStorage.UROverview_FID_IgnoreList += 'fid:'+uroShownFID;
      uroAddLog('added fid '+uroShownFID+' to ignore list');
      uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
      uroDiv.style.visibility = 'hidden';
      uroEnableIgnoreListControls();

      W.map.events.register("mousemove", null, uroFilterItemsOnMove);
   }
   return false;
}
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)
{
   var re;
   if(uroGetCBChecked('_cbCaseInsensitive') === true) re = RegExp(keyword,'i');
   else re = RegExp(keyword);

   if(desc.search(re) != -1) return true;
   else return false;
}
function uroClickify(desc)
{
   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;
   }
   return desc;
}
function uroGetUpdateRequestSessions()
{
   var idList = [];

   while((idList.length < 50) && (uroPendingURSessionIDs.length))
   {
      var id = uroPendingURSessionIDs.shift();
      idList.push(id);
   }

   if(idList.length > 0)
   {
      uroAddLog('grabbing '+idList.length+' updateRequestSessions, IDs: '+idList);
      W.model.updateRequestSessions.get(idList);
   }

   if((uroPendingURSessionIDs.length) || (uroRequestedURSessionIDs.length))
   {
      setTimeout(uroGetUpdateRequestSessions,1000);
   }      
}
function uroRefreshUpdateRequestSessions()
{
   var urcount = 0;
   uroPendingURSessionIDs = [];
   uroRequestedURSessionIDs = [];
   
   for (var urID in W.model.mapUpdateRequests.objects)
   {
      if(W.model.mapUpdateRequests.objects.hasOwnProperty(urID))
      {   
         if(W.model.updateRequestSessions.objects[urID] === undefined)
         {
            uroPendingURSessionIDs.push(urID);
         }
         urcount++;
      }
   }
   uroGetUpdateRequestSessions();
}
function uroURHasMyComments(fid)
{
   if(uroUserID === -1) return false;
   var nComments = W.model.updateRequestSessions.objects[fid].comments.length;
   if(nComments === 0) return false;

   for(var cidx=0; cidx<nComments; cidx++)
   {
      if(W.model.updateRequestSessions.objects[fid].comments[cidx].userID == uroUserID) return true;
   }

   return false;
}
function uroACMObj(urID, markerType, customType, hasMyComments, nComments)
{
   this.urID = urID;
   this.markerType = markerType;
   this.customType = customType;
   this.hasMyComments = hasMyComments;
   this.nComments = nComments;
}
function uroAddCustomMarkers(urID, markerType, customType, hasMyComments, nComments)
{
   var useCustomMarker = false;
   if(uroGetCBChecked('_cbMasterEnable') === true)
   {
      if(customType === 0) useCustomMarker = (uroGetCBChecked('_cbCustomRoadworksMarkers'));
      else if(customType === 1) useCustomMarker = (uroGetCBChecked('_cbCustomConstructionMarkers'));
      else if(customType === 2) useCustomMarker = (uroGetCBChecked('_cbCustomClosuresMarkers'));
      else if(customType === 3) useCustomMarker = (uroGetCBChecked('_cbCustomEventsMarkers'));
      else if(customType === 4) useCustomMarker = (uroGetCBChecked('_cbCustomNotesMarkers'));
      else if(customType === 5) useCustomMarker = (uroGetCBChecked('_cbCustomWSLMMarkers'));
      else if(customType === 6) useCustomMarker = (uroGetCBChecked('_cbCustomBOGMarkers'));
      else if(customType === 7) useCustomMarker = (uroGetCBChecked('_cbCustomDifficultMarkers'));
      else if(customType === 98) useCustomMarker = (uroGetCBChecked('_cbCustomNativeSLMarkers'));
      else if(customType === 99) useCustomMarker = (uroGetCBChecked('_cbCustomKeywordMarkers'));
      else if(customType === 100) useCustomMarker = (uroGetCBChecked('_cbCustomElginMarkers'));
      else if(customType === 101) useCustomMarker = (uroGetCBChecked('_cbCustomTrafficCastMarkers'));
      else if(customType === 102) useCustomMarker = (uroGetCBChecked('_cbCustomTrafficMasterMarkers'));
      else if(customType === 103) useCustomMarker = (uroGetCBChecked('_cbCustomCaltransMarkers'));
      else if(customType === 104) useCustomMarker = (uroGetCBChecked('_cbCustomTFLMarkers'));
   }
   if(!useCustomMarker) customType = -1;
   uroCustomMarkerList.push(new uroACMObj(urID, markerType, customType, hasMyComments, nComments));
}
function uroRenderCustomMarkers(markerType)
{
   var urID;
   var elmID;
   var newSpan;
   var divElem;
   var objIdx;
   var customType;
   var cmlObj;
   var defaultMarkerURL = "url('"+document.location.origin + '/assets-editor/sprites/vectors/' + uroNativeMarkerImage+"')";
   var touchedByURO = false;   
   
   if(markerType == 'ur')
   {
      var useDefaultConvoMarker = false;
      var addCommentCount = false;

      if(uroGetCBChecked('_cbMasterEnable') === true)
      {
         if((uroGetCBChecked('_cbNativeConvoMarkers')) && (uroBetaEditor === false)) useDefaultConvoMarker = true;
         if((uroGetCBChecked('_cbNativeBetaConvoMarkers')) && (uroBetaEditor === true)) useDefaultConvoMarker = true;
         if(uroGetCBChecked('_cbCommentCount')) addCommentCount = true;
      }
      else
      {
         useDefaultConvoMarker = true;
      }

      var uRCM_masterEnable = uroGetCBChecked('_cbMasterEnable');
      
      divElem = document.getElementById(W.map.updateRequestLayer.id);
      
      if(divElem.childNodes.length > 0)
      {
         for(objIdx = 0; objIdx < uroCustomMarkerList.length; objIdx++)
         {
            customType = -1;
            cmlObj = uroCustomMarkerList[objIdx];
            if(cmlObj.markerType == 'ur')
            {
               if(uRCM_masterEnable === true)
               {
                  customType = cmlObj.customType;
               }
               if(customType < 100)
               {
                  urID = cmlObj.urID;
                  var nComments = cmlObj.nComments;
                  var iconObj = W.map.updateRequestLayer.markers[urID].icon;
                  newSpan = '';

                  if(nComments !== 0)
                  {
                     var classList = iconObj.imageDiv.classList;
                     elmID = "commentCount_"+urID;

                     if(addCommentCount)
                     {                    
                        // add a new comment count bubble if the UR doesn't already have one
                        if(document.getElementById(elmID) === null)
                        {
                           newSpan += '<span id="'+elmID+'" style="position:absolute;top:-9px;left:-11px;pointer-events:none;z-index:1">';
                           // define the comment-count holding span within the span used to hold the empty bubble image, and before the image is
                           // added to the HTML, to avoid z-indexing issues when adjacent comment count bubbles are overlapped...
                           newSpan += '<span id="'+elmID+"_inner"+'" style="position:absolute;top:4px;left:11px;font-size:11px;;pointer-events:none"></span>';
                           newSpan += '<img src="'+uroMarkers[0]+'">';
                           newSpan += '</span>';
                        }
                     }
                     else
                     {
                        // remove comment count bubble from this UR marker if one has previously been
                        // added and the user has now disabled the option...
                        if(document.getElementById(elmID) !== null)
                        {
                           document.getElementById(elmID).remove();
                        }
                        if(document.getElementById(elmID+"_inner") !== null)
                        {
                           document.getElementById(elmID+"_inner").remove();
                        }
                     }

                     elmID = "convoMarker_"+urID;
                     if(useDefaultConvoMarker === false)
                     {
                        if(document.getElementById(elmID) === null)
                        {
                           var hasMyComments = cmlObj.hasMyComments;
                           // z-index needs to be set to 1 here so that when a new comment is added to a UR and WME re-renders the native
                           // conversation marker, the custom marker remains on top...
                           newSpan += '<span id="'+elmID+'" style="position:absolute;top:-9px;left:18px;pointer-events:none;z-index:1">';
                           if(hasMyComments) newSpan += '<img src="'+uroMarkers[2]+'">';
                           else newSpan += '<img src="'+uroMarkers[1]+'">';
                           newSpan += '</span>';
                           classList.remove("has-comments");
                        }
                     }
                     else
                     {
                        // remove custom conversation marker from this UR if one has previously been
                        // added and the user has now disabled this option
                        if(document.getElementById(elmID) !== null)
                        {
                           document.getElementById(elmID).remove();
                        }
                        if(nComments > 0)
                        {
                           // only replace the native marker class if the UR has comments - if we're just clearing the custom
                           // marker following a master enable switchoff, we don't then want to add native markers to URs which
                           // didn't have them in the first place...
                           classList.add("has-comments");
                        }
                     }
                  }
                  
                  // change main marker if required
                  touchedByURO = W.map.updateRequestLayer.markers[urID].touchedByURO;

                  /*
                  //// TEMPORARY REMOVAL UNTIL CUSTOM ICON SUPPORT IS FIXED IN NEW WME
                  if(customType != -1)
                  {
                     if((touchedByURO === undefined) || (touchedByURO === false))
                     {
                        customType = uroGetCustomMarkerIdx(customType);
                        W.map.updateRequestLayer.markers[urID].icon.imageDiv.style.backgroundImage = uroAltMarkers[customType];
                        W.map.updateRequestLayer.markers[urID].touchedByURO = true;
                     }
                  }
                  else
                  {
                     if((touchedByURO === undefined) || (touchedByURO === true))
                     {                  
                        W.map.updateRequestLayer.markers[urID].icon.imageDiv.style.backgroundImage = defaultMarkerURL;
                        W.map.updateRequestLayer.markers[urID].touchedByURO = false;
                     }
                  }
                  */
                  
                  if(newSpan !== '')
                  {
                     iconObj.$div.prepend(newSpan);
                     
                     if(addCommentCount)
                     {                    
                        var styleLeft;
                        if(nComments < 10) styleLeft = '11px';
                        else if(nComments < 100) styleLeft = '8px';
                        else styleLeft = '5px';
                        elmID = "commentCount_"+urID;
                        if(document.getElementById(elmID+"_inner") !== null)
                        {
                           document.getElementById(elmID+"_inner").innerHTML = nComments;
                           document.getElementById(elmID+"_inner").style.left = styleLeft;
                        }
                     }                  
                  }
               }
            }
         }
      }
   }

   else if(markerType == 'mp')
   {
      divElem = document.getElementById(W.map.problemLayer.id);
      if(divElem.childNodes.length > 0)
      {       
         for(objIdx = 0; objIdx < uroCustomMarkerList.length; objIdx++)
         {       
            cmlObj = uroCustomMarkerList[objIdx];
            if(cmlObj.markerType == 'mp')
            {
               customType = cmlObj.customType;
               if((customType >= 100) || (customType == -1))
               {
                  urID = cmlObj.urID;
                                
                  // change main marker if required
                  touchedByURO = W.map.problemLayer.markers[urID].touchedByURO;
                  /*
                  //// TEMPORARY REMOVAL UNTIL CUSTOM ICON SUPPORT IS FIXED IN NEW WME
                  if(customType != -1)
                  {
                     if((touchedByURO === undefined) || (touchedByURO === false))
                     {
                        customType = uroGetCustomMarkerIdx(customType);
                        W.map.problemLayer.markers[urID].icon.imageDiv.style.backgroundImage = uroAltMarkers[customType];
                        W.map.problemLayer.markers[urID].touchedByURO = true;
                     }
                  }
                  else
                  {
                     if((touchedByURO === undefined) || (touchedByURO === true))
                     {                  
                        W.map.problemLayer.markers[urID].icon.imageDiv.style.backgroundImage = defaultMarkerURL;
                        W.map.problemLayer.markers[urID].touchedByURO = false;
                     }
                  }               
                  */
               }
            }
         }
      }
   }
}


function uroFilterPlaces()
{
   if(uroFilterPreamble() === false) return;

   if(uroPlaceSelected === true) return;

   if(uroGetCBChecked('_cbDisablePlacesFiltering') === true) return;

   uroUpdateVenueEditorList();

   var filterNameID = null;
   var tbUserName = uroGetElmValue('_textPlacesEditor');
   var selector = document.getElementById('_selectPlacesUserID');
   if(selector.selectedIndex > 0)
   {
      var selUserName = document.getElementById('_selectPlacesUserID').selectedOptions[0].innerHTML;
      if(selUserName == tbUserName)
      {
         filterNameID = document.getElementById('_selectPlacesUserID').selectedOptions[0].value;
      }
   }      
   if(filterNameID === null)
   {
      var userObj = W.model.users.getByAttributes({userName:tbUserName})[0];
      if(userObj !== undefined)
      {
         filterNameID = userObj.id;
      }
   }

   
   var filterCats = [];
   for(var i=0; i<W.Config.venues.categories.length; i++)
   {
      var parentCategory = W.Config.venues.categories[i];
      var subCategory;

      if(uroGetCBChecked('_cbPlacesFilter-'+parentCategory) === true)
      {
         filterCats.push(parentCategory);
         for(var i1=0; i1<W.Config.venues.subcategories[parentCategory].length; i1++)
         {
            subCategory = W.Config.venues.subcategories[parentCategory][i1];
            filterCats.push(subCategory);
         }
      }
      else
      {
         for(var i2=0; i2<W.Config.venues.subcategories[parentCategory].length; i2++)
         {
            subCategory = W.Config.venues.subcategories[parentCategory][i2];
            if(uroGetCBChecked('_cbPlacesFilter-'+subCategory) === true)
            {
               filterCats.push(subCategory);
            }
         }
      }
   }

   var placeStyle;

   var uFP_filterEditedLessThan = uroGetCBChecked('_cbPlaceFilterEditedLessThan');
   var uFP_filterEditedMoreThan = uroGetCBChecked('_cbPlaceFilterEditedMoreThan');
   var uFP_filterL0 = uroGetCBChecked('_cbHidePlacesL0');
   var uFP_filterL1 = uroGetCBChecked('_cbHidePlacesL1');
   var uFP_filterL2 = uroGetCBChecked('_cbHidePlacesL2');
   var uFP_filterL3 = uroGetCBChecked('_cbHidePlacesL3');
   var uFP_filterL4 = uroGetCBChecked('_cbHidePlacesL4');
   var uFP_filterL5 = uroGetCBChecked('_cbHidePlacesL5');
   var uFP_filterStaff = uroGetCBChecked('_cbHidePlacesStaff');
   var uFP_filterAL = uroGetCBChecked('_cbHidePlacesAdLocked');
   var uFP_filterOnLockLevel = (uFP_filterL0 || uFP_filterL1 || uFP_filterL2 || uFP_filterL3 || uFP_filterL4 || uFP_filterL5 || uFP_filterStaff);
   var uFP_filterNoPhotos = uroGetCBChecked('_cbHideNoPhotoPlaces');
   var uFP_filterWithPhotos = uroGetCBChecked('_cbHidePhotoPlaces');
   var uFP_filterNoLinks = uroGetCBChecked('_cbHideNoLinkedPlaces');
   var uFP_filterWithLinks = uroGetCBChecked('_cbHideLinkedPlaces');
   var uFP_filterNoKeyword = uroGetCBChecked('_cbHideKeywordPlaces');
   var uFP_filterKeyword = uroGetCBChecked('_cbHideNoKeyeordPlaces');
   var uFP_filterPrivate = uroGetCBChecked('_cbFilterPrivatePlaces');
   var uFP_invertFilters = uroGetCBChecked('_cbInvertPlacesFilter');
   var uFP_masterEnable = uroGetCBChecked('_cbMasterEnable');
   var uFP_filterAreaPlaces = uroGetCBChecked('_cbHideAreaPlaces');
   var uFP_filterPointPlaces = uroGetCBChecked('_cbHidePointPlaces');
   
   var uFP_filterCreatedBy = uroGetCBChecked('_cbShowOnlyPlacesCreatedBy');
   var uFP_filterEditedBy = uroGetCBChecked('_cbShowOnlyPlacesEditedBy');
   
   var uFP_NameKeyword = document.getElementById('_textKeywordPlace').value.toLowerCase();   
   
   var uFP_thresholdMinDays = document.getElementById('_inputFilterPlaceEditMinDays').value;
   var uFP_thresholdMaxDays = document.getElementById('_inputFilterPlaceEditMaxDays').value;
   
   for(var v=0; v<W.map.landmarkLayer.features.length; v++)
   {
      placeStyle = 'visible';
      if(uFP_masterEnable === true)
      {
         var lmObj = W.map.landmarkLayer.features[v];

         // when an area place is selected, the drag points for editing the place outline now get added as objects into W.map.landmarkLayer.features,
         // however none of these objects have the .model property - we must therefore check each entry in features[] to see if it has .model before
         // attempting to filter it...
         if(lmObj.model != null)
         {
            if(lmObj.model.attributes.id < 0)
            {
               // don't apply filtering to newly-created places - this allows the user to leave their filtering settings unchanged whilst
               // adding a new place which, once saved, would then be hidden...
               break;
            }
            
            if(uFP_filterAreaPlaces)
            {
               if(lmObj.model.attributes.geometry.id.indexOf('Polygon') !== -1)
               {
                  placeStyle = 'hidden';
               }
            }
            if(uFP_filterPointPlaces)
            {
               if(lmObj.model.attributes.geometry.id.indexOf('Point') !== -1)
               {
                  placeStyle = 'hidden';
               }
            }
                        

            if(placeStyle == 'visible')
            {
               if((uFP_filterEditedLessThan) || (uFP_filterEditedMoreThan))
               {
                  var editDate = lmObj.model.attributes.updatedOn;
                  if(editDate === undefined)
                  {
                     // where a place has never been edited since its creation, use the creation date instead...
                     editDate = lmObj.model.attributes.createdOn;
                  }
                  if(editDate != null)
                  {
                     var editDaysAgo = uroDateToDays(editDate);
                     if(uFP_filterEditedLessThan)
                     {
                        if(editDaysAgo < uFP_thresholdMinDays)
                        {
                           placeStyle = 'hidden';
                        }
                     }
                     if(uFP_filterEditedMoreThan)
                     {
                        if(editDaysAgo > uFP_thresholdMaxDays)
                        {
                           placeStyle = 'hidden';
                        }
                     }
                  }
               }
            }

            if(placeStyle == 'visible')
            {
               if(uFP_filterOnLockLevel)
               {
                  var lockLevel = lmObj.model.attributes.lockRank;
                  if ((uFP_filterL0) && (lockLevel === 0)) placeStyle = 'hidden';
                  if ((uFP_filterL1) && (lockLevel === 1)) placeStyle = 'hidden';
                  if ((uFP_filterL2) && (lockLevel === 2)) placeStyle = 'hidden';
                  if ((uFP_filterL3) && (lockLevel === 3)) placeStyle = 'hidden';
                  if ((uFP_filterL4) && (lockLevel === 4)) placeStyle = 'hidden';
                  if ((uFP_filterL5) && (lockLevel === 5)) placeStyle = 'hidden';
                  if ((uFP_filterStaff) && (lockLevel === 6)) placeStyle = 'hidden';
               }
            }

            if(placeStyle == 'visible')
            {
               if(uFP_filterAL)
               {
                  if(lmObj.model.attributes.adLocked) placeStyle = 'hidden';
               }
            }            

            if(placeStyle == 'visible')
            {
               if(uFP_filterNoPhotos || uFP_filterWithPhotos)
               {
                  var nPhotos = 0;
                  for(var loop=0; loop<lmObj.model.attributes.images.length; loop++)
                  {
                     if(lmObj.model.attributes.images[loop].attributes.approved) nPhotos++;
                  }
                  if((uFP_filterNoPhotos) && (nPhotos === 0)) placeStyle = 'hidden';
                  if((uFP_filterWithPhotos) && (nPhotos !== 0)) placeStyle = 'hidden';
               }
            }

            if(placeStyle == 'visible')
            {
               if(uFP_filterNoLinks || uFP_filterWithLinks)
               {
                  var nLinks = lmObj.model.attributes.externalProviderIDs.length;
                  if((uFP_filterNoLinks) && (nLinks === 0)) placeStyle = 'hidden';
                  if((uFP_filterWithLinks) && (nLinks !== 0)) placeStyle = 'hidden';
               }
            }            

            if(placeStyle == 'visible')
            {
               if((uFP_filterPrivate === true) && (lmObj.model.attributes.residential === true))
               {
                  placeStyle = 'hidden';
               }
               else
               {
                  for(var cat=0; cat<filterCats.length; cat++)
                  {
                     if(lmObj.model.attributes.categories.contains(filterCats[cat]))
                     {
                        placeStyle = 'hidden';
                        break;
                     }
                  }
               }
            }
            
            if(placeStyle == 'visible')
            {
               if(uFP_filterNoKeyword || uFP_filterKeyword)
               {
                  var venueName = lmObj.model.attributes.name.toLowerCase();
                  var noKeywordMatch = true;
                  if(uFP_NameKeyword === '')
                  {
                     noKeywordMatch = (venueName !== '');
                  }
                  else
                  {
                     noKeywordMatch = (venueName.indexOf(uFP_NameKeyword) === -1);
                  }
                     
                  if(!noKeywordMatch && uFP_filterNoKeyword) placeStyle = 'hidden';
                  if(noKeywordMatch && uFP_filterKeyword) placeStyle = 'hidden';
               }
            }
            
            if(placeStyle == 'visible')
            {
               if(filterNameID != null)
               {
                  if(uFP_filterCreatedBy === true)
                  {
                     if(filterNameID != lmObj.model.attributes.createdBy) placeStyle = 'hidden';
                  }
                  if(uFP_filterEditedBy === true)
                  {
                     if(filterNameID != lmObj.model.attributes.updatedBy) placeStyle = 'hidden';
                  }
               }
            }
            
         }

         if(uFP_invertFilters === true)
         {
            if(placeStyle == 'hidden') placeStyle = 'visible';
            else placeStyle = 'hidden';
         }
      }

      var geoID = W.map.landmarkLayer.features[v].geometry.id;
      if(document.getElementById(geoID) !== null)
      {
         document.getElementById(geoID).style.visibility = placeStyle;
      }
   }
 
   var uFP_filterUneditable = uroGetCBChecked('_cbFilterUneditablePlaceUpdates');
   var uFP_filterLockRanked = uroGetCBChecked('_cbFilterLockRankedPlaceUpdates');
   var uFP_filterFlagged = uroGetCBChecked("_cbFilterFlaggedPUR");
   var uFP_filterNewPlace = uroGetCBChecked("_cbFilterNewPlacePUR");
   var uFP_filterUpdatedDetails = uroGetCBChecked("_cbFilterUpdatedDetailsPUR");
   var uFP_filterNewPhoto = uroGetCBChecked("_cbFilterNewPhotoPUR");
   var uFP_filterMinPURAge = uroGetCBChecked('_cbEnablePURMinAgeFilter');
   var uFP_filterMaxPURAge = uroGetCBChecked('_cbEnablePURMaxAgeFilter');
   var uFP_invertPURFilters = uroGetCBChecked('_cbInvertPURFilters');
   var uFP_filterHighSeverity = uroGetCBChecked('_cbPURFilterHighSeverity');
   var uFP_filterMedSeverity = uroGetCBChecked('_cbPURFilterMediumSeverity');
   var uFP_filterLowSeverity = uroGetCBChecked('_cbPURFilterLowSeverity');
   var uFP_leavePURGeos = uroGetCBChecked('_cbLeavePURGeos');
   
   var uFP_thresholdMinPURDays = uroGetElmValue('_inputPURFilterMinDays');
   var uFP_thresholdMaxPURDays = uroGetElmValue('_inputPURFilterMaxDays');
   var uFP_isLoggedIn = W.loginManager.isLoggedIn();
   var uFP_userRank = W.loginManager.user.rank;
   
   var purAge = null;
   
   for(var pu in W.map.placeUpdatesLayer.markers)
   {
      if(W.map.placeUpdatesLayer.markers.hasOwnProperty(pu))
      {
         var puObj = W.map.placeUpdatesLayer.markers[pu];
         
         if(W.map.placeUpdatesLayer.getVisibility() === true)
         {
            placeStyle = 'visible';
            if(uFP_masterEnable === true)
            {
               if(uFP_masterEnable === true)
               {
                  if(uFP_filterUneditable === true)
                  {
                     if(puObj.model.attributes.permissions === 0)
                     {
                        placeStyle = 'hidden';
                     }
                     if((placeStyle == 'visible') && (uFP_isLoggedIn))
                     {
                        if(uFP_userRank < puObj.model.attributes.lockRank)
                        {
                           placeStyle = 'hidden';
                        }
                     }
                     if((placeStyle == 'visible') && (puObj.model.attributes.adLocked))
                     {
                        placeStyle = 'hidden';
                     }
                  }

                  if((placeStyle == 'visible') && (uFP_filterLockRanked === true))
                  {
                     if(puObj.model.attributes.lockRank !== 0)
                     {
                        placeStyle = 'hidden';
                     }
                  }

                  if((placeStyle == 'visible') && (uFP_filterFlagged === true))
                  {
                     if(puObj.icon.imageDiv.className.indexOf('flag') != -1)
                     {
                        placeStyle = 'hidden';
                     }
                  }
                  
                  if((placeStyle == 'visible') && (uFP_filterNewPlace === true))
                  {
                     if(puObj.icon.imageDiv.className.indexOf('add_venue') != -1)
                     {
                        placeStyle = 'hidden';
                     }
                  }
                  if((placeStyle == 'visible') && (uFP_filterUpdatedDetails === true))
                  {
                     if((puObj.icon.imageDiv.className.indexOf('update_venue') != -1) || (puObj.icon.imageDiv.className.indexOf('multiple') != -1))
                     {
                        placeStyle = 'hidden';
                     }
                  }
                  if((placeStyle == 'visible') && (uFP_filterNewPhoto === true))
                  {
                     if(puObj.icon.imageDiv.className.indexOf('add_image') != -1)
                     {
                        placeStyle = 'hidden';
                     }
                  }

                  if(uFP_invertPURFilters === true)
                  {
                     if(placeStyle == 'hidden') placeStyle = 'visible';
                     else placeStyle = 'hidden';
                  }

                  if(uFP_filterMinPURAge || uFP_filterMaxPURAge)
                  {
                     purAge = uroGetPURAge(puObj.model);
                     if(uFP_filterMinPURAge === true)
                     {
                        if(purAge < uFP_thresholdMinPURDays) placeStyle = 'hidden';
                     }
                     if(uFP_filterMaxPURAge === true)
                     {
                        if(purAge > uFP_thresholdMaxPURDays) placeStyle = 'hidden';
                     }
                  }

                  if(placeStyle == 'visible')
                  {
                     var purSeverity = puObj._getSeverity();
                     if((uFP_filterHighSeverity) && (purSeverity == "high")) placeStyle = 'hidden';
                     if((placeStyle == 'visible') && (uFP_filterMedSeverity) && (purSeverity == "medium")) placeStyle = 'hidden';
                     if((placeStyle == 'visible') && (uFP_filterLowSeverity) && (purSeverity == "low")) placeStyle = 'hidden';
                  }
               }
            }

            puObj.icon.imageDiv.style.visibility = placeStyle;

            if(uFP_leavePURGeos === false)
            {
               if(puObj.model != null)
               {
                  if(puObj.model.geometry != null)
                  {
                     var puGeo = document.getElementById(puObj.model.geometry.id);
                     if(puGeo !== null)
                     {
                        puGeo.style.visibility = placeStyle;
                     }
                  }
               }
            }
         }
      }
   }    
}
function uroFilterCameras()
{
   if(uroFilterPreamble() === false) return;
   var camLayer = document.getElementById(uroRootContainer+'_svgRoot');
   if(camLayer === null)
   {
      if(uroNullCamLayer === false)
      {
         uroAddLog('caught null camLayer');
         uroNullCamLayer = true;
      }
      return;
   }
   uroNullCamLayer = false;
   if(uroMouseIsDown === false) W.map.camerasLayer.redraw();
   if(uroGetCBChecked('_cbMasterEnable') === true)
   {
      uroUpdateCamEditorList();
      var filterNameID = null;
      var tbUserName = uroGetElmValue('_textCameraEditor');
      var selector = document.getElementById('_selectCameraUserID');
      if(selector.selectedIndex > 0)
      {
         var selUserName = document.getElementById('_selectCameraUserID').selectedOptions[0].innerHTML;
         if(selUserName == tbUserName)
         {
            filterNameID = document.getElementById('_selectCameraUserID').selectedOptions[0].value;
         }
      }      
      if(filterNameID === null)
      {
         var userObj = W.model.users.getByAttributes({userName:tbUserName})[0];
         if(userObj !== undefined)
         {
            filterNameID = userObj.id;
         }
      }

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

            if(uroCam.attributes.updatedBy !== null)
            {
               if(W.model.users.objects[uroCam.attributes.updatedBy] != null)
               {
                  uroCamUpdater = W.model.users.objects[uroCam.attributes.updatedBy].userName;
                  uroCamUpdaterRank = W.model.users.objects[uroCam.attributes.updatedBy].rank;
               }
            }

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

            if(filterNameID != null)
            {
               if(uroGetCBChecked('_cbShowOnlyCamsCreatedBy') === true)
               {
                  if(filterNameID != uroCam.attributes.createdBy) uroCamStyle = 'hidden';
               }
               if(uroGetCBChecked('_cbShowOnlyCamsEditedBy') === true)
               {
                  if(filterNameID != uroCam.attributes.updatedBy) uroCamStyle = 'hidden';
               }
            }
            
            if(uroGetCBChecked('_cbShowOnlyMyCams') === true)
            {
               if((uroUserID != uroCam.attributes.createdBy)&&(uroUserID != uroCam.attributes.updatedBy)) uroCamStyle = 'hidden';
            }

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

               if((uroGetCBChecked('_cbShowWorldCams') === false) && (posWorld === 0)) uroCamStyle = 'hidden';
               if((uroGetCBChecked('_cbShowUSACams') === false) && (posUSA === 0)) uroCamStyle = 'hidden';
               if((uroGetCBChecked('_cbShowNonWorldCams') === false) && (posWorld !== 0) && (posUSA !== 0)) uroCamStyle = 'hidden';
            }

            if((uroGetCBChecked('_cbShowApprovedCams') === false) || (uroGetCBChecked('_cbShowNonApprovedCams') === false))
            {
               if((uroGetCBChecked('_cbShowApprovedCams') === false) && (uroCamApproved === true)) uroCamStyle = 'hidden';
               if((uroGetCBChecked('_cbShowNonApprovedCams') === false) && (uroCamApproved === false)) uroCamStyle = 'hidden';
            }

            if((uroGetCBChecked('_cbShowNonApprovedCams') === true) && (uroCamApproved === false))
            {
               if(((uroGetCBChecked('_cbShowOlderCreatedNonApproved') === true)) && (uroGetCameraAge(uroCam,1) <= uroGetElmValue('_inputCameraMinCreatedDays'))) uroCamStyle = 'hidden';
               if(((uroGetCBChecked('_cbShowOlderUpdatedNonApproved') === true)) && (uroGetCameraAge(uroCam,0) <= uroGetElmValue('_inputCameraMinUpdatedDays'))) uroCamStyle = 'hidden';
            }

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

            if(uroGetCBChecked('_cbShowSpeedCams') === true)
            {
               if((uroGetCBChecked('_cbShowIfNoSpeedSet') === false) && (uroCam.attributes.speed === null)) uroCamStyle = 'hidden';
               if((uroGetCBChecked('_cbShowIfSpeedSet') === false) && (uroCam.attributes.speed !== null)) uroCamStyle = 'hidden';
            }

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

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

            if((uroGetCBChecked('_cbHideCWLCams') === true) && (uroIsCamOnWatchList(uroCam.attributes.id) != -1)) uroCamStyle = 'hidden';

            var uroCamGeometryID = uroCam.geometry.id;
            if(camLayer.getElementById(uroCamGeometryID) !== null)
            {
               if(uroCamStyle == "hidden")
               {
                  camLayer.getElementById(uroCamGeometryID).remove();
               }
            }
         }
      }
   }
}
function uroFilterURs_onObjectsChanged()
{
   if(uroFilterPreamble())
   {
      if(uroBackfilling === false)
      {
         if(uroURDialogIsOpen === false)
         {
            uroURBackfill();
         }
         else
         {
            uroFilterURs();
         }
      }
   }
}
function uroFilterURs_onObjectsAdded()
{
   if(uroFilterPreamble())
   {
      if(uroBackfilling === false)
      {
         uroURBackfill();
      }
   }
}
function uroFilterURs_onObjectsRemoved()
{
   if(uroFilterPreamble())
   {   
      if(uroBackfilling === false)
      {      
         uroURBackfill();
      }
   }
}
function uroBackfillQueueObj(lon, lat, blockSize)
{
   this.lon = lon;
   this.lat = lat;
   this.blockSize = blockSize;
}
function uroURBackfill_GetData()
{
   if(uroBackfillQueue.length === 0)
   {
      uroBackfilling = false;
      uroFilterURs();
      return;
   }   
   
   var nextBFQueueObj = uroBackfillQueue.shift();
      
   var lon = parseFloat(nextBFQueueObj.lon);
   var lat = parseFloat(nextBFQueueObj.lat);
   var blockSize = parseFloat(nextBFQueueObj.blockSize);
   uroAddLog('Backfill square '+lon+','+lat);
   var backfillReq = new XMLHttpRequest();
   backfillReq.onreadystatechange = function ()
   {
      if (backfillReq.readyState == 4)
      {
         uroAddLog('backfill data request, response '+backfillReq.status+' received');
         if (backfillReq.status == 200)
         {
            var tResp = JSON.parse(backfillReq.responseText);
            var urCount = tResp.mapUpdateRequests.objects.length;

            uroAddLog(urCount+' URs loaded for backfill processing');
            if(urCount == 500)
            {
               uroAddLog('WARNING - backfill data may have been pre-filtered by server');
            }

            var backfilled = 0;
            for(var i=0; i<urCount; i++)
            {
               var urID = tResp.mapUpdateRequests.objects[i].id;
               if(W.model.mapUpdateRequests.objects[urID] === undefined)
               {
                  var newUR = require('Waze/Feature/Vector/UpdateRequest');
                  var tUR = new newUR(tResp.mapUpdateRequests.objects[i]);
                  var tPoint = new OpenLayers.Geometry.Point();
                  tPoint.x = tResp.mapUpdateRequests.objects[i].geometry.coordinates[0];
                  tPoint.y = tResp.mapUpdateRequests.objects[i].geometry.coordinates[1];
                  tPoint.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
                  tUR.geometry = tPoint;
                  var tReqBounds = new OpenLayers.Geometry.Polygon();
                  var tBounds = new OpenLayers.Bounds();
                  tBounds.left = tPoint.x;
                  tBounds.right = tPoint.x;
                  tBounds.top = tPoint.y;
                  tBounds.bottom = tPoint.y;
                  tReqBounds.bounds = tBounds;
                  tUR.requestBounds = tReqBounds;
                  W.model.mapUpdateRequests.put(tUR);
                  backfilled++;
               }
            }
            uroAddLog(backfilled+' URs backfilled');
         }
         uroURBackfill_GetData();
      }
   };
   var tURL = 'https://' + document.location.host;
   tURL += Waze.Config.api_base;
   tURL += '/Features?language=en&mapUpdateRequestFilter=0';
   tURL += '&bbox='+(lon)+','+(lat)+','+(lon + blockSize)+','+(lat + blockSize);
   backfillReq.open('GET',tURL,true);
   backfillReq.send();
}
function uroURBackfill()
{
   if((uroGetCBChecked('_cbURBackfill') === false) || (uroGetCBChecked('_cbMasterEnable') === false))
   {
      uroFilterURs();
      return;
   }

   var nativeURCount = Object.keys(W.model.mapUpdateRequests.objects).length;
   if(nativeURCount < 500)
   {
      uroAddLog(nativeURCount+' URs loaded natively, no backfilling required');
      uroFilterURs();
      return;
   }

   uroAddLog('exactly 500 URs loaded, possible server-side filtering requiring backfill...');

   var subSize = 0.1;
   var vpWidth = W.map.getExtent().getWidth();
   var vpHeight = W.map.getExtent().getHeight();
   var vpCentre = W.map.getCenter();
   var vpLL = new OpenLayers.LonLat();
   var vpUR = new OpenLayers.LonLat();
   vpLL.lon = vpCentre.lon - (vpWidth / 2);
   vpLL.lat = vpCentre.lat - (vpHeight / 2);
   vpUR.lon = vpCentre.lon + (vpWidth / 2);
   vpUR.lat = vpCentre.lat + (vpHeight / 2);
   vpLL = vpLL.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
   vpUR = vpUR.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
   vpLL.lon -= (subSize / 2);
   vpLL.lat -= (subSize / 2);
   vpUR.lon += (subSize / 2);
   vpUR.lat += (subSize / 2);
   vpLL.lon = +vpLL.lon.toFixed(1);
   vpLL.lat = +vpLL.lat.toFixed(1);
   vpUR.lon = +vpUR.lon.toFixed(1);
   vpUR.lat = +vpUR.lat.toFixed(1);

   uroBackfilling = true;
   uroBackfillQueue = [];
   for(var bfLat = vpLL.lat; bfLat <= vpUR.lat; bfLat += subSize)
   {
      for(var bfLon = vpLL.lon; bfLon <= vpUR.lon; bfLon += subSize)
      {
         uroBackfillQueue.push(new uroBackfillQueueObj(bfLon, bfLat, subSize));
      }
   }
   uroURBackfill_GetData();
}
function uroFilterURs()
{
   if(uroUserID === -1) return;
   
   // compatibility fix for URComments - based on code supplied by RickZabel
   var hasActiveURFilters = false;
   if(uroGetCBChecked('_cbMasterEnable') === true)
   {
      var urTabInputs = document.getElementById('uroCtrlURs').getElementsByTagName('input');
      for(var loop = 0; loop < urTabInputs.length; loop++)
      {
         if(urTabInputs[loop].type == 'checkbox')
         {
            var ignoreCB = false;
            ignoreCB = ignoreCB || (urTabInputs[loop].id == '_cbCaseInsensitive');
            ignoreCB = ignoreCB || (urTabInputs[loop].id == '_cbNoFilterForTaggedURs');
            if((urTabInputs[loop].checked) && (ignoreCB === false))
            {
               hasActiveURFilters = true;
               break;
            }
         }
      }
   }
   sessionStorage.UROverview_hasActiveURFilters = hasActiveURFilters;
   if(uroFilterPreamble() === false) return;
   uroRefreshUpdateRequestSessions();
   var selectorResolver = document.getElementById('_selectURResolverID');
   var selectorCommentUser = document.getElementById('_selectURUserID');

   if(uroGetCBChecked('_cbURResolverIDFilter') === false)
   {
      while(selectorResolver.options.length > 0)
      {
         selectorResolver.options.remove(0);
      }
   }
   if(uroGetCBChecked('_cbURUserIDFilter') === false)
   {
      while(selectorCommentUser.options.length > 0)
      {
         selectorCommentUser.options.remove(0);
      }
   }
   if(Object.keys(W.model.updateRequestSessions.objects).length === 0)
   {
      return;
   }
   var commenterUser = null;
   if(uroGetCBChecked('_cbURUserIDFilter') === true)
   {
      if(selectorCommentUser.options.length === 0)
      {
         uroUpdateUserList();
      }
      if(selectorCommentUser.selectedOptions[0] != null)
      {
         commenterUser = parseInt(selectorCommentUser.selectedOptions[0].value);
      }
   }
   var resolverUser = null;
   if(uroGetCBChecked('_cbURResolverIDFilter') === true)
   {
      if(selectorResolver.options.length === 0)
      {
         uroUpdateResolverList();
      }
      if(selectorResolver.selectedOptions[0] != null)
      {
         resolverUser = parseInt(selectorResolver.selectedOptions[0].value);
      }
   }
   uroCustomMarkerList = [];

   var uFURs_masterEnable = uroGetCBChecked('_cbMasterEnable');
   var filterOutsideEditableArea = uroGetCBChecked('_cbURFilterOutsideArea');
   var filterSolved = uroGetCBChecked('_cbFilterSolved');
   var filterUnidentified = uroGetCBChecked('_cbFilterUnidentified');
   var filterClosed = uroGetCBChecked('_cbFilterClosedUR');
   var filterOpen = uroGetCBChecked('_cbFilterOpenUR');
   var filterDescMustBePresent = uroGetCBChecked('_cbURDescriptionMustBePresent');
   var filterDescMustBeAbsent = uroGetCBChecked('_cbURDescriptionMustBeAbsent');
   var filterKeywordMustBePresent = uroGetCBChecked('_cbEnableKeywordMustBePresent');
   var filterKeywordMustBeAbsent = uroGetCBChecked('_cbEnableKeywordMustBeAbsent');
   var filterMinURAge = uroGetCBChecked('_cbEnableMinAgeFilter');
   var filterMaxURAge = uroGetCBChecked('_cbEnableMaxAgeFilter');
   var filterMinComments = uroGetCBChecked('_cbEnableMinCommentsFilter');
   var filterMaxComments = uroGetCBChecked('_cbEnableMaxCommentsFilter');
   var filterReporterLastCommenter = uroGetCBChecked('_cbHideIfReporterLastCommenter');
   var filterReporterNotLastCommenter = uroGetCBChecked('_cbHideIfReporterNotLastCommenter');
   var filterHideAnyComments = uroGetCBChecked('_cbHideAnyComments');
   var filterHideNotLastCommenter = uroGetCBChecked('_cbHideIfNotLastCommenter');
   var filterHideMyComments = uroGetCBChecked('_cbHideMyComments');
   var filterIfLastCommenter = uroGetCBChecked('_cbHideIfLastCommenter');
   var filterIfNotLastCommenter = uroGetCBChecked('_cbHideIfNotLastCommenter');
   var filterCommentMinAge = uroGetCBChecked('_cbEnableCommentAgeFilter2');
   var filterCommentMaxAge = uroGetCBChecked('_cbEnableCommentAgeFilter');
   var filterUserID = uroGetCBChecked('_cbURUserIDFilter');
   var filterMyFollowed = uroGetCBChecked('_cbHideMyFollowed');
   var filterMyUnfollowed = uroGetCBChecked('_cbHideMyUnfollowed');
   
   var filterWazeAuto = uroGetCBChecked('_cbFilterWazeAuto');
   var filterRoadworks = uroGetCBChecked('_cbFilterRoadworks');
   var filterConstruction = uroGetCBChecked('_cbFilterConstruction');
   var filterClosure = uroGetCBChecked('_cbFilterClosure');
   var filterEvent = uroGetCBChecked('_cbFilterEvent');
   var filterNote = uroGetCBChecked('_cbFilterNote');
   var filterWSLM = uroGetCBChecked('_cbFilterWSLM');
   var filterBOG = uroGetCBChecked('_cbFilterBOG');
   var filterDifficult = uroGetCBChecked('_cbFilterDifficult');
   
   var filterIncorrectTurn = uroGetCBChecked('_cbFilterIncorrectTurn');
   var filterIncorrectAddress = uroGetCBChecked('_cbFilterIncorrectAddress');
   var filterIncorrectRoute = uroGetCBChecked('_cbFilterIncorrectRoute');
   var filterMissingRoundabout = uroGetCBChecked('_cbFilterMissingRoundabout');
   var filterGeneralError = uroGetCBChecked('_cbFilterGeneralError');
   var filterTurnNotAllowed = uroGetCBChecked('_cbFilterTurnNotAllowed');
   var filterIncorrectJunction = uroGetCBChecked('_cbFilterIncorrectJunction');
   var filterMissingBridgeOverpass = uroGetCBChecked('_cbFilterMissingBridgeOverpass');
   var filterWrongDrivingDirection = uroGetCBChecked('_cbFilterWrongDrivingDirection');
   var filterMissingExit = uroGetCBChecked('_cbFilterMissingExit');
   var filterMissingRoad = uroGetCBChecked('_cbFilterMissingRoad');
   var filterMissingLandmark = uroGetCBChecked('_cbFilterMissingLandmark');
   var filterNativeSpeedLimit = uroGetCBChecked('_cbFilterSpeedLimits');
   var filterBlockedRoad = uroGetCBChecked('_cbFilterBlockedRoad');
   var filterUndefined = uroGetCBChecked('_cbFilterUndefined');
   
   var invertURFilters = uroGetCBChecked('_cbInvertURFilter');
   var invertURStateFilters = uroGetCBChecked('_cbInvertURStateFilter');
   var noFilterTaggedURs = uroGetCBChecked('_cbNoFilterForTaggedURs');
   var noFilterURInURL = uroGetCBChecked('_cbNoFilterForURInURL');
   
   var keywordPresent = uroGetElmValue('_textKeywordPresent');
   var keywordAbsent = uroGetElmValue('_textKeywordAbsent');
   var thresholdMinAge = uroGetElmValue('_inputFilterMinDays');
   var thresholdMaxAge = uroGetElmValue('_inputFilterMaxDays');
   var thresholdMinComments = uroGetElmValue('_inputFilterMinComments');
   var thresholdMaxComments = uroGetElmValue('_inputFilterMaxComments');
   var thresholdMaxCommentAge = uroGetElmValue('_inputFilterCommentDays');
   var thresholdMinCommentAge = uroGetElmValue('_inputFilterCommentDays2');
   var ignoreOtherEditorComments = uroGetCBChecked('_cbIgnoreOtherEditorComments');
   
   var urcFilteringIsActive = false;
   var urcCB = document.getElementById('URCommentsFilterEnabled');
   if(urcCB !== null)
   {
      if(urcCB.checked)
      {
         urcFilteringIsActive = true;
      }
   }
   urcCB = document.getElementById('URCommentUROOnlyMyUR');
   if(urcCB !== null)
   {
      if(urcCB.checked)
      {
         urcFilteringIsActive = true;
      }
   }
   urcCB = document.getElementById('URCommentUROHideTagged');
   if(urcCB !== null)
   {
      if(urcCB.checked)
      {
         urcFilteringIsActive = true;
      }
   }

   
   
   for (var urobj in W.model.mapUpdateRequests.objects)
   {
      if(W.model.mapUpdateRequests.objects.hasOwnProperty(urobj))
      {
         var ureq = W.model.mapUpdateRequests.objects[urobj];
         var ureqID = null;
         if(ureq.fid === null) ureqID = ureq.attributes.id;
         else ureqID = ureq.fid;
         
         var urStyle = 'visible';         
         var inhibitFiltering = ((ureqID == uroURIDInURL) && (noFilterURInURL));
         var hasMyComments = false;
         var nComments = 0;
         var customType = uroGetCustomType(ureqID, "ur");
         if(W.model.updateRequestSessions.objects[ureqID] != null)
         {
            nComments = W.model.updateRequestSessions.objects[ureqID].comments.length;
            if((uFURs_masterEnable === false) && (nComments === 0))
            {
               // when master enable is turned off, we want to make sure that all URs, including ones that were previously hidden, are correctly
               // displayed in their native form - i.e. no comment count or custom conversation bubbles.  The easiest way to achieve this is to
               // force the uroRenderCustomMarkers code to test for the presence of these bubbles on each UR, which we do by setting a non-zero
               // comment count for each UR...  For URs which genuinely do have no comments we use -1 to indicate that we're not really setting
               // a comment count, but that we still need to do something that wouldn't be achieved by using 0.
               nComments = -1;
            }
         }
         
         if((uFURs_masterEnable === true) && (inhibitFiltering === false))
         {
            var wazeauto_ur = false;
            var ukroadworks_ur = false;
            var construction_ur = false;
            var closure_ur = false;
            var event_ur = false;
            var note_ur = false;
            var wslm_ur = false;
            var bog_ur = false;
            var difficult_ur = false;

            var filterByNotIncludedKeyword = false;
            var filterByIncludedKeyword = true;

            var desc = '';
            if(ureq.attributes.description !== null) desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, "");

            if(customType === 0) ukroadworks_ur = true;
            else if(customType === 1) construction_ur = true;
            else if(customType === 2) closure_ur = true;
            else if(customType === 3) event_ur = true;
            else if(customType === 4) note_ur = true;
            else if(customType === 5) wslm_ur = true;
            else if(customType === 6) bog_ur = true;
            else if(customType === 7) difficult_ur = true;

            // check UR against editable area...

            if(filterOutsideEditableArea === true)
            {
               if(ureq.canEdit() === false) urStyle = 'hidden';
            }
            // check UR against current session ignore list...
            if(uroIsOnIgnoreList(ureqID)) urStyle = 'hidden';
            
            // state-age filtering
            if(urStyle == 'visible')
            {
               // check against closed/not identified filtering if enabled...
               if(filterSolved === true)
               {
                  if(ureq.attributes.resolution === 0) urStyle = 'hidden';
               }
               if(filterUnidentified === true)
               {
                  if(ureq.attributes.resolution == 1) urStyle = 'hidden';
               }

               if((ureq.attributes.resolvedOn !== null) && (filterClosed === true))
               {
                  urStyle = 'hidden';
               }

               if((ureq.attributes.resolvedOn === null) && (filterOpen === true))
               {
                  urStyle = 'hidden';
               }

               if(urStyle == 'visible')
               {
                  // check UR against keyword filtering if enabled...
                  if(filterDescMustBePresent === true)
                  {
                     if(desc === '') urStyle = 'hidden';
                  }
                  if(filterDescMustBeAbsent === true)
                  {
                     if(desc !== '') urStyle = 'hidden';
                  }

                  if(filterKeywordMustBePresent === true)
                  {
                     var keywordIsPresentInDesc = uroKeywordPresent(desc,keywordPresent);
                     filterByIncludedKeyword &= (!keywordIsPresentInDesc);
                  }
                  if(filterKeywordMustBeAbsent === true)
                  {
                     var keywordIsAbsentInDesc = uroKeywordPresent(desc,keywordAbsent);
                     filterByNotIncludedKeyword |= keywordIsAbsentInDesc;
                  }
               }

               if(urStyle == 'visible')
               {
                  // do age-based filtering if enabled
                  if(filterMinURAge === true)
                  {
                     if(uroGetURAge(ureq,0,false) < thresholdMinAge) urStyle = 'hidden';
                  }
                  if(filterMaxURAge === true)
                  {
                     if(uroGetURAge(ureq,0,false) > thresholdMaxAge) urStyle = 'hidden';
                  }
               }

               if(urStyle == 'visible')
               {
                  if(resolverUser !== null)
                  {
                     if(ureq.attributes.resolvedBy != resolverUser) urStyle = 'hidden';
                  }
               }

               if(urStyle == 'visible')
               {
                  // do comments/following filtering
                  if(W.model.updateRequestSessions.objects[ureqID] != null)
                  {
                     nComments = W.model.updateRequestSessions.objects[ureqID].comments.length;
                     var commentDaysOld = -1;


                     if(filterMinComments === true)
                     {
                        if(nComments < thresholdMinComments) urStyle = 'hidden';
                     }
                     if(filterMaxComments === true)
                     {
                        if(nComments > thresholdMaxComments) urStyle = 'hidden';
                     }


                     if(nComments > 0)
                     {
                        var reporterIsLastCommenter = false;
                        if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == -1) reporterIsLastCommenter = true;

                        if(filterReporterLastCommenter === true)
                        {
                           if(reporterIsLastCommenter === true) urStyle = 'hidden';
                        }
                        else if(filterReporterNotLastCommenter === true)
                        {
                           if(reporterIsLastCommenter === false) urStyle = 'hidden';
                        }

                        hasMyComments = uroURHasMyComments(ureqID);
                        if(hasMyComments === false)
                        {
                           if(filterHideAnyComments === true) urStyle = 'hidden';
                           if(filterHideNotLastCommenter === true) urStyle = 'hidden';
                        }
                        else
                        {
                           if(filterHideMyComments === true) urStyle = 'hidden';

                           var userIsLastCommenter = false;
                           if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == uroUserID) userIsLastCommenter = true;

                           if(filterIfLastCommenter === true)
                           {
                              if(userIsLastCommenter === true) urStyle = 'hidden';
                           }
                           else if(filterIfNotLastCommenter === true)
                           {
                              if(userIsLastCommenter === false) urStyle = 'hidden';
                           }
                        }
                        
                        var cidx;
                        
                        if(ignoreOtherEditorComments === false)
                        {
                           commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1]);
                        }
                        else
                        {
                           for(cidx=0; cidx<nComments; cidx++)
                           {
                              var cObj = W.model.updateRequestSessions.objects[ureqID].comments[cidx];
                              if((cObj.userID == uroUserID) || (cObj.userID == -1))
                              {
                                 commentDaysOld = uroGetCommentAge(cObj);
                              }
                           }                        
                        }
                        if((filterCommentMinAge === true) && (commentDaysOld != -1))
                        {
                           if(thresholdMinCommentAge > commentDaysOld) urStyle = 'hidden';
                        }
                        if((filterCommentMaxAge === true) && (commentDaysOld != -1))
                        {
                           if(thresholdMaxCommentAge < commentDaysOld) urStyle = 'hidden';
                        }
                        
                        if((commenterUser !== null) && (urStyle != 'hidden'))
                        {
                           urStyle = 'hidden';
                           for(cidx=0; cidx<nComments; cidx++)
                           {
                              if(W.model.updateRequestSessions.objects[ureqID].comments[cidx].userID == commenterUser)
                              {
                                 urStyle = 'visible';
                                 break;
                              }
                           }
                        }

                        var commentText = '';
                        for(cidx=0; cidx<nComments; cidx++)
                        {
                           commentText += W.model.updateRequestSessions.objects[ureqID].comments[cidx].text;
                        }

                        if(filterKeywordMustBePresent === true)
                        {
                           var keywordIsPresentInComments = uroKeywordPresent(commentText,keywordPresent);
                           filterByIncludedKeyword &= (!keywordIsPresentInComments);
                        }
                        if(filterKeywordMustBeAbsent === true)
                        {
                           var keywordIsAbsentInComments = uroKeywordPresent(commentText,keywordAbsent);
                           filterByNotIncludedKeyword |= keywordIsAbsentInComments;
                        }
                     }
                     else
                     {
                        if(filterUserID === true)
                        {
                           urStyle = 'hidden';
                        }
                     }

                     filterByNotIncludedKeyword &= filterKeywordMustBeAbsent;
                     filterByIncludedKeyword &= filterKeywordMustBePresent;
                     if(filterByNotIncludedKeyword || filterByIncludedKeyword)
                     {
                        urStyle = 'hidden';
                     }

                     if(W.model.updateRequestSessions.objects[ureqID].isFollowing === true)
                     {
                        if(filterMyFollowed === true) urStyle = 'hidden';
                     }
                     else
                     {
                        if(filterMyUnfollowed === true) urStyle = 'hidden';
                     }
                  }
               }

               if(invertURStateFilters === true)
               {
                 if(urStyle == 'hidden') urStyle = 'visible';
                 else urStyle = 'hidden';
               }               
            }

            // type filtering
            if(urStyle == 'visible')
            {
               // Test for Waze automatic URs before any others - these always (?) get inserted as General Error URs,
               // so we can't filter them by type...
               if(desc.indexOf('Waze Automatic:') != -1)
               {
                  wazeauto_ur = true;
               }

               if(wazeauto_ur === true)
               {
                  if(filterWazeAuto === true) urStyle = 'hidden';
               }

               else if(ukroadworks_ur === true)
               {
                  if(filterRoadworks === true) urStyle = 'hidden';
               }
               else if(construction_ur === true)
               {
                  if(filterConstruction === true) urStyle = 'hidden';
               }
               else if(closure_ur === true)
               {
                  if(filterClosure === true) urStyle = 'hidden';
               }
               else if(event_ur === true)
               {
                  if(filterEvent === true) urStyle = 'hidden';
               }
               else if(note_ur === true)
               {
                  if(filterNote === true) urStyle = 'hidden';
               }
               else if(wslm_ur === true)
               {
                  if(filterWSLM === true) urStyle = 'hidden';
               }
               else if(bog_ur === true)
               {
                  if(filterBOG === true) urStyle = 'hidden';
               }
               else if(difficult_ur === true)
               {
                  if(filterDifficult === true) urStyle = 'hidden';
               }

               else if(ureq.attributes.type == 6)
               {
                  if(filterIncorrectTurn === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 7)
               {
                  if (filterIncorrectAddress === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 8)
               {
                  if(filterIncorrectRoute === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 9)
               {
                  if(filterMissingRoundabout === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 10)
               {
                  if(filterGeneralError === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 11)
               {
                  if(filterTurnNotAllowed === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 12)
               {
                  if(filterIncorrectJunction === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 13)
               {
                  if(filterMissingBridgeOverpass === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 14)
               {
                  if(filterWrongDrivingDirection === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 15)
               {
                  if(filterMissingExit === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 16)
               {
                  if(filterMissingRoad === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 18)
               {
                  if(filterMissingLandmark === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 19)
               {
                  if(filterBlockedRoad === true) urStyle = 'hidden';
               }
               else if(ureq.attributes.type == 23)
               {
                  if(filterNativeSpeedLimit === true) urStyle = 'hidden';
               }
               else if(filterUndefined === true) urStyle = 'hidden';

               if(invertURFilters === true)
               {
                 if(urStyle == 'hidden') urStyle = 'visible';
                 else urStyle = 'hidden';
               }
            }

            // stage-age filtering override for tagged URs
            if(noFilterTaggedURs === true)
            {
               if(ukroadworks_ur === true)
               {
                  if(filterRoadworks === false) urStyle = 'visible';
               }
               else if(construction_ur === true)
               {
                  if(filterConstruction === false) urStyle = 'visible';
               }
               else if(closure_ur === true)
               {
                  if(filterClosure === false) urStyle = 'visible';
               }
               else if(event_ur === true)
               {
                  if(filterEvent === false) urStyle = 'visible';
               }
               else if(note_ur === true)
               {
                  if(filterNote === false) urStyle = 'visible';
               }
               else if(wslm_ur === true)
               {
                  if(filterWSLM === false) urStyle = 'visible';
               }
            }
         }
         // only touch marker visibility if we've got active filter settings, or if URComments is not
         // doing any filtering of its own
         if((hasActiveURFilters === true) || (urcFilteringIsActive === false) || (uFURs_masterEnable === false))
         {
            W.map.updateRequestLayer.markers[urobj].icon.imageDiv.style.visibility = urStyle;
         }
         if(urStyle != 'hidden')
         {
            uroAddCustomMarkers(ureqID,'ur',customType, hasMyComments, nComments);
         }
      }
   }
   
   uroRenderCustomMarkers('ur');
}
function uroGetProblemTypes()
{
   uroKnownProblemTypeIDs = [];
   uroKnownProblemTypeNames = [];
   var tProblemList = I18n.lookup("problems.types");
   for(var tObj in tProblemList)
   {
      if(tObj !== undefined)
      {
         uroKnownProblemTypeIDs.push(parseInt(tObj));
         uroKnownProblemTypeNames.push(tProblemList[tObj].title);
      }
   }    
}
function uroFilterProblems()
{
   if(uroFilterPreamble() === false) return;
   var selector;

   if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') === false) && (uroGetCBChecked('_cbMPClosedUserIDFilter') === false))
   {
      selector = document.getElementById('_selectMPUserID');
      while(selector.options.length > 0)
      {
         selector.options.remove(0);
      }
   }

   var solverUser = null;
   if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') === true) || (uroGetCBChecked('_cbMPClosedUserIDFilter') === true))
   {
      selector = document.getElementById('_selectMPUserID');
      if(selector.options.length === 0)
      {
         uroUpdateMPSolverList();
      }
      if(selector.selectedOptions[0] != null)
      {
         solverUser = parseInt(selector.selectedOptions[0].value);
      }
   }

   var urobj;
   var problem;
   var problemStyle;
   var problem_marker_img;

   var uFP_masterEnable = uroGetCBChecked('_cbMasterEnable');
   var filter_OutsideEditableArea = uroGetCBChecked('_cbMPFilterOutsideArea');
   var filter_Solved = uroGetCBChecked('_cbMPFilterSolved');
   var filter_Unidentified = uroGetCBChecked('_cbMPFilterUnidentified');
   var filter_Closed = uroGetCBChecked('_cbMPFilterClosed');
   var filter_NotClosedUserID = uroGetCBChecked('_cbMPNotClosedUserIDFilter');
   var filter_ClosedUserID = uroGetCBChecked('_cbMPClosedUserIDFilter');
   var filter_Reopened = uroGetCBChecked('_cbMPFilterReopenedProblem');
   
   var filter_LowSeverity = uroGetCBChecked('_cbMPFilterLowSeverity');
   var filter_MediumSeverity = uroGetCBChecked('_cbMPFilterMediumSeverity');
   var filter_HighSeverity = uroGetCBChecked('_cbMPFilterHighSeverity');
   
   var filter_TurnProblems = uroGetCBChecked('_cbMPFilterTurnProblem');
   
   var filterTypes = [];
   var i;
   for(i=0; i<uroKnownProblemTypeIDs.length; i++)
   {
      if(uroGetCBChecked('_cbMPFilter_T'+uroKnownProblemTypeIDs[i])) filterTypes.push(uroKnownProblemTypeIDs[i]);
   }    
   var filter_TypeUnknown = uroGetCBChecked('_cbMPFilterUnknownProblem');
   
   var filter_TaggedElgin = uroGetCBChecked('_cbFilterElgin');
   var filter_TaggedTrafficCast = uroGetCBChecked('_cbFilterTrafficCast');
   var filter_TaggedTrafficMaster = uroGetCBChecked('_cbFilterTrafficMaster');
   var filter_TaggedCaltrans = uroGetCBChecked('_cbFilterCaltrans');
   var filter_TaggedTFL = uroGetCBChecked('_cbFilterTFL');
   
   var filter_Invert = uroGetCBChecked('_cbInvertMPFilter');


   for (urobj in W.model.problems.objects)
   {
      if(W.model.problems.objects.hasOwnProperty(urobj))
      {
         problem = W.model.problems.objects[urobj];
         
         problemStyle = 'visible';
         var ureqID = null;
         var customType = null;

         if(uFP_masterEnable === true)
         {
            var elgin_mp = false;
            var trafficcast_mp = false;
            var trafficmaster_mp = false;
            var caltrans_mp = false;
            var tfl_mp = false;

            ureqID = problem.attributes.id;
            customType = uroGetCustomType(ureqID, "mp");
            if(customType === 100) elgin_mp = true;
            else if(customType === 101) trafficcast_mp = true;
            else if(customType === 102) trafficmaster_mp = true;
            else if(customType === 103) caltrans_mp = true;
            else if(customType === 104) tfl_mp = true;
            
            // check problem against current session ignore list...
            if(uroIsOnIgnoreList(ureqID)) problemStyle = 'hidden';

            if(filter_OutsideEditableArea === true)
            {
               if(problem.canEdit() === false)
               {
                  problemStyle = 'hidden';
               }
            }

            // check against closed/not identified filtering if enabled...
            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(filter_Solved === true)
                  {
                     if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
                  }
                  if(filter_Unidentified === true)
                  {
                     if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
                  }
               }
            }

            if(filter_Closed === true)
            {
               if(problem.attributes.open === false)
               {
                  problemStyle = 'hidden';
               }
            }

            if(problemStyle == 'visible')
            {
               if(solverUser !== null)
               {
                  if((filter_NotClosedUserID === true) && (problem.attributes.resolvedBy == solverUser)) problemStyle = 'hidden';
                  if((filter_ClosedUserID === true) && (problem.attributes.resolvedBy != solverUser)) problemStyle = 'hidden';
               }
            }

            if(problemStyle == 'visible')
            {
               var problemType = null;
               if(uroDOMHasTurnProblems)
               {
                  problemType = problem.attributes.problemType;
               }
               else
               {
                  problemType = problem.attributes.subType;
               }

               if(elgin_mp === true)
               {
                  if(filter_TaggedElgin === true) problemStyle = 'hidden';
               }
               else if(trafficcast_mp === true)
               {
                  if(filter_TaggedTrafficCast === true) problemStyle = 'hidden';
               }
               else if(trafficmaster_mp === true)
               {
                  if(filter_TaggedTrafficMaster === true) problemStyle = 'hidden';
               }
               else if(caltrans_mp === true)
               {
                  if(filter_TaggedCaltrans === true) problemStyle = 'hidden';
               }
               else if(tfl_mp === true)
               {
                  if(filter_TaggedTFL === true) problemStyle = 'hidden';
               }

               else if(uroKnownProblemTypeIDs.indexOf(problemType) !== -1)
               {
                  if(filterTypes.indexOf(problemType) !== -1)
                  {
                     problemStyle = 'hidden';
                  }
               }
               else if(filter_TypeUnknown === true) problemStyle = 'hidden';

               if(filter_Reopened === true)
               {
                  if((problem.attributes.open === true) && (problem.attributes.resolvedOn !== null))
                  {
                     problemStyle = 'hidden';
                  }
               }


               if(filter_Invert === true)
               {
                  if(problemStyle == 'hidden') problemStyle = 'visible';
                  else problemStyle = 'hidden';
               }


               if(problem.attributes.weight <= 3)
               {
                  if(filter_LowSeverity === true) problemStyle = 'hidden';
               }
               else if(problem.attributes.weight <= 7)
               {
                  if(filter_MediumSeverity === true) problemStyle = 'hidden';
               }
               else if(filter_HighSeverity === true) problemStyle = 'hidden';
            }
         }

         W.map.problemLayer.markers[urobj].icon.imageDiv.style.visibility = problemStyle;

         if((problemStyle != 'hidden') && (ureqID !== null) && (customType !== null))
         {
            uroAddCustomMarkers(ureqID,'mp',customType, false, 0);
         }
      }
   }

   if(uroDOMHasTurnProblems)
   {
      for (urobj in W.model.turnProblems.objects)
      {
         if(W.model.turnProblems.objects.hasOwnProperty(urobj))
         {
            problem = W.model.turnProblems.objects[urobj];
            problemStyle = 'visible';

            if(uFP_masterEnable === true)
            {
               // check problem against current session ignore list...
               if(uroIsOnIgnoreList(problem.attributes.id)) problemStyle = 'hidden';

               // check against closed/not identified filtering if enabled...
               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(filter_Solved === true)
                     {
                        if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
                     }
                     if(filter_Unidentified === true)
                     {
                        if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
                     }
                  }
               }

               if(filter_Closed === true)
               {
                  if(problem.attributes.open === false)
                  {
                     problemStyle = 'hidden';
                  }
               }

               if(problemStyle == 'visible')
               {
                  if(filter_TurnProblems === true) problemStyle = 'hidden';

                  if(filter_Reopened === true)
                  {
                     if((problem.attributes.open === true) && (problem.attributes.resolvedOn !== null))
                     {
                        problemStyle = 'hidden';
                     }
                  }

                  if(filter_Invert === true)
                  {
                     if(problemStyle == 'hidden') problemStyle = 'visible';
                     else problemStyle = 'hidden';
                  }
               }
            }
            W.map.problemLayer.markers[urobj].icon.imageDiv.style.visibility = problemStyle;
         }
      }
   } 
   uroRenderCustomMarkers('mp');
}

function uroToHex(decValue,digits)
{
   var modifier = 1;
   for(var i=0; i<digits; i++)
   {
      modifier *= 16;
   }
   decValue = parseInt(decValue);
   decValue += modifier;
   var retval = decValue.toString(16);
   retval = retval.substr(-digits);
   retval = retval.toUpperCase();
   return retval;
}
function uroFilterPreamble()
{
   var mapviewport = document.getElementsByClassName("olMapViewport")[0];
   if(mapviewport === null)
   {
      if(uroNullMapViewport === false)
      {
         uroAddLog('caught null mapviewport');
         uroNullMapViewport = true;
      }
      return false;
   }
   
   var uiElms = document.getElementById('uroCtrlMisc');
   if(uiElms == null) 
   {
      uroAddLog('caught missing UI');
      return false;
   }
   if(uiElms.innerHTML.length === 0)
   {
      uroAddLog('caught empty UI');
      return false;
   }
   
   uroNullMapViewport = false;

   return true;
}
function uroFilterItems_URTabClick()
{
   uroFilterURs();
}
function uroFilterItems_MPTabClick()
{
   uroFilterProblems();
}
function uroFilterItems_PlacesTabClick()
{
   uroFilterPlaces();
}
function uroFilterItems_CamerasTabClick()
{
   uroFilterCameras();
}
function uroFilterItems_MiscTabClick()
{
   uroFilterItems();
}
function uroFilterItems_MasterEnableClick()
{
   if(uroGetCBChecked('_cbMasterEnable') === false)
   {
      uroHidePopup();
   }
   uroFilterItems();
}

function uroScaleTheScaleBar()
{
   // adjust the scale bar to more accurately reflect true distances at all latitudes
   
   var currLat = W.map.getCenter().transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")).lat;

   if((currLat < 85) && (currLat > -85))
   {
      var cosLat = Math.cos((currLat * Math.PI) / 180);
      var scaleElm;
      var elmWidth;
      
      scaleElm = document.getElementsByClassName('olControlScaleLineTop')[0];
      if(scaleElm.innerHTML.indexOf(' ') !== -1)
      {
         elmWidth = Math.round((scaleElm.clientWidth + 2) / cosLat);
         scaleElm.innerHTML = scaleElm.innerHTML.replace(' ','');
         scaleElm.style.width = elmWidth + 'px';
      }
      scaleElm = document.getElementsByClassName('olControlScaleLineBottom')[0];
      if(scaleElm.innerHTML.indexOf(' ') !== -1)
      {
         elmWidth = Math.round((scaleElm.clientWidth + 2) / cosLat);
         scaleElm.innerHTML = scaleElm.innerHTML.replace(' ','');
         scaleElm.style.width = elmWidth + 'px';
      }
   }
}

function uroFilterItems()
{  
   uroScaleTheScaleBar();  
   uroFilterProblems(); 
   uroFilterPlaces();  
   uroFilterCameras(); 
   uroFilterURs();
}
function uroFilterItemsOnMove()
{
   W.map.events.unregister('mousemove',null,uroFilterItemsOnMove);
   uroFilterItems();
}

function uroDeleteObject()
{
   uroAddLog('delete camera ID '+uroShownFID);
   if(W.model.cameras.objects[uroShownFID] === null)
   {
      uroAddLog('camera object not found...');
      return false;
   }
   uroRemoveCamFromWatchList();
   var actionObj = require('Waze/Action/DeleteObject');
   var deleteAction = new actionObj(W.model.cameras.objects[uroShownFID], null);
   W.model.actionManager.add(deleteAction);
   uroExitPopup();
   uroHidePopup();
   return false;
}

function uroGetUserNameAndRank(userID)
{
   var userName;
   var userLevel;
   if(W.model.users.objects[userID] != null)
   {
      userName = W.model.users.objects[userID].userName;
      if(userName === undefined)
      {
         userName = userID;
      }
      userLevel = W.model.users.objects[userID].rank + 1;
   }
   else
   {
      userName = userID;
      userLevel = '?';
   }
   return userName + ' (' + userLevel + ')';
}
function uroCheckCommentsForTag(idSrc, customText)
{
   var ursObj = W.model.updateRequestSessions.objects[idSrc];
   if(typeof(ursObj) == 'undefined') return -1;
   if(ursObj.comments.length === 0) return -1;

   for(var idx=ursObj.comments.length-1; idx>=0; idx--)
   {
      for(var tag=0; tag<uroCustomURTags.length; tag++)
      {
         var keyword = uroCustomURTags[tag];
         if(ursObj.comments[idx].text.indexOf(keyword) != -1)
         {
            return tag;
         }
      }
      
      if(customText !== '')
      {
         if(ursObj.comments[idx].text.toLowerCase().indexOf(customText) != -1)
         {
            return 99;
         }
      }
   }
   return -1;
}

function uroGetCustomMarkerIdx(customType)
{
   if(customType === 0) return 1;      // ROADWORKS
   if(customType === 1) return 1;      // CONSTRUCTION
   if(customType === 2) return 0;      // CLOSURE
   if(customType === 3) return 4;      // EVENT
   if(customType === 4) return 3;      // NOTE
   if(customType === 5) return 5;      // WSLM
   if(customType === 6) return 11;     // BOG
   if(customType === 7) return 12;     // DIFFICULT
   
   if(customType === 98) return 5;     // Native speed limit URs
   if(customType === 99) return 2;     // custom text
   
   if(customType === 100) return 6;    // ELGIN
   if(customType === 101) return 7;    // TRAFFICCAST
   if(customType === 102) return 8;    // TRAFFICMASTER
   if(customType === 103) return 9;    // CALTRANS
   if(customType === 104) return 10;   // TFL
   
   return -1;
}
function uroGetCustomType(idSrc, markerType)
{
   var desc = '';
   var provider = '';
   var customText = '';
   if(uroGetCBChecked('_cbCustomKeywordMarkers')) customText = document.getElementById('_textCustomKeyword').value.toLowerCase();
   
   if(markerType == "ur")
   {
      var ureq = W.model.mapUpdateRequests.objects[idSrc];
      
      // early test for native speed limit URs
      if(ureq.attributes.type == 23) return 98;
      
      // UR objects always have a .description attribute, which is set to null if empty...
      if(ureq.attributes.description !== null)
      {
         desc = ureq.attributes.description;
      }
   }
   else if(markerType == "mp")
   {
      var mp = W.model.problems.objects[idSrc];
      // ...whereas MP objects with a blank description don't even get the attribute
      if(mp.attributes.description != null)
      {
         desc = mp.attributes.description;
      }
      if(mp.attributes.provider != null)
      {
         provider = mp.attributes.provider;
      }
   }

   if(desc !== '')
   {
      if(markerType == 'ur')
      {
         for(var tag=0; tag<uroCustomURTags.length; tag++)
         {
            var keyword = uroCustomURTags[tag];
            if(desc.indexOf(keyword) != -1)
            {
               return tag;
            }
         }         
      }
      
      if((uroGetCBChecked('_cbCustomKeywordMarkers')) && (customText !== ''))
      {
         if(desc.toLowerCase().indexOf(customText) != -1) return 99;
      }

      if(markerType == 'mp')
      {
         if(desc.indexOf('[Elgin]') != -1) return 100;
         if(desc.indexOf('[TrafficCast]') != -1) return 101;
         if(desc.indexOf('[TM]') != -1) return 102;
         if(desc.indexOf('[Caltrans]') != -1) return 103;
         if(desc.indexOf('[TfL Open Data]') != -1) return 104;
         if(provider.indexOf('London TFL Closures') != -1) return 104;
      }
   }
   if(markerType == "ur")
   {
      return uroCheckCommentsForTag(idSrc, customText);
   }

   return -1;
}

function uroFormatRestriction(restObj)
{
   var retval = '<tr>';
   retval += '<td style="text-align:center;">';
   if((restObj._days & 1) == 1) retval += 'S';
   else retval += '-';
   retval += '</td><td style="text-align:center;">';
   if((restObj._days & 2) == 2) retval += 'M';
   else retval += '-';
   retval += '</td><td style="text-align:center;">';
   if((restObj._days & 4) == 4) retval += 'T';
   else retval += '-';
   retval += '</td><td style="text-align:center;">';
   if((restObj._days & 8) == 8) retval += 'W';
   else retval += '-';
   retval += '</td><td style="text-align:center;">';
   if((restObj._days & 16) == 16) retval += 'T';
   else retval += '-';
   retval += '</td><td style="text-align:center;">';
   if((restObj._days & 32) == 32) retval += 'F';
   else retval += '-';
   retval += '</td><td style="text-align:center;">';
   if((restObj._days & 64) == 64) retval += 'S';
   else retval += '-';

   retval += '</td><td>';

   if(restObj._fromDate === null) retval += 'All dates';
   else retval += restObj._fromDate+' to '+restObj._toDate;

   retval += '</td><td>';

   if(restObj._allDay === true) retval += 'All day';
   else retval += restObj._fromTime+' to '+restObj._toTime;

   retval += '</td><td>';

   if(restObj.allVehicleTypes == restObj._vehicleTypes) retval += 'All vehicles';
   else retval += 'Some vehicles';

   retval += '</td><td>';

   if(restObj._description !== null)
   {
      var desc = restObj._description.replace(/<\/?[^>]+(>|$)/g, "");
      desc = uroClickify(desc);
      retval += desc;
   }

   retval += '</td></tr>';

   return retval;
}

function uroHidePopup()
{
   if(uroPopupShown)
   {  
      uroDiv.style.visibility = 'hidden';
      uroPopupShown = false;
      uroPopupTimer = -2;
      uroShownFID = -1;
   }
   uroPopupSuppressed = false;
}
function uroSuppressPopup()
{
   uroDiv.style.visibility = 'hidden';
   window.getSelection().removeAllRanges();
   uroPopupSuppressed = true;
}

function uroRecentreSessionOnUR()
{
   W.map.updateRequestLayer.markers[uroShownFID].icon.imageDiv.click();
   W.map.moveTo(W.map.updateRequestLayer.markers[uroShownFID].lonlat, 5);
   uroHidePopup();
   return false;
}
function uroRecentreSessionOnMP()
{
   W.map.problemLayer.markers[uroShownFID].icon.imageDiv.click();
   W.map.moveTo(W.map.problemLayer.markers[uroShownFID].lonlat, 5);
   uroHidePopup();
   return false;
}
function uroRecentreSessionOnPUR()
{
   W.map.placeUpdatesLayer.markers[uroShownFID].icon.imageDiv.click();
   W.map.moveTo(W.map.placeUpdatesLayer.markers[uroShownFID].lonlat, 5);
   uroHidePopup();
   return false;
}
function uroRecentreSessionOnVenueNavPoint()
{
   W.map.moveTo(uroGetVenueNavPoint(uroShownFID), 5);
   uroHidePopup();
   return false;
}

function uroGetDateTimeString(ts)
{
   var tDateObj = new Date(ts);
   var dateLocale;
   var timeLocale;
   if(uroGetCBChecked('_cbDateFmtDDMMYY')) dateLocale = 'en-gb';
   if(uroGetCBChecked('_cbDateFmtMMDDYY')) dateLocale = 'en-us';
   if(uroGetCBChecked('_cbDateFmtYYMMDD')) dateLocale = 'ja';
   if(uroGetCBChecked('_cbTimeFmt24H')) timeLocale = 'en-gb';
   if(uroGetCBChecked('_cbTimeFmt12H')) timeLocale = 'en-us';
   return tDateObj.toLocaleDateString(dateLocale) + ' ' + tDateObj.toLocaleTimeString(timeLocale);
}
function uroParsePxString(pxString)
{
   return parseInt(pxString.split("px")[0]);
}

function uroStackListObj(fid,x,y)
{
   this.fid = fid;
   this.x = uroTypeCast(x);
   this.y = uroTypeCast(y);
}
function uroRestackMarkers()
{
   if(uroStackList.length === 0) return;
   var markerCollection = null;
   if(uroStackType == 1) markerCollection = W.map.updateRequestLayer.markers;
   else if(uroStackType == 2) markerCollection = W.map.problemLayer.markers;
   else if(uroStackType == 3) markerCollection = W.map.placeUpdatesLayer.markers;

   if(markerCollection !== null)
   {
      uroAddLog('restacking markers...');
      // strip off the .realX/realY attributes from any UR object we've previously added it to, to allow
      // the native recentering to work again...
      for(var marker in markerCollection)
      {
         if(markerCollection.hasOwnProperty(marker))
         {
            var testMarkerObj = markerCollection[marker];
            if(testMarkerObj.model.attributes.geometry.realX != null)
            {
               testMarkerObj.model.attributes.geometry.x = testMarkerObj.model.attributes.geometry.realX;
               testMarkerObj.model.attributes.geometry.y = testMarkerObj.model.attributes.geometry.realY;
               delete(testMarkerObj.model.attributes.geometry.realX);
               delete(testMarkerObj.model.attributes.geometry.realY);
            }
         }
      }
      // now restack any markers that were repositioned...
      for(var idx=0; idx<uroStackList.length; idx++)
      {
         var orig_x = uroStackList[idx].x + 'px';
         var orig_y = uroStackList[idx].y + 'px';
         var fid = uroStackList[idx].fid;

         if(markerCollection[fid] != null)
         {
            markerCollection[fid].icon.imageDiv.style.left = orig_x;
            markerCollection[fid].icon.imageDiv.style.top = orig_y;
         }
      }
      uroStackList = [];
      uroUnstackedMasterID = null;
      uroStackType = null;
   }
}
function uroIsIDAlreadyUnstacked(idSrc)
{
   if(uroStackList.length === 0) return false;
   for(var idx=0; idx<uroStackList.length; idx++)
   {
      if(uroStackList[idx].fid == idSrc) return true;
   }
   return false;
}
function uroCheckStacking(stackType, masterID, unstackedX, unstackedY)
{
   if(uroIsIDAlreadyUnstacked(masterID) === true) return;
   if(uroStackType !== null) return;
   if(uroPopupDwellTimer > 0) return;

   uroAddLog('checking for marker stack, masterID: '+masterID+', stackType: '+stackType);
   var stackList = [];
   stackList.push(masterID);
   var threshSquared = uroGetElmValue('_inputUnstackSensitivity');
   threshSquared *= threshSquared;

   var markerCollection = null;
   var marker;
   
   if(stackType == 1) markerCollection = W.map.updateRequestLayer.markers;
   else if(stackType == 2) markerCollection = W.map.problemLayer.markers;
   else if(stackType == 3) markerCollection = W.map.placeUpdatesLayer.markers;

   var offset = 1000000000;
   if(markerCollection !== null)
   {
      for(marker in markerCollection)
      {
         if(markerCollection.hasOwnProperty(marker))
         {
            var testMarkerObj = markerCollection[marker];
            var includeInStack = (testMarkerObj.icon.imageDiv.style.visibility != 'hidden');
            var suppressClosed = (testMarkerObj.icon.imageDiv.classList.contains("recently-closed") & (W.map.updateRequestLayer.showHidden === false));

            // if multiple markers are stacked exactly on top of one another, WME will always open up the one which it would have rendered on the
            // top of the stack in the absence of any URO+ filtering, regardless of which UR pin actually receives the click event.  To prevent
            // this, we give each pin in the stack a unique set of false coordinates, storing the original coordinates in newly created
            // properties so they can be restored later on
            //
            // originally this fix changed the x coordinate for each UR in the stack to be a unique value that ought to have been well out of the range
            // of any real coordinate and therefore unable to clash with any UR marker coordinates that weren't in the current stack.  However it now
            // appears this could then cause WME to think a completely different UR was being opened - possibly as a result of some change in coordinate
            // handling allowing out of range values to be wrapped around back into the normal range?  As a workaround for this new WME behaviour, both the
            // x and y coordinates are now set to valid values somewhere in the North Atlantic Ocean - the likelihood of there being any real URs in this
            // area is so vanishingly small as to be not worth worrying about...
            
            
            if(testMarkerObj.model.attributes.geometry.realX === undefined)
            {
               testMarkerObj.model.attributes.geometry.realX = testMarkerObj.model.attributes.geometry.x;
               testMarkerObj.model.attributes.geometry.x += offset;
               testMarkerObj.model.attributes.geometry.realY = testMarkerObj.model.attributes.geometry.y;
               testMarkerObj.model.attributes.geometry.y += offset;
               offset += 1000;
            }
            

            if((includeInStack) && (!suppressClosed))
            {
               if(testMarkerObj.id != masterID)
               {
                  var xdiff = unstackedX - uroParsePxString(markerCollection[testMarkerObj.id].icon.imageDiv.style.left);
                  var ydiff = unstackedY - uroParsePxString(markerCollection[testMarkerObj.id].icon.imageDiv.style.top);
                  var distSquared = ((xdiff * xdiff) + (ydiff * ydiff));
                  if(distSquared < threshSquared)
                  {
                     stackList.push(testMarkerObj.id);
                  }
               }
            }
         }
      }
   }

   // as it's the fiddling with .geometry.x which seems to inhibit the autocentering behaviour when a UR/MP marker is clicked, we need to
   // allow this to occur even if unstacking isn't required at this zoom level.  To then reenable recentering when clicking on the crosshairs
   // or feed entry, we need to reinstate the correct .x value once the marker is no longer being highlighted, which means we pretty much need
   // to do all of the unstacking *except* for actually unstacking the stack and hiding the other markers...
   var inhibitUnstacking = (W.map.getZoom() < uroGetElmValue('_inputUnstackZoomLevel'));
   // also inhibit unstacking if there's only a single marker in the list - this will be true if we're highlighting an isolated marker that
   // doesn't need to be unstacked, and where we're only using the .geometry.x fiddle to prevent autocentering...
   inhibitUnstacking |= (stackList.length == 1);
 
   uroStackType = stackType;
   
   if(stackList.length > 0)
   {
      if(inhibitUnstacking) uroAddLog('single marker highlighted, adjusting geometry properties to prevent recentering...');
      else uroAddLog('markers are stacked!');
      if(uroUnstackedMasterID != masterID)
      {
         uroAddLog('unstacked ID mismatch, relocating markers...');
         uroRestackMarkers();
         uroUnstackedMasterID = masterID;
         uroStackList = [];

         // push the highlighted marker onto the stacklist so uroIsIDAlreadyUnstacked() will return true
         uroStackList.push(new uroStackListObj(masterID,unstackedX,unstackedY));

         for(var shoveIdx=0; shoveIdx < stackList.length; shoveIdx++)
         {
            var fid = stackList[shoveIdx];
            var x = uroParsePxString(markerCollection[fid].icon.imageDiv.style.left);
            var y = uroParsePxString(markerCollection[fid].icon.imageDiv.style.top);
            // store the unstacked marker positions so they can be reinstated later
            uroStackList.push(new uroStackListObj(fid,x,y));
            if(!inhibitUnstacking)
            {
               markerCollection[fid].icon.imageDiv.style.left = unstackedX + 'px';
               markerCollection[fid].icon.imageDiv.style.top = unstackedY + 'px';
               unstackedX += 10;
               unstackedY -= 30;               
            }
         }

   
         if(!inhibitUnstacking)
         {
            // hide other markers to prevent confusion with the unstacked markers
            for(marker in markerCollection)
            {
               if(markerCollection.hasOwnProperty(marker))
               {
                  var toHideID = markerCollection[marker].id;
                  if(uroIsIDAlreadyUnstacked(toHideID) === false)
                  {
                     markerCollection[toHideID].icon.imageDiv.style.visibility = 'hidden';
                  }
               }
            }
         }
      }
   }
   else
   {
      uroRestackMarkers();
   }
}

function uroGetVenueNavPoint(uroFID)
{
   for(var vObj in W.model.venues.objects)
   {
      if(W.model.venues.objects.hasOwnProperty(vObj))
      {
         if(uroFID == vObj)
         {
            return W.model.venues.objects[vObj].getNavigationPoint().point.toLonLat();
         }
      }
   }
   // just in case... return a safe value if the requested venue object wasn't found
   return W.map.getCenter();
}

function uroOpenNewTab()
{
   // flush the current settings into localStorage before the new tab opens, so that when its instance of
   // URO+ fires up it'll have the same settings as this one
   uroSaveSettings();
   return true;
}

function uroEditTBR()
{
   if(uroTBRObj === null)
   {
      return;
   }
   uroTBRObj.getElementsByClassName('waze-icon-clock')[0].click();
   return false;
}

function uroKillCentering()
{
   return W.map.getExtent();
}
function uroRestoreCentering()
{
   if(uroAutoCentreDisabledOn.length > 0)
   {
      if(uroAutoCentreDisabledOn[0] == 'PUR')
      {
         if(W.map.placeUpdatesLayer.markers[uroAutoCentreDisabledOn[1]] != null)
         {
            W.map.placeUpdatesLayer.markers[uroAutoCentreDisabledOn[1]].model.geometry.getBounds = W.map.placeUpdatesLayer.markers[uroAutoCentreDisabledOn[1]].model.geometry.origGetBounds;
         }
      }
      else if(uroAutoCentreDisabledOn[0] == 'MP')
      {
         if(W.map.problemLayer.markers[uroAutoCentreDisabledOn[1]] != null)
         {
            W.map.problemLayer.markers[uroAutoCentreDisabledOn[1]].model.getDisconnectBounds = W.map.problemLayer.markers[uroAutoCentreDisabledOn[1]].model.origGetDisconnectBounds;         
         }
      }
      uroAutoCentreDisabledOn = [];
   }   
}

function uroAddClosureRowToTable(rcObj)
{
   var result = '';

   if(rcObj.active === true)
   {
      result += '<tr>';
   }
   else
   {
      result += '<tr bgcolor="#C0C0C0">';
   }

   var startDate = rcObj.startDate;
   var endDate = "unknown";
   if(rcObj.endDate !== null)
   {
      endDate = rcObj.endDate;
   }
   var provider = "---";
   if(rcObj.provider !== null)
   {
      provider = rcObj.provider;
   }
   else if(rcObj.createdBy !== null)
   {
      provider = uroGetUserNameAndRank(rcObj.createdBy);
   }
   var reason = "---";
   if(rcObj.reason !== null)
   {
      reason = rcObj.reason;
   }
   var mte = "---";
   if(rcObj.eventId !== null)
   {
      try
      {
         mte = W.model.majorTrafficEvents.objects[rcObj.eventId].attributes.names[0].value;
      }
      catch(err)
      {
      }
   }
   
   result += '<td>' + startDate + ' to ' + endDate + '</td>';
   result += '<td>' + provider + '</td>';
   result += '<td>' + reason + '</td>';
   result += '<td>' + mte + '</td>';
   result += '</td></tr>';
   return result;
}


function uroGetAddress(streetID, houseNumber, formatForSegmentPopup)
{
   var result = '';
   if((houseNumber !== undefined) && (houseNumber !== null))
   {
      result += houseNumber + ' ';
   }

   if(streetID != null)
   {
      var streetName = I18n.lookup('edit.address.no_street');
      var doesStreetIDExist = true;
      if(W.model.streets.objects[streetID] === undefined)
      {
         streetName = 'non-existent streetID';
         doesStreetIDExist = false;
      }
      else
      {
         if((streetName !== null) && (W.model.streets.objects[streetID].isEmpty === false))
         {
            streetName = W.model.streets.objects[streetID].name;
         }
      }
      if(formatForSegmentPopup === true)
      {
         result += '<b>'+streetName+'</b><br>';         
      }
      else
      {
         result += streetName + ', ';
      }
      
      if(doesStreetIDExist === true)
      {
         var cityName = I18n.lookup('edit.address.no_city');
         var doesCityIDExist = true;
         var cityID = W.model.streets.objects[streetID].cityID;
         if(W.model.cities.objects[cityID] === undefined)
         {
            cityName = 'non-existent cityID';
            doesCityIDExist = false;
         }
         else
         {
            if(W.model.cities.objects[cityID].attributes.name !== "")
            {
               cityName = W.model.cities.objects[cityID].attributes.name;
            }
         }
         result += cityName + ', ';
         
         if(doesCityIDExist === true)
         {
            var stateID = W.model.cities.objects[cityID].attributes.stateID;
            if(W.model.states.objects[stateID] === undefined)
            {
               result += 'non-existent stateID';
            }
            else
            {
               result += W.model.states.objects[stateID].name;
            }
         }
      }
   }
   result += '<br>';
   
   return result;
}


function uroNewLookHighlightedItemsCheck(e)
{
   var result = '';
   var rw;
   var rh;
   var objHasIgnoreLink = false;
   var objHasDeleteLink = false;
   var objHasAddWatchLink = false;
   var objHasRemoveWatchLink = false;
   var objHasUpdateWatchLink = false;
   var objHasRecentreSessionLink = false;
   var objHasOpenInNewTabLink = false;
   var objHasCloneLink = false;
   var isVenue = false;
   var isMapComment = false;
   var newPopupType = null;
   var markerObj;
   var markerPos;
   var markerImg;
   var ureq = null;
   var idx;
   var hovered = false;
   var targetTab = '';
   var unstackedX;
   var unstackedY;
   var ureqID = null;
   var isUR = false;
   var isProblem = false;
   var isTurnProb = false;
   var isPlaceUpdate = false;
   var mouseX;
   var mouseY;
   var uroDaysResolved;
   var renderIntent;
   
   // function preamble...
   {
      if(uroMTEMode) return;
      if(!uroInitialised) return;
      
      if(e == 'dwellTimeout')
      {
      }
      else
      {
         if((uroMouseIsDown) && (e.buttons === 0))
         {
            uroAddLog('trapped erroneous mousedown state');
            uroMouseIsDown = false;
         }
      }
      if(uroMouseIsDown)
      {
         return;
      }

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

      if(W.map.updateRequestLayer === null)
      {
         if(uroNullURLayer === false)
         {
            uroAddLog('caught null UR layer');
            uroNullURLayer = true;
         }
         return;
      }
      uroNullURLayer = false;

      if(W.map.problemLayer === null)
      {
         if(uroNullProblemLayer === false)
         {
            uroAddLog('caught null problem layer');
            uroNullProblemLayer = true;
         }
         return;
      }
      uroNullProblemLayer = false;

      if(uroGetCBChecked('_cbMasterEnable') === false)
      {
         return;
      }

      if(e == 'dwellTimeout')
      {
         mouseX = uroPrevMouseX;
         mouseY = uroPrevMouseY;
      }
      else
      {
         mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
         mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top;

         var maxJitter = uroGetElmValue('_inputMaxJitter');
         if((Math.abs(uroPrevMouseX - mouseX) > maxJitter) || (Math.abs(uroPrevMouseY - mouseY) > maxJitter))
         {
            uroPopupDwellTimer = uroGetElmValue('_inputPopupDwellTimeout');
         }
         uroPrevMouseX = mouseX;
         uroPrevMouseY = mouseY;
      }
   }

   var popupXOffset = uroParsePxString(window.getComputedStyle(document.getElementById('sidebar')).getPropertyValue("width"));
   var popupYOffset = $(document.getElementById("WazeMap")).offset().top - 80;
   var uroPopupX = mouseX + popupXOffset + 10;
   var uroPopupY = mouseY + popupYOffset - 10;   
   
   // popup for segment restrictions
   if((uroMousedOverMarkerType === null) && (uroGetCBChecked('_cbInhibitSegPopup') === false))
   {
      for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
      {
         if(W.map.segmentLayer.features[slIdx].renderIntent == 'highlight')
         {
            if(W.map.getExtent().intersectsBounds(W.map.segmentLayer.features[slIdx].geometry.getBounds()))
            {            
               var doPopUp = false;
               var segObj;
               var restObj;
               
               if(W.map.segmentLayer.features[slIdx].fid === null) segObj = W.map.segmentLayer.features[slIdx].model;
               else segObj = W.map.segmentLayer.features[slIdx];

               // generic segment data
               if(uroGetCBChecked('_cbInhibitSegGenericPopup') === false)
               {
                  doPopUp = true;
                  var streetID = segObj.attributes.primaryStreetID;
                  
                  uroAddLog('building popup for segment '+streetID);
                  
                  result += uroGetAddress(streetID, null, true);
                  
                  result += '<b>ID: </b>'+segObj.attributes.id+'<br>';
                  var fwdSpeed = segObj.attributes.fwdMaxSpeed;
                  var revSpeed = segObj.attributes.revMaxSpeed;
                  var fwdUnverified = segObj.attributes.fwdMaxSpeedUnverified;
                  var revUnverified = segObj.attributes.revMaxSpeedUnverified;
                  var roadType = segObj.attributes.roadType;
                  var verifyLimits = true;
                  if((roadType === 17) || (roadType === 20))
                  {
                     verifyLimits = false;
                  }
                  if(segObj.attributes.fwdDirection)
                  {
                     result += '<b>A-B speed: </b>'+uroGetLocalisedSpeedString(fwdSpeed, verifyLimits);
                     if(fwdUnverified) result += ' (unverified)';
                     result += '<br>';
                  }
                  if(segObj.attributes.revDirection)
                  {
                     result += '<b>B-A speed: </b>'+uroGetLocalisedSpeedString(revSpeed, verifyLimits);
                     if(revUnverified) result += ' (unverified)';
                     result += '<br>';
                  }
                  if((segObj.attributes.fwdDirection) && (segObj.attributes.revDirection) && (fwdSpeed != revSpeed) && (!fwdUnverified) && (!revUnverified))
                  {
                     result += 'Two-way segment has different verified speed limits...<br>';
                  }
               }

               // segment restrictions
               result += '<table cellpadding=4 border=1">';
               if(segObj.attributes.fwdRestrictions.length > 0)
               {
                  doPopUp = true;
                  result += '<tr><td colspan=11><b>A-B restrictions:</b></td></tr>';
                  for(idx = 0; idx < segObj.attributes.fwdRestrictions.length; idx++)
                  {
                     restObj = segObj.attributes.fwdRestrictions[idx];
                     result += uroFormatRestriction(restObj);
                  }
               }

               if (segObj.attributes.revRestrictions.length > 0)
               {
                  doPopUp = true;
                  result += '<tr><td colspan=11><b>B-A restrictions:</b></td></tr>';
                  for(idx = 0; idx < segObj.attributes.revRestrictions.length; idx++)
                  {
                     restObj = segObj.attributes.revRestrictions[idx];
                     result += uroFormatRestriction(restObj);
                  }
               }
               result += '</table>';
               if(W.map.closuresMarkerLayer.getVisibility() === true)
               {
                  result += '<table cellpadding=4 border=1" width="100%">';
                  if(segObj.attributes.hasClosures === true)
                  {
                     var hasFwd = false;
                     var hasRev = false;
                     var rcObj;
                     var roadClosure;
                     
                     for(roadClosure in W.model.roadClosures.objects)
                     {
                        if(W.model.roadClosures.objects.hasOwnProperty(roadClosure))
                        {
                           rcObj = W.model.roadClosures.objects[roadClosure];
                           if(rcObj.segID == segObj.attributes.id)
                           {
                              if(rcObj.forward === true)
                              {
                                 if(hasFwd === false)
                                 {
                                    result += '<tr><td colspan=4><b>A-B closures:</b></td></tr>';
                                    hasFwd = true;
                                 }
                                 result += uroAddClosureRowToTable(rcObj);
                              }
                              else
                              {
                                 hasRev = true;
                              }
                           }
                        }
                     }
                     if(hasRev === true)
                     {
                        result += '<tr><td colspan=4><b>B-A closures:</b></td></tr>';
                        for(roadClosure in W.model.roadClosures.objects)
                        {
                           if(W.model.roadClosures.objects.hasOwnProperty(roadClosure))
                           {
                              rcObj = W.model.roadClosures.objects[roadClosure];
                              if(rcObj.segID == segObj.attributes.id)
                              {
                                 if(rcObj.forward === false)
                                 {
                                    result += uroAddClosureRowToTable(rcObj);
                                 }
                              }
                           }
                        }
                     }
                     if((hasFwd === true) || (hasRev === true))
                     {
                        doPopUp = true;
                     }
                  }
                  result += '</table>';
               }

               if(doPopUp === true)
               {
                  if(segObj.attributes.id === null) uroFID = segObj.id;
                  else uroFID = segObj.attributes.id;
                  newPopupType = 'segment_restriction';
               }

               break;
            }
            else
            {
               uroAddLog('segment '+uroFID+' has renderIntent==highlight but is offscreen... blocking popup');
            }            
         }
      }
   }
   // popup for restricted turns
   if((uroMousedOverMarkerType === null) && (newPopupType === null) && (uroGetCBChecked('_cbInhibitTurnsPopup') === false))
   {
      if(W.map.layers[uroTurnsLayerIdx].name !== 'Node Connections')
      {
         uroWazeBits();
      }
      if(uroTurnsLayerIdx !== null)
      {      
         var turnMarkerCount = W.map.layers[uroTurnsLayerIdx].markers.length;
         if(turnMarkerCount > 0)
         {
            for(idx=0; idx<turnMarkerCount; idx++)
            {
               markerObj = W.map.layers[uroTurnsLayerIdx].markers[idx];
               var arrowElm = markerObj.icon.imageDiv.childNodes[0];
               markerImg = window.getComputedStyle(arrowElm).getPropertyValue("background-image");
               markerPos = window.getComputedStyle(arrowElm).getPropertyValue("background-position");

               hovered = false;

               if(markerImg.indexOf('turns96765f551688fd5082b619129499bbb3.png') != -1)
               {
                  if(markerPos == '-72px 0px')
                  {
                     hovered = true;
                  }
               }
               if(hovered === true)
               {
                  uroAddLog('hover over restricted turn marker');
                  uroTBRObj = arrowElm.childNodes[0];
                  var trObj = ($(arrowElm).data('model'));
                  
                  var Vertex = new require("Waze/Model/Graph/Vertex");
                  var turnGraph = W.model.getTurnGraph().getTurn(Vertex.forwardOf(trObj.fromSeg.attributes.id),Vertex.reverseOf(trObj.toSeg.attributes.id));
                  var resObj = turnGraph._turnData._restrictions;
                  
                  uroAddLog('building popup for turn restriction');

                  result += '<label id="_editTBR">Click to edit</label><br>';
                  result += '<table cellpadding=4 border=1">';
                  for(var resIdx=0; resIdx < resObj.length; resIdx++)
                  {
                     result += uroFormatRestriction(resObj[resIdx]);
                  }
                  result += '</table>';             
                  uroFID = markerObj.icon.imageDiv._eventCacheID;
                  newPopupType = 'turn_restriction';
                  
                  break;
               }
            }
         }
      }
   }

   // popup for landmarks
   if((uroMousedOverMarkerType === null) && (newPopupType === null) && (uroGetCBChecked('_cbInhibitLandmarkPopup') === false))
   {
      uroPlaceSelected = false;
      
      var venueObj = null;
      renderIntent = null;
      var navpointPos=new OpenLayers.LonLat();
      
      for(var llFeatureIdx=0; llFeatureIdx < W.map.landmarkLayer.features.length; llFeatureIdx++)
      {
         if(W.map.landmarkLayer.features[llFeatureIdx] !== undefined)
         {
            renderIntent = W.map.landmarkLayer.features[llFeatureIdx].renderIntent;
            if(renderIntent == 'highlight')
            {
               if(W.map.getExtent().intersectsBounds(W.map.landmarkLayer.features[llFeatureIdx].geometry.getBounds()))
               {
                  if(W.map.landmarkLayer.features[llFeatureIdx].fid === null) venueObj = W.map.landmarkLayer.features[llFeatureIdx].model;
                  else venueObj = W.map.landmarkLayer.features[llFeatureIdx];
                  if(newPopupType === null)
                  {
                     if(venueObj.attributes.id === null) uroFID = venueObj.id;
                     else uroFID = venueObj.attributes.id;
                     
                     uroAddLog('building popup for place '+uroFID);
                     
                     navpointPos = uroGetVenueNavPoint(uroFID);
                     navpointPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
                     result += '<b>';
                     if(venueObj.attributes.name === '') 
                     {
                        if(venueObj.attributes.residential === true) result += '<i>Residential</i>';
                        else result += '<i>Unnamed</i>';
                     }
                     else result += venueObj.attributes.name;
                     if(venueObj.attributes.externalProviderIDs.length > 0)
                     {
                        result += ' <i>(linked)</i>';
                     }
                     if(venueObj.attributes.adLocked)
                     {
                        result += ' <i>(AdLocked)</i>';
                     }
                     result += '</b><br>';
                     result += uroGetAddress(venueObj.attributes.streetID, venueObj.attributes.houseNumber, false);                  
                     result += '<ul>';
                     for(idx = 0; idx < venueObj.attributes.categories.length; idx++)
                     {
                        result += '<li>' + I18n.lookup("venues.categories." + venueObj.attributes.categories[idx]);
                     }
                     result += '</ul>';
                     if(venueObj.attributes.residential === true)
                     {
                        if(venueObj.geometry.CLASS_NAME == 'OpenLayers.Geometry.Point')
                        {
                           result += '<a href="#" id="_cloneRP">Clone place</a>';
                           objHasCloneLink = true;
                        }
                     }
                     var npLink = document.location.href;
                     ////var npLayers = '&layers='+...
                     var npLayers = '';
                     npLink = npLink.substr(0,npLink.indexOf('?zoom'));
                     npLink += '?zoom=5&lat='+navpointPos.lat+'&lon='+navpointPos.lon+npLayers;

                     targetTab = "_uroTab_" + Math.round(Math.random()*1000000);
                     result += '<hr>Jump to nav point: <a href="'+npLink+'" id="_openInNewTab" target="'+targetTab+'">in new tab</a> - ';
                     objHasOpenInNewTabLink = true;
                     result += '<a href="#" id="_recentreSession">in this tab</a>';
                     objHasRecentreSessionLink = true;

                     newPopupType = 'venue';
                     isVenue = true;
                     break;
                  }
                  else
                  {
                     var otherID;
                     if(venueObj.attributes.id === null) otherID = venueObj.id;
                     else otherID = venueObj.attributes.id;
                     uroAddLog('venue '+otherID+' is also highlighted');
                  }
               }
               else
               {
                  uroAddLog('landmark '+uroFID+' has renderIntent==highlight but is offscreen... blocking popup');
               }               
            }
            else if((renderIntent == 'select') || (renderIntent == 'highlightselected'))
            {
               uroPlaceSelected = true;
            }
         }
      }
   }
   
   // popup for map comments
   if((uroMousedOverMarkerType === null) && (newPopupType === null) && (uroGetCBChecked('_cbInhibitMapCommentPopup') === false))
   {
      if (W.map.layers[uroMCLayerIdx].featureType !== 'mapComment')
      {
         uroWazeBits();
      }
      if(uroMCLayerIdx !== null)
      {
         uroMCSelected = false;
         
         var mcObj = null;
         renderIntent = null;
         
         for(var mcFeatureIdx=0; mcFeatureIdx < W.map.layers[uroMCLayerIdx].features.length; mcFeatureIdx++)
         {
            renderIntent = W.map.layers[uroMCLayerIdx].features[mcFeatureIdx].renderIntent;
            if(renderIntent == 'highlight')
            {
               if(W.map.getExtent().intersectsBounds(W.map.layers[uroMCLayerIdx].features[mcFeatureIdx].geometry.getBounds()))
               {
                  mcObj = W.map.layers[uroMCLayerIdx].features[mcFeatureIdx].model;
                  if(newPopupType === null)
                  {
                     uroFID = mcObj.attributes.id;
                     uroAddLog('building popup for map comment '+uroFID);
                     
                     result += '<b>';
                     if(mcObj.attributes.subject === '') 
                     {
                        result += '<i>No subject</i>';
                     }
                     else result += mcObj.attributes.subject;
                     result += '</b><br>';
                     if(mcObj.attributes.body !== '')
                     {
                        var mcDesc = mcObj.attributes.body.replace(/<\/?[^>]+(>|$)/g, "");
                        if(mcDesc != "null")
                        {
                           mcDesc = uroClickify(mcDesc);
                           result += mcDesc + '<br>';
                        }
                     }
                     
                     
                     var mcDaysOld = uroGetMCAge(mcObj,0,false);
                     var mcSubmittedTS = uroGetMCAge(mcObj,0,true);
                     if(mcSubmittedTS != -1)
                     {
                        mcSubmittedTS = uroGetDateTimeString(mcSubmittedTS);
                     }
                     if(mcDaysOld != -1)
                     {
                        result += '<i>Submitted ' + uroParseDaysAgo(mcDaysOld) + ' ';
                        if(mcSubmittedTS != -1) result += '(' + mcSubmittedTS + ') ';
                        if(mcObj.attributes.createdBy != null)
                        {
                           result += ' by '+uroGetUserNameAndRank(mcObj.attributes.createdBy);
                        }
                        result += '</i><br>';
                     }
                     mcDaysOld = uroGetMCAge(mcObj,1,false);
                     mcSubmittedTS = uroGetMCAge(mcObj,1,true);
                     if(mcSubmittedTS != -1)
                     {
                        mcSubmittedTS = uroGetDateTimeString(mcSubmittedTS);
                     }
                     if(mcDaysOld != -1)
                     {
                        result += '<i>Updated ' + uroParseDaysAgo(mcDaysOld) + ' ';
                        if(mcSubmittedTS != -1) result += '(' + mcSubmittedTS + ') ';
                        if(mcObj.attributes.createdBy != null)
                        {
                           result += ' by '+uroGetUserNameAndRank(mcObj.attributes.updatedBy);
                        }
                        result += '</i><br>';
                     }
                     
                     var mcHasMyComments = false;
                     var mcNComments = mcObj.attributes.conversation.length;
                     if(mcNComments > 0)
                     {
                        for(var i=0; i<mcNComments; i++)
                        {
                           if(mcObj.attributes.conversation[i].userID == uroUserID)
                           {
                              mcHasMyComments = true;
                              break;
                           }
                        }
                     }
                     result += '<br>' + mcNComments +' comment';
                     if(mcNComments != 1) result += 's';
                     if((mcHasMyComments === false) && (mcNComments > 0)) result += ' (none by me)';

                     newPopupType = 'map_comment';
                     isMapComment = true;
                     break;
                  }
                  else
                  {
                     var mcOtherID = mcObj.attributes.id;
                     uroAddLog('map comment '+mcOtherID+' is also highlighted');
                  }
               }
               else
               {
                  uroAddLog('map comment '+uroFID+' has renderIntent==highlight but is offscreen... blocking popup');
               }               
            }
            else if((renderIntent == 'select') || (renderIntent == 'highlightselected'))
            {
               uroMCSelected = true;
            }
         }
      }
   }   

   // look for URs, place updates and problems
   if(newPopupType === null)
   {
      if((uroMousedOverMarkerType == 'ur') && (newPopupType === null) && (uroGetCBChecked('_cbInhibitURPopup') === false))
      {
         hovered = true;
         isUR = true;
         newPopupType = 'ur';
         ureq = W.model.mapUpdateRequests.objects[uroMousedOverMarkerID];

         unstackedX = uroParsePxString(W.map.updateRequestLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.left);
         unstackedY = uroParsePxString(W.map.updateRequestLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.top);

         // override popup base position
         uroPopupX = unstackedX + popupXOffset + 6;
         uroPopupY = unstackedY + popupYOffset + 66;
         uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left);
         uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top);

         // check for stacking...
         if(uroShownFID != uroMousedOverMarkerID)
         {
            uroCheckStacking(1,uroMousedOverMarkerID, unstackedX, unstackedY);
         }
         uroFID = uroMousedOverMarkerID;
         
         uroAddLog('building popup for UR '+uroMousedOverMarkerID);
         result = '<b>Update Request ('+uroMousedOverMarkerID+'): ' + I18n.lookup("update_requests.types." + ureq.attributes.type) + '</b><br>';
         if(ureq.attributes.description !== null)
         {
            var desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, "");
            if(desc != "null")
            {
               desc = uroClickify(desc);
               result += desc + '<br>';
            }
         }
         var uroDaysOld = uroGetURAge(ureq,0,false);
         var uroSubmittedTS = uroGetURAge(ureq,0,true);
         if(uroSubmittedTS != -1)
         {
            uroSubmittedTS = uroGetDateTimeString(uroSubmittedTS);
         }
         if(uroDaysOld != -1)
         {
            result += '<i>Submitted ' + uroParseDaysAgo(uroDaysOld) + ' ';
            if(uroSubmittedTS != -1) result += '(' + uroSubmittedTS + ') ';
            if(ureq.attributes.guestUserName != null)
            {
               result += 'via Livemap';
               if(ureq.attributes.guestUserName !== '')
               {
                  result += ' by '+ureq.attributes.guestUserName.replace(/<\/?[^>]+(>|$)/g, "");
               }
            }
            result += '</i>';
         }
         if(ureq.attributes.resolvedOn !== null)
         {
            uroDaysResolved = uroGetURAge(ureq,1,false);
            var uroResolvedTS = uroGetURAge(ureq,1,true);
            if(uroResolvedTS != -1)
            {
               uroResolvedTS = uroGetDateTimeString(uroResolvedTS);
            }

            if(uroDaysResolved != -1)
            {
               result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
               if(uroResolvedTS != -1) result += '(' + uroResolvedTS + ')</i>';

               result += '<br><i>Marked as ';
               if(ureq.attributes.resolution === 0) result += 'solved';
               else if(ureq.attributes.resolution == 1) result += 'not identified';
               else result += 'unknown';
               if(ureq.attributes.resolvedBy !== null)
               {
                  result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
               }
               result += '</i>';
            }
         }
         
         if(W.model.updateRequestSessions.objects[uroMousedOverMarkerID] != null)
         {
            var hasMyComments = uroURHasMyComments(uroMousedOverMarkerID);
            var nComments = W.model.updateRequestSessions.objects[uroMousedOverMarkerID].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(W.model.updateRequestSessions.objects[uroMousedOverMarkerID].comments[nComments-1]);
               if(commentDaysOld != -1)
               {
                  result += ', last update '+uroParseDaysAgo(commentDaysOld);
               }
            }
         }         
      }

      if((uroMousedOverMarkerType == 'pur') && (newPopupType === null) && (uroGetCBChecked('_cbInhibitPUPopup') === false))
      {
         hovered = true;
         isPlaceUpdate = true;
         newPopupType = 'pur';
         ureq = W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model;
         
         unstackedX = uroParsePxString(W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.left);
         unstackedY = uroParsePxString(W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.top);

         // override popup base position
         uroPopupX = unstackedX + popupXOffset + 6;
         uroPopupY = unstackedY + popupYOffset + 66;
         uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left);
         uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top);
         
         if(uroShownFID != uroMousedOverMarkerID)
         {
            // check for stacking...
            uroCheckStacking(3,uroMousedOverMarkerID, unstackedX, unstackedY);
         }
         uroFID = uroMousedOverMarkerID;
         
         // to inhibit auto-centering only when the PUR marker is clicked, we wait for the marker to get highlighted, then
         // make a copy of the original getBounds() function before replacing it with a call to W.map.getExtent().  Clicking
         // the marker causes a call to getBounds() which will then return the current map extent, and thus no change in the
         // map view will occur...
         uroRestoreCentering();
         W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model.geometry.origGetBounds = W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model.geometry.getBounds;
         W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model.geometry.getBounds = uroKillCentering;
         uroAutoCentreDisabledOn.push('PUR', uroMousedOverMarkerID);
         
         uroAddLog('building popup for placeUpdate '+uroMousedOverMarkerID);
         result = '<b>';
         if(ureq.attributes.name === '') result += 'Unnamed landmark';
         else result += ureq.attributes.name;
         result += '</b><br>';

         result += '<ul>';
         for(idx = 0; idx < ureq.attributes.categories.length; idx++)
         {
            result += '<li>' + I18n.lookup("venues.categories." + ureq.attributes.categories[idx]);
         }
         result += '</ul>';

         if(ureq.attributes.residential === true)
         {
            result += '<i>Residential</i>';
         }

         var daysOld = uroGetPURAge(ureq);
         if(daysOld != -1)
         {
            result += '<br><i>Submitted '+uroParseDaysAgo(daysOld)+'</i>';
         }
      }

      if((uroMousedOverMarkerType == 'mp') && (newPopupType === null) && (uroGetCBChecked('_cbInhibitMPPopup') === false))
      {
         hovered = true;
         isProblem = true;
         newPopupType = 'map_problem';
         ureq = W.model.problems.objects[uroMousedOverMarkerID];
         if(ureq === undefined)
         {
            if(uroDOMHasTurnProblems)
            {
               ureq = W.model.turnProblems.objects[uroMousedOverMarkerID];
               if(ureq != null) isTurnProb = true;
            }
         }
         
         unstackedX = uroParsePxString(W.map.problemLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.left);
         unstackedY = uroParsePxString(W.map.problemLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.top);

         // override popup base position
         uroPopupX = unstackedX + popupXOffset + 6;
         uroPopupY = unstackedY + popupYOffset + 66;
         uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left);
         uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top);

         // check for stacking...
         if(uroShownFID != uroMousedOverMarkerID)
         {
            uroCheckStacking(2,uroMousedOverMarkerID, unstackedX, unstackedY);
         }            
         uroFID = uroMousedOverMarkerID;
         // same method of disabling the on-click auto-centre behaviour as for PURs above...
         uroRestoreCentering();
         W.map.problemLayer.markers[uroMousedOverMarkerID].model.origGetDisconnectBounds = W.map.problemLayer.markers[uroMousedOverMarkerID].model.getDisconnectBounds;
         W.map.problemLayer.markers[uroMousedOverMarkerID].model.getDisconnectBounds = uroKillCentering;
         uroAutoCentreDisabledOn.push('MP', uroMousedOverMarkerID); 

         uroAddLog('building popup for problem '+uroMousedOverMarkerID);
         if(isTurnProb) result = '<b>Turn Problem ('+uroMousedOverMarkerID+'): ' + I18n.lookup("problems.types.turn.title");
         else
         {
            result = '<b>Map Problem ('+uroMousedOverMarkerID+'): ';

            var problemType = null;
            if(uroDOMHasTurnProblems)
            {
               problemType = ureq.attributes.problemType;
            }
            else
            {
               problemType = ureq.attributes.subType;
            }

            if(problemType == 300)
            {
               result += I18n.lookup("problems.panel.closure.title");
            }
            else
            {
               if(I18n.lookup("problems.types." + problemType) === undefined) result += 'Unknown problem type ('+problemType+')';
               else result += I18n.lookup("problems.types." + problemType + ".title");
            }
         }
         result += '</b><br>';
         if(ureq.attributes.description != null)
         {
            result += 'Description: ' + ureq.attributes.description + '<br>';
         }
         if(ureq.attributes.extraInfo != null)
         {
            result += 'ExtraInfo: ' + ureq.attributes.extraInfo + '<br>';
         }
         if(ureq.attributes.provider != null)
         {
            result += 'Provider: ' + ureq.attributes.provider + '<br>';
         }
         if(ureq.attributes.resolvedOn != null)
         {
            uroDaysResolved = uroGetURAge(ureq,1,false);
            if(uroDaysResolved != -1)
            {
               result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
               if(ureq.attributes.resolvedBy != null)
               {
                  result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
               }

               if((ureq.attributes.open === true) && (ureq.attributes.resolvedOn != null))
               {
                  result += '<br>Reopened by Waze';
               }
               result += '</i>';
            }
         }
         
      }

      if(hovered === false)
      {
         uroFID = -1;
         if(uroStackType !== null)
         {
            var tStackType = uroStackType;
            uroRestackMarkers();
            if(tStackType == 1) uroFilterURs();
            else if(tStackType == 2) uroFilterProblems();
            else if(tStackType == 3) uroFilterPlaces();
         }
      }
      else
      {
         // add "open new WME tab" link
         var urPos=new OpenLayers.LonLat();
         if(isPlaceUpdate)
         {
            urPos=ureq.geometry.bounds.centerLonLat.clone();
         }
         else
         {
            if(ureq.geometry.realX === undefined)
            {
               urPos.lon = ureq.geometry.x;
               urPos.lat = ureq.geometry.y;
            }
            else
            {
               urPos.lon = ureq.geometry.realX;
               urPos.lat = ureq.geometry.realY;
            }
         }
         urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
         var urLink = document.location.href;
         ////var urLayers = '&layers='+...
         var urLayers = '';
         urLink = urLink.substr(0,urLink.indexOf('?zoom'));
         urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers;

         if(isUR) urLink += '&mapUpdateRequest='+uroMousedOverMarkerID;
         else if(isTurnProb) urLink += '&showturn='+uroMousedOverMarkerID+'&endshow';
         else if(isProblem) urLink += '&mapProblem='+uroMousedOverMarkerID;
         else if(isPlaceUpdate) urLink += '&showpur='+uroMousedOverMarkerID+'&endshow';

         targetTab = "_uroTab_" + Math.round(Math.random()*1000000);
         result += '<hr><ul><li><a href="'+urLink+'" id="_openInNewTab" target="'+targetTab+'">Open in new tab</a> - ';
         objHasOpenInNewTabLink = true;
         result += '<a href="#" id="_recentreSession">centre in current tab</a>';
         objHasRecentreSessionLink = true;

         // add "open new livemap tab" link
         var lmLink = null;
         if(document.getElementById("livemap-link") != null)
         {
            uroAddLog('Livemap link in livemap-link id element');
            lmLink = document.getElementById("livemap-link").href;
         }
         else if(document.getElementsByClassName("livemap-link") != null)
         {
            uroAddLog('Livemap link in livemap-link class element');
            lmLink = document.getElementsByClassName("livemap-link")[0].href;
         }
         else
         {
            uroAddLog('Livemap link not found...');
         }
         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>';
         }
         if(!isPlaceUpdate)
         {
            // add "ignore for this session" link
            result += '<li><a href="#" id="_addtoignore">Hide for this session</a></ul>';
            objHasIgnoreLink = true;
         }
      }
   }
   
   if((newPopupType != 'map_problem') && (newPopupType != 'pur'))
   {
      uroRestoreCentering();
   }

   // look for cameras
   if((newPopupType === null) && (uroGetCBChecked('_cbInhibitCamPopup') === false))
   {
      for(var clFeature in W.map.camerasLayer._featureMap)
      {
         if(W.map.camerasLayer._featureMap[clFeature] !== undefined)
         {
            if(W.map.camerasLayer._featureMap[clFeature].renderIntent == 'highlight')
            {
               ureq = W.map.camerasLayer._featureMap[clFeature].model;
               ureqID = ureq.attributes.id;

               // test isSelected() so that we only do overview data on cameras that are being hovered over
               if(ureq.isSelected() === false)
               {
                  uroPopupY -= 20;
                  newPopupType = 'camera';
                  uroFID = ureqID;
                  uroAddLog('building popup for camera '+uroFID);
                  if(I18n.lookup("edit.camera.fields.type") === undefined)
                  {
                     result += '<b>Camera: ' + ureq.TYPES[ureq.attributes.type] + '</b><br>';
                  }
                  else
                  {
                     result += '<b>Camera: ' + I18n.lookup("edit.camera.fields.type." + ureq.attributes.type) + '</b><br>';
                  }
                  result += 'ID: '+uroFID+'<br>';
                  result += 'Created by ';
                  var userID;
                  if(W.model.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(W.model.users.get(ureq.attributes.updatedBy) != null)
                  {
                     userID = ureq.attributes.updatedBy;
                     var userName = W.model.users.objects[userID].userName;
                     var userLevel = W.model.users.objects[userID].rank + 1;
                     result += userName + ' (' + userLevel + ')';
                  }
                  else result += 'unknown';
                  result += ', ';
                  camAge = uroGetCameraAge(ureq,0);
                  if(camAge != -1)
                  {
                     result += uroParseDaysAgo(camAge);
                  }
                  else result += 'unknown days ago';
                  result += '<br>Speed data: ';
                  result += uroGetLocalisedSpeedString(ureq.attributes.speed, true);
                  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>';
               }
               break;
            }
         }
      }
   }

   if((newPopupType !== null) && (uroPopupDwellTimer === 0) && (uroPopupSuppressed === false))
   {
      if((uroFID != uroShownFID) || (newPopupType != uroShownPopupType))
      {
         if(uroFID != uroShownFID) uroAddLog('FID mismatch, show popup: '+uroFID+'/'+uroShownFID);
         else uroAddLog('Popup type mismatch: '+newPopupType+'/'+uroShownPopupType);
         uroShownFID = uroFID;
         uroShownPopupType = newPopupType;
         uroPopupShown = false;
      }
      if(uroPopupShown === false)
      {
         uroAddLog('display popup at '+uroPopupX+','+uroPopupY);
         uroPopupShown = true;
         uroDiv.style.height = "auto";
         uroDiv.style.width = "auto";         
         uroDiv.innerHTML = result;
        
         if((uroFID != -1) && (objHasIgnoreLink === true))
         {
            uroAddEventListener('_addtoignore','click', uroAddToIgnoreList, true);
         }
         if(objHasDeleteLink === true)
         {
            uroAddEventListener('_deleteobject','click', uroDeleteObject, true);
         }
         if(objHasRemoveWatchLink === true)
         {
            uroAddEventListener('_removefromwatchlist','click', uroRemoveCamFromWatchList, true);
         }
         if(objHasAddWatchLink === true)
         {
            uroAddEventListener('_addtowatchlist','click', uroAddCamToWatchList, true);
         }
         if(objHasUpdateWatchLink === true)
         {
            uroAddEventListener('_updatewatchlist','click', uroUpdateCamWatchList, true);
         }
         if(objHasOpenInNewTabLink === true)
         {
            uroAddEventListener('_openInNewTab','mouseup', uroOpenNewTab, true);
         }
         if(objHasRecentreSessionLink === true)
         {
            if(isUR) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnUR, true);
            else if((isProblem)||(isTurnProb)) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnMP, true);
            else if(isPlaceUpdate) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnPUR, true);
            else if(isVenue) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnVenueNavPoint, true);
         }
         if(objHasCloneLink === true)
         {
            uroAddEventListener('_cloneRP', 'click', uroCloneResidentialPlace, true);
         }
         
         if(newPopupType == 'turn_restriction')
         {
            uroAddEventListener('_editTBR','click', uroEditTBR, true);
         }

         // restrict the popup width to be no wider than just under half the window width to avoid it 
         // completely overlapping the marker it's associated with - by keeping it to just below half 
         // the window width we guarantee that it'll fit either to the left or the right of the marker
         // no matter how far across the screen the marker is located...         
         rw = parseInt(uroDiv.clientWidth);
         if(rw > (window.innerWidth * 0.45)) 
         {
            rw = (window.innerWidth * 0.45);
            uroDiv.style.width = rw+'px';
         }
         // get the div height after any adjustment of the width above, to account for whatever content
         // reflow may have occurred as a result of reducing the width...
         rh = parseInt(uroDiv.clientHeight);

         if((uroPopupX + rw) > window.innerWidth)
         {
            // where the popup would be off the right hand side of the screen, move it completely over to the
            // other side of the mouse pointer
            uroPopupX -= (rw + 20);
            if(uroPopupX < 0) uroPopupX = 0;
         }
         if((uroPopupY + rh) > window.innerHeight)
         {
            // where the popup would be off the bottom of the screen, shift it up just far enough to be
            // fully visible
            uroPopupY -= (((uroPopupY + rh) - window.innerHeight) + 30);
            if(uroPopupY < 0) uroPopupY = 0;
         }
         uroDiv.style.top = uroPopupY+'px';
         uroDiv.style.left = uroPopupX+'px';
         uroDiv.style.visibility = 'visible';
      }
      uroPopupTimer = -1;
   }
   else if((newPopupType === null) && (uroPopupDwellTimer !== 0) && (uroPopupShown === true))
   {
      uroHidePopup();
   }
   else
   {
      if((uroPopupTimer == -1) && (uroFID != uroShownFID))
      {
         uroPopupTimer = uroGetElmValue('_inputPopupEntryTimeout');
      }
   }  
}

function uroExclusiveCB()
{
   var cbChecked = uroGetCBChecked(this.id);

   if(cbChecked === true)
   {
      var pairedList = this.attributes.pairedWith.value.split(',');
      for(var i=0; i<pairedList.length; i++)
      {
         uroSetCBChecked(pairedList[i], false);
      }
   }
}

function uroGetAMs(e)
{
   if(uroMTEMode) return;
   if(!uroFilterPreamble) return;
   if(!uroInitialised) return;
   
   var amList = '';
   if(W.map.managedAreasLayer.getVisibility() === true)
   {
      var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
      var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top - document.getElementById('toolbar').clientHeight;
      var mousePixel = new OL.Pixel(mouseX, mouseY);
      var mousePoint = W.map.getLonLatFromPixel(mousePixel).toPoint();

      for(var amObj in W.model.managedAreas.objects)
      {
         if(W.model.managedAreas.objects[amObj].geometry.containsPoint(mousePoint))
         {
            if(amList !== '') amList += ', ';
            amList += uroGetUserNameAndRank(W.model.managedAreas.objects[amObj].userID);
         }
      }
      if(amList === '')
      {
         amList = 'none';
      }
      amList = "<b>Area Managers:</b> "+amList;
   }
   document.getElementById("uroAMList").innerHTML = amList;
}

function uroMouseDown()
{
   uroMouseIsDown = true;
}
function uroMouseUp()
{
   uroMouseIsDown = false;
}
function uroMouseOut()
{
   //console.debug('Elvis has left the building...');
}

function uroUREvent_onObjectsChanged()
{
}
function uroUREvent_onObjectsAdded()
{
   if(uroGetCBChecked('_cbURResolverIDFilter') === true)
   {
      uroUpdateResolverList();
   }
   uroFilterURs();
}
function uroUREvent_onObjectsRemoved()
{
}

function uroGetSelectedURCommentCount()
{
   if(W.model.updateRequestSessions.objects[uroSelectedURID] != null)
   {
      var cachedCommentCount = W.model.updateRequestSessions.objects[uroSelectedURID].comments.length;
      uroAddLog(uroSelectedURID+':'+cachedCommentCount+' '+uroExpectedCommentCount);

      // if there aren't the same number of cached comments as there are comments in the UR dialog list, initiate
      // a refresh of the comment data...
      if(cachedCommentCount != uroExpectedCommentCount)
      {
         if(uroPendingCommentDataRefresh === true)
         {
            if(cachedCommentCount > 0)
            {
               uroCachedLastCommentID = W.model.updateRequestSessions.objects[uroSelectedURID].comments[cachedCommentCount-1].id;
            }
            else
            {
               uroCachedLastCommentID = null;
            }
            uroAddLog('updateRequestSessions refresh required for UR '+uroSelectedURID);
            if(uroCachedLastCommentID !== null)
            {
               uroAddLog('last comment ID for this UR is '+uroCachedLastCommentID);
            }
            else
            {
               uroAddLog('first comment for this UR, no previous comment to ID');
            }
            var idList = [];
            idList.push(uroSelectedURID);
            // need to delete the existing cache object first, as .get() is only capable of creating new objects,
            // it doesn't seem able to update an existing object with new data
            W.model.updateRequestSessions.remove(W.model.updateRequestSessions.objects[uroSelectedURID]);
            W.model.updateRequestSessions.get(idList);
            // the call to .get() initiates a XMLHttpRequest for the data, so we now need to switch modes - the
            // refresh process has started so we're no longer pending, but we are now waiting for the XMLHttpRequest
            // to return something...
            uroPendingCommentDataRefresh = false;
            uroWaitingCommentDataRefresh = true;
         }
         else
         {
            if(cachedCommentCount > 0)
            {
               var currentLastCommentID = W.model.updateRequestSessions.objects[uroSelectedURID].comments[cachedCommentCount-1].id;
               if(currentLastCommentID == uroCachedLastCommentID)
               {
                  // most recent comment loaded for this UR is the same one that was present at the start of this
                  // refresh process, so kick back into pending mode so we can retry the .get()...
                  uroAddLog('latest comment ID still the same, reverting to pending mode...');
                  uroPendingCommentDataRefresh = true;
               }
               else
               {
                  // something may have gone awry here - the most recent comment loaded for this UR doesn't have the
                  // same ID as the one present at the start of the refresh process, yet the comment counts still don't
                  // match up, which suggests either a comment got lost along the way or someone else has commented on
                  // the same UR at almost the same time.  To get out of the loop this would create, assume that a
                  // mismatch in the IDs means the .get() has completed successfully no matter what the new comment
                  // count is, and take this new count to be the count we were expecting all along...
                  uroAddLog('latest comment ID different, but expected count not correct...');
                  uroExpectedCommentCount = cachedCommentCount;
               }
            }
            else
            {
               uroAddLog('first comment on this UR not received yet, reverting to pending mode...');
               uroPendingCommentDataRefresh = true;
            }
         }

      }
      else
      {
         // if the WME session is loaded with a UR already selected, such that WME has opened the UR dialog as part
         // of the session startup process, adding new comments to the UR cause the cached data to be updated immediately.
         // This prevents URO+ from switching into waiting mode in the above block of code, so we have to instead do
         // it here by comparing the cached count against the expected count following the Send click event.
         if(cachedCommentCount >= uroExpectedCommentCount)
         {
            uroPendingCommentDataRefresh = false;
            uroWaitingCommentDataRefresh = true;
            uroExpectedCommentCount = null;
         }

         // once the cached data has been updated, refilter the URs so that the new comment count is taken into account
         // immediately for filtering and display purposes
         if(uroWaitingCommentDataRefresh === true)
         {
            uroWaitingCommentDataRefresh = false;
            uroFilterURs();
            uroAddLog('refresh complete');
         }
      }
   }
}

function uroAddedComment()
{
   // when the user clicks the Send button to submit a new UR comment, this event handler fires before the new comment is
   // posted to the server and thus also before the comment list gets updated in the UR dialog.  So we take the current
   // comment count and, if the new comment edit box isn't empty, increment it by 1 to get the expected count.  Then we
   // set the pending flag true to initiate a session refresh on the next 100ms tick
   uroExpectedCommentCount = W.map.panelRegion.currentView.conversationView.viewModel.attributes.commentCount;
   if(document.getElementsByClassName('new-comment-text')[0].value !== '')
   {
      uroExpectedCommentCount++;
      uroAddLog('new comment added to UR '+uroSelectedURID+', cache refresh required...');
      uroPendingCommentDataRefresh = true;
   }
   else
   {
      uroPendingCommentDataRefresh = false;
   }
}

function uroInhibitNextUpdateRequestButton(e)
{
   var doClick = true;
   e.stopPropagation();
   
   if(document.getElementsByClassName('form-control new-comment-text').length > 0)
   {
      if(document.getElementsByClassName('form-control new-comment-text')[0].textLength > 0)
      {
         doClick = (confirm('Comment not sent, close report panel anyway?'));
      }
   }
   if(doClick)
   {
      document.getElementsByClassName('close-panel')[0].click();
   }
}   

function uroAddLZ(valueToPad, newLength)
{
   var padString = '';
   for(var i=0; i<newLength; i++)
   {
      padString += '0';
   }
   padString += valueToPad.toString();
   return padString.slice(-newLength);
}

function uroIncrementClosureDate(oldDate, incByDays)
{
   var dateBits = oldDate.split('-');
   var year = parseInt(dateBits[0]);
   var month = parseInt(dateBits[1])-1;
   var date = parseInt(dateBits[2])+1;
   var incrementedDate = new Date(year, month, date);
   return (uroAddLZ(incrementedDate.getFullYear(),4) + '-' + uroAddLZ(incrementedDate.getMonth()+1,2) + '-' + uroAddLZ(incrementedDate.getDate(),2));
}

function uroGetElementProperty(elmName, elmOffset, elmProperty)
{
   var retval = null;
   if(document.getElementsByName(elmName).length !== 0)
   {
      retval = document.getElementsByName(elmName)[elmOffset][elmProperty];    
   }
   return retval;
}

// Residential Place Cloning
//{
   var uroCRPStreetID;
   var uroCRPHouseNumber;
   
   function uroCompleteRPClone()
   {   
      // as with closure cloning, the place details edit form requires us to push the new value into the relevant
      // edit field and then generate a change event on that field, otherwise WME doesn't bother reading the value...
      
      // street name
      var streetObj = W.model.streets.get(uroCRPStreetID);
      if(streetObj !== undefined)
      {
         document.getElementsByClassName('street-name')[0].value = streetObj.name;
         document.getElementsByClassName('street-name')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
      
         // city name
         var cityObj = W.model.cities.get(streetObj.cityID);
         if(cityObj !== undefined)
         {
            if(cityObj.attributes.isEmpty === true)
            {
               // The donor point place we create to take the cloned RPP properties may have been automatically given
               // a city name by WME, and thus the city name field will already be filled in and activated...  If our
               // RPP doesn't however have a city name, we need to deactivate the city name field again, so that WME
               // doesn't complain about the user trying to save the new RPP with an empty city name
               if(document.getElementsByClassName("empty-city")[0].checked === false)
               {
                  document.getElementsByClassName("empty-city")[0].click();
               }
            }
            document.getElementsByClassName('city-name')[0].value = cityObj.attributes.name;
            document.getElementsByClassName('city-name')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
            
            // county
            document.getElementsByClassName('state-id')[0].value = cityObj.attributes.stateID;
            document.getElementsByClassName('state-id')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
            
            // country
            document.getElementsByClassName('country-id')[0].value = cityObj.attributes.countryID;
            document.getElementsByClassName('country-id')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
         }
      }
      
      // house number
      document.getElementsByClassName('house-number')[0].value = uroCRPHouseNumber;
      document.getElementsByClassName('house-number')[0].dispatchEvent(new Event('change', { 'bubbles': true }));

      // now wait for the user to confirm everything and click Apply...
   }
   
   function uroConvertToRP()
   {
      // panel isn't open yet, which means the user either hasn't clicked yet or WME is still processing the
      // placement of the venue, so wait a while and then check again...
      if(document.getElementById('edit-panel').getElementsByClassName('landmark').length === 0)
      {
         setTimeout(uroConvertToRP, 100);
         return;
      }
      
      // panel is open, so move to the next step of the cloning procedure by converting the newly created
      // place to residential by generating a click event on the "convert to residential" link...
      document.getElementsByClassName("toggle-residential")[0].click();
      
      // and then click on the address edit icon...
      document.getElementsByClassName('waze-icon-edit')[0].click();
      
      // now click on the "none" checkbox for the street name edit field so we can enter the street name
      document.getElementById('empty-street').click();
      
      // WME automatically clears the checkbox associated with the city name edit field if we set the street
      // name to be one that has a city associated with it, which is nice :-)
      
      // the click event seems to take a while to execute, and if we call dispatchEvent on the edit field whilst
      // it's still tagged as disabled then it gets ignored, causing the value in that field to be dropped when
      // we apply the changes to the place.  Trying to programatically detect when the field has been activated 
      // doesn't seem to be reliable, however a fixed delay of 1s seems to work nicely
      setTimeout(uroCompleteRPClone, 1000);
   }
   
   function uroCloneResidentialPlace()
   {
      // trying to clone a RPP when one is already selected causes the selected one to be changed back to
      // a non-residential, as uroConvertToRP() thinks the user has already clicked to place the new RPP...
      if(document.getElementById('edit-panel').getElementsByClassName('landmark').length === 0)
      {
         var venueObj = W.model.venues.objects[uroFID];
         if(venueObj !== undefined)
         {
            // copy address from highlighted residential place
            uroCRPHouseNumber = venueObj.attributes.houseNumber;
            uroCRPStreetID = venueObj.attributes.streetID;

            // generate a click event on the first new point venue entry in the venues menu in order to generate a
            // new point venue object that we can manipulate...
            document.getElementsByClassName('toolbar-group-venues')[0].getElementsByClassName("drawing-control main-control point")[0].click();

            // now wait for the user to click on the map to place the new point venue
            uroConvertToRP();
         }
      }
   }
//}

// Closure Cloning
//{
   var uroConfirmClosureDelete = true;
   var uroClosuresToDelete = 0;
   
   var uroCLocation;
   var uroCReason;
   var uroCEvent;
   var uroCDirection;
   var uroCHasStartDate;
   var uroCStartDate;
   var uroCStartTime;
   var uroCEndDate;
   var uroCEndTime;
   var uroCIgnoreTraffic;

   function uroCompleteClosureCloning()
   {
      if(document.getElementsByClassName('edit-closure').length === 0)
      {
         window.setTimeout(uroCompleteClosureCloning,100);
         return;
      }

      // need to generate a change event on each of the form fields, because WME appears to be silently populating some hidden
      // closure object with the details as they're entered manually, and if we just set the form values without then forcing
      // the change event as well then WME will end up using its default values instead of the ones we've so lovingly copied...

      if(uroCLocation !== null)
      {
         document.getElementsByName('closure_location')[0].value = uroCLocation;
         document.getElementsByName('closure_location')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
      if(uroCReason !== null) 
      {
         document.getElementsByName('closure_reason')[0].value = uroCReason;
         document.getElementsByName('closure_reason')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
      if(uroCDirection !== null)
      {
         document.getElementsByName('closure_direction')[0].selectedIndex = uroCDirection;
         document.getElementsByName('closure_direction')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
      if(uroCHasStartDate !== null)
      {
         document.getElementsByName('closure_hasStartDate')[0].checked = uroCHasStartDate;
         document.getElementsByName('closure_hasStartDate')[0].dispatchEvent(new Event('change', {'bubbles':true})); 
      }
      if(uroCStartDate !== null)
      {
         document.getElementsByName('closure_startDate')[0].value = uroCStartDate;
         document.getElementsByName('closure_startDate')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
      if(uroCStartTime !== null)
      {
         document.getElementsByName('closure_startTime')[0].value = uroCStartTime;
         document.getElementsByName('closure_startTime')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
      
      if(uroCIgnoreTraffic !== null)
      {
         document.getElementsByName('closure_permanent')[0].checked = uroCIgnoreTraffic;
         document.getElementsByName('closure_permanent')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }     
      if(uroCEndTime !== null)
      {
         document.getElementsByName('closure_endTime')[0].value = uroCEndTime;
         // the cloning process doesn't alter the end time, which seems to confuse WME when it then receives the
         // change event - the MTE dropdown ends up being reset to just the "Choose event" and "None" entries
         // regardless of how many MTE entries there ought to be.  The fix for this appears to simply be to then
         // submit a second change event...
         document.getElementsByName('closure_endTime')[0].dispatchEvent(new Event('change', {'bubbles':true}));
         document.getElementsByName('closure_endTime')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }       

      // the current version of WME wipes any existing end date as soon as the end time is altered, so we now need
      // to set the date after the time instead of before as in earlier versions of this function...
      if(uroCEndDate !== null)
      {
         document.getElementsByName('closure_endDate')[0].value = uroCEndDate;
         document.getElementsByName('closure_endDate')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
      
      
      uroTempFixMTEDropDown();
      if(uroCEvent !== null)
      {
         if(document.getElementsByName('closure_eventId')[0].options.length > 1)
         {
            for(var loop=0; loop<document.getElementsByName('closure_eventId')[0].options.length; loop++)
            {
               if(document.getElementsByName('closure_eventId')[0].options[loop].value == uroCEvent)
               {
                  document.getElementsByName('closure_eventId')[0].selectedIndex = loop;
                  break;
               }
            }
         }
         else
         {
            document.getElementsByName('closure_eventId')[0].selectedIndex = 0;
         }
         document.getElementsByName('closure_eventId')[0].dispatchEvent(new Event('change', {'bubbles':true}));
      }
   }   
      
   function uroCloneClosure()
   {
      var closureOffset = parseInt(this.id.split('-')[1]);
      
      // grab the current closure details from the UI...
      document.getElementsByClassName('closure-item')[closureOffset].children[0].children[0].children[1].click();
      uroCLocation = uroGetElementProperty('closure_location', 0, 'value');
      uroCReason = uroGetElementProperty('closure_reason', 0, 'value');
      uroCEvent = uroGetElementProperty('closure_eventId', 0, 'value');
      uroCDirection = uroGetElementProperty('closure_direction', 0, 'selectedIndex');
      uroCHasStartDate = uroGetElementProperty('closure_hasStartDate', 0, 'checked');
      uroCStartDate = uroGetElementProperty('closure_startDate', 0, 'value');
      uroCStartTime = uroGetElementProperty('closure_startTime', 0, 'value');
      uroCEndDate = uroGetElementProperty('closure_endDate', 0, 'value');
      uroCEndTime = uroGetElementProperty('closure_endTime', 0, 'value');
      uroCIgnoreTraffic = uroGetElementProperty('closure_permanent', 0, 'checked');  
      document.getElementsByClassName('closures')[0].getElementsByClassName('cancel-button')[0].click();
      
      // auto-increment the start and end dates...
      uroCStartDate = uroIncrementClosureDate(uroCStartDate,1);
      uroCEndDate = uroIncrementClosureDate(uroCEndDate,1);
      
      // generate a click event on the Add a closure button to open up the closure editing UI, then
      // wait for the UI to finish opening...
      document.getElementsByClassName('add-closure-button')[0].click();
      window.setTimeout(uroCompleteClosureCloning,100);
   }

   function uroDeleteNextClosureOnList()
   {
      var nClosures = document.getElementsByClassName('closure-item').length;
      if(nClosures > 0)
      {
         if (nClosures != uroClosuresToDelete)
         {
            uroClosuresToDelete = nClosures;
            document.getElementsByClassName('closure-item')[0].getElementsByClassName('delete')[0].click();
         }
         setTimeout(uroDeleteNextClosureOnList,100);
      }
      else
      {
         uroConfirmClosureDelete = true;
      }
   }

   function uroDeleteAllClosures()
   {
      uroConfirmClosureDelete = true;
      if(window.confirm(I18n.lookup("closures.delete_confirm_no_reason")+' ('+I18n.lookup("closures.apply_to_all")+')'))
      {
         uroConfirmClosureDelete = false;
         var nClosures = document.getElementsByClassName('closure-item').length;
         if(nClosures > 0)
         {
            uroClosuresToDelete = -1;
            uroDeleteNextClosureOnList();
         }
         else
         {
            uroConfirmClosureDelete = true;
         }
      }
   }
//}

// Feed Filtering
//{
   function uroToggleFFCtrls()
   {
      if(uroShowFeedFilter === false)
      {
         uroShowFeedFilter = true;
         document.getElementById('_uroFFCtrlVisibility').className = "fa fa-minus-square-o";
         document.getElementById('uroFFCtrls').style.display = "block";
      }
      else
      {
         uroShowFeedFilter = false;
         document.getElementById('_uroFFCtrlVisibility').className = "fa fa-plus-square-o";
         document.getElementById('uroFFCtrls').style.display = "none";
      }
   }

   function uroForceFeedRefresh()
   {
      uroFeedFilterReloads = 0;
   }
   
   function uroAddFeedFilterControls()
   {
      if(document.getElementById('sidepanel-feed') != null)
      {
         if(document.getElementById('sidepanel-feed').childNodes[0] != null)
         {
            var nDiv = document.createElement('div');
            var iHTML = '';
            nDiv.id = "uroFeedFilter";
            iHTML += '<i class="fa fa-plus-square-o" style="cursor:pointer;font-size:14px;" id="_uroFFCtrlVisibility"> </i><b>Feed Filter Controls</b><br>';
            iHTML += '<div id="uroFFCtrls">';
            iHTML += '<b>Filter feed by listing type:</b><br>';
            iHTML += '<input type="checkbox" id="_cbFeedFilter_TypeUR" />UR<br>';
            iHTML += '<input type="checkbox" id="_cbFeedFilter_TypeMP" />MP<br>';
            iHTML += '<input type="checkbox" id="_cbFeedFilter_TypePUR" />PUR<br>';
            iHTML += '<input type="checkbox" id="_cbFeedFilter_TypePM" />PM notifications<br>';
            
            iHTML += '<br><b>Filter feed by listing reason:</b><br>';
            for(var loop=0; loop < uroFeedFilterFilters.length; loop++)
            {
               iHTML += '<input type="checkbox" id="_cbFeedFilter_'+loop+'" />'+I18n.lookup(uroFeedFilterFilters[loop][0])+'<br>';
            }
            iHTML += '<input type="checkbox" id="_cbFeedFilter_MotNone" />None of the above...<br>';
            iHTML += '<br><input type="checkbox" id="_cbFeedFilter_Invert" />Invert behaviour of above filters<br>';
            
            iHTML += '<br><b>Filter feed by keyword/phrase:</b><br>';
            iHTML += '<input type="checkbox" id="_cbFeedFilter_HideKeyword" pairedWith="_cbFeedFilter_ShowKeyword" />Hide or ';
            iHTML += '<input type="checkbox" id="_cbFeedFilter_ShowKeyword" pairedWith="_cbFeedFilter_HideKeyword" />show if keyword is present<br>';
            iHTML += '<input type="text" id="_cbFeedFilter_Keyword" />';

            iHTML += '</div>';
            nDiv.innerHTML = iHTML;
            document.getElementById('sidepanel-feed').insertBefore(nDiv,document.getElementById('sidepanel-feed').childNodes[0]);
            uroAddEventListener('_uroFFCtrlVisibility','click',uroToggleFFCtrls, true);
            uroShowFeedFilter = true;
            uroToggleFFCtrls();
            
            var nDiv2 = document.createElement('div');
            nDiv2.id = "uroFeedRefresher";
            nDiv2.style.display = 'none';
            nDiv2.innerHTML = '<br><div id="_btnFeedRefresh" class="btn btn-block btn-default" style="display: block;"><i class="fa fa-refresh"></div>';
            document.getElementById('sidepanel-feed').appendChild(nDiv2);
            uroAddEventListener('_btnFeedRefresh','click',uroForceFeedRefresh, true);
         }
      }
   }
   
   function uroTSTFeedFilter()
   {
      var feedEntries = document.getElementsByClassName('feed-item');
      var feedLength = feedEntries.length;
      if(feedLength === 0) return;
      
      if(document.getElementById('uroFeedFilter') === null) return;
      
      var hideFI;
      var iHTML;
      var fClass;
      
      var ffKeyword = uroGetElmValue('_cbFeedFilter_Keyword');
      var ffShowKW = uroGetCBChecked('_cbFeedFilter_ShowKeyword');
      var ffHideKW = uroGetCBChecked('_cbFeedFilter_HideKeyword');
      var kwPresent;
      
      var isChecked_cbFeedFilter_TypeUR = uroGetCBChecked('_cbFeedFilter_TypeUR');
      var isChecked_cbFeedFilter_TypeMP = uroGetCBChecked('_cbFeedFilter_TypeMP');
      var isChecked_cbFeedFilter_TypePUR = uroGetCBChecked('_cbFeedFilter_TypePUR');
      var isChecked_cbFeedFilter_TypePM = uroGetCBChecked('_cbFeedFilter_TypePM');
      var isChecked_cbFeedFilter_MotNone = uroGetCBChecked('_cbFeedFilter_MotNone');
      var isChecked_cbFeedFilter_Invert = uroGetCBChecked('_cbFeedFilter_Invert');

      var trans = [];
      var isChecked = [];
      var nFilters = uroFeedFilterFilters.length;
      
      for(var loop=0; loop < nFilters; loop++)
      {
         trans.push(I18n.lookup(uroFeedFilterFilters[loop][0]));
         isChecked.push(uroGetCBChecked('_cbFeedFilter_'+loop));
      }      

      for(var i=0; i<feedLength; i++)
      {
         hideFI = false;
         iHTML = feedEntries[i].innerHTML;
         fClass = feedEntries[i].className;
         
         if(isChecked_cbFeedFilter_TypeUR)
         {
            hideFI |= (fClass.indexOf('feed-issue-ur') != -1);
         }
         if(isChecked_cbFeedFilter_TypeMP)
         {
            hideFI |= (fClass.indexOf('feed-issue-mp') != -1);
         }
         if(isChecked_cbFeedFilter_TypePUR)
         {
            hideFI |= (fClass.indexOf('feed-issue-pu') != -1);
         }
         if(isChecked_cbFeedFilter_TypePM)
         {
            hideFI |= (fClass.indexOf('feed-notification-pm') != -1);
         }
         
         for(var filters=0; filters < nFilters; filters++)
         {
            if(isChecked[filters])
            {
               hideFI |= (iHTML.indexOf(trans[filters]) != -1);
            }
         }
               
         if(isChecked_cbFeedFilter_MotNone)
         {
            hideFI |= (iHTML.indexOf('motivation') == -1);
         }
                  
         if(isChecked_cbFeedFilter_Invert)
         {
            hideFI = !hideFI;
         }
        
         if((ffShowKW) || (ffHideKW))
         {
            kwPresent = (iHTML.indexOf(ffKeyword) != -1);
            hideFI |= (kwPresent & ffHideKW);
            hideFI |= ((!kwPresent) & ffShowKW); 
         }
        
         if(hideFI) feedEntries[i].style.display = 'none';
         else feedEntries[i].style.display = 'block';
      }
      
      var nFeedItems = document.getElementById('sidepanel-feed').getElementsByClassName('feed-item').length;
      var nVisibleItems = 0;
      for(var j=0; j < nFeedItems; j++)
      {
         if(document.getElementById('sidepanel-feed').getElementsByClassName('feed-item')[j].style.display == 'block')
         {
            nVisibleItems++;
         }
      }
      if(nVisibleItems < 5)
      {
         if(document.getElementById('sidepanel-feed').getElementsByClassName('feed-loading-more')[0].style.display == 'none')
         {
            if(uroFeedFilterReloads < 5)
            {
               document.getElementById('sidepanel-feed').getElementsByClassName('feed-load-more')[0].click();
               uroFeedFilterReloads++;
               document.getElementById('uroFeedRefresher').style.display = 'none';
            }
            else
            {
               document.getElementById('uroFeedRefresher').style.display = 'block';
            }
         }
      }
      else
      {
         uroFeedFilterReloads = 0;
         document.getElementById('uroFeedRefresher').style.display = 'none';
      }
   }   
//}

function uroGetMarkerType(className)
{
   var markerType = null;
   if(className.indexOf('user-generated') !== -1) markerType = 'ur';
   else if(className.indexOf('map-problem') !== -1) markerType = 'mp';
   else if(className.indexOf('place-update') !== -1) markerType = 'pur';
   return markerType;
}
function uroMarkerMouseOver(e)
{
   var markerType;
   markerType = uroGetMarkerType(this.className);
   if(markerType !== null)
   {
      var markerID = null;
      markerID = this.attributes["data-id"].value;
      uroAddLog('hover over '+markerType+' ID '+markerID);
      uroMousedOverMarkerID = markerID;
      uroMousedOverMarkerType = markerType;
      
      if(markerType == 'ur') uroHoveredURID = markerID;
   }
   else
   {
      uroAddLog('hover over unknown object...');
   }
}
function uroMarkerMouseOut(e)
{
   var markerType;
   markerType = uroGetMarkerType(this.className);
   if(markerType !== null)
   {
      var markerID = null;
      markerID = this.attributes["data-id"].value;
      uroAddLog('hover off '+markerType+' ID '+markerID);
      uroMousedOverMarkerID = null;
      uroMousedOverMarkerType = null;
      uroHoveredURID = null;
   }
   else
   {
      uroAddLog('hover off unknown object...');
   }
}
function uroMarkerClick()
{
   var markerType = uroGetMarkerType(this.className);
   if(markerType !== null)
   {
      var markerID = this.attributes["data-id"].value;
      uroAddLog('clicked on '+markerType+' marker '+markerID);
      uroClickedOnMarkerID = markerID;
      uroClickedOnMarkerType = markerType;
   }
}

function uroBlobMouseOver(e)
{
   var blobType = this.attributes.uroBlobType;
   if(blobType !== undefined)
   {
      var blobID = this.attributes.uroBlobID;
      uroAddLog('hover over '+blobType+' ID '+blobID);
      //uroMousedOverMarkerID = markerID;
      //uroMousedOverMarkerType = markerType;
   }
   else
   {
      uroAddLog('hover over unknown blob...');
   }
}
function uroBlobMouseOut(e)
{
   var blobType = this.attributes.uroBlobType;
   if(blobType !== undefined)
   {
      var blobID = this.attributes.uroBlobID;
      uroAddLog('hover off '+blobType+' ID '+blobID);
      //uroMousedOverMarkerID = markerID;
      //uroMousedOverMarkerType = markerType;
   }
   else
   {
      uroAddLog('hover off unknown blob...');
   }
}
function uroBlobClick()
{
   var blobType = this.attributes.uroBlobType;
   if(blobType !== undefined)
   {
      var blobID = this.attributes.uroBlobID;
      uroAddLog('clicked on '+blobType+' blob '+blobID);
   }
}

function uroMCLayerChanged()
{
	if(uroMCLayerIdx != null)
	{
		uroAddLog('adding MC blob event handlers');
		for(var mObj=0; mObj<W.map.layers[uroMCLayerIdx].features.length; mObj++)
		{
			var mcBlobID = W.map.layers[uroMCLayerIdx].features[mObj].model.attributes.geometry.id;
			var mcID = W.map.layers[uroMCLayerIdx].features[mObj].model.attributes.id;
			var mcBlob = document.getElementById(mcBlobID);
			if(mcBlob !== null)
			{
				mcBlob.addEventListener("mouseover", uroBlobMouseOver, false);
				mcBlob.addEventListener("mouseout", uroBlobMouseOut, false);
				mcBlob.addEventListener("click", uroBlobClick, false);
				mcBlob.attributes.uroBlobID = mcID;
				mcBlob.attributes.uroBlobType = "map_comment";
			}
		}
	}
}
function uroPlaceLayerChanged()
{
	uroAddLog('adding place blob event handlers');
	for(var mObj=0; mObj<W.map.landmarkLayer.features.length; mObj++)
	{
		var mcBlobID = W.map.landmarkLayer.features[mObj].model.attributes.geometry.id;
		var mcID = W.map.landmarkLayer.features[mObj].model.attributes.id;
		var mcBlob = document.getElementById(mcBlobID);
		if(mcBlob !== null)
		{
			mcBlob.addEventListener("mouseover", uroBlobMouseOver, false);
			mcBlob.addEventListener("mouseout", uroBlobMouseOut, false);
			mcBlob.addEventListener("click", uroBlobClick, false);
			mcBlob.attributes.uroBlobID = mcID;
			mcBlob.attributes.uroBlobType = "place";
		}
	}
}
function uroURLayerChanged()
{
   uroAddLog('adding UR marker event handlers');
   for(var mObj in W.map.updateRequestLayer.markers)
   {
      var mIcon = W.map.updateRequestLayer.markers[mObj].icon.div;
      mIcon.addEventListener("mouseover",uroMarkerMouseOver, false);
      mIcon.addEventListener("mouseout",uroMarkerMouseOut, false);
      mIcon.addEventListener("click",uroMarkerClick, false);
   }
}
function uroMPLayerChanged()
{
   uroAddLog('adding MP marker event handlers');
   for(var mObj in W.map.problemLayer.markers)
   {
      var mIcon = W.map.problemLayer.markers[mObj].icon.div;
      mIcon.addEventListener("mouseover", uroMarkerMouseOver, false);
      mIcon.addEventListener("mouseout", uroMarkerMouseOut, false);
      mIcon.addEventListener("click", uroMarkerClick, false);
   }
}
function uroPURLayerChanged()
{
   uroAddLog('adding PUR marker event handlers');   
   for(var mObj in W.map.placeUpdatesLayer.markers)
   {
      var mIcon = W.map.placeUpdatesLayer.markers[mObj].icon.div;
      mIcon.addEventListener("mouseover", uroMarkerMouseOver, false);
      mIcon.addEventListener("mouseout", uroMarkerMouseOut, false);
      mIcon.addEventListener("click", uroMarkerClick, false);
   }
}
function uroFinalizeListenerSetup()
{
   uroFinalisingListenerSetup = true;
   
   // 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)
   W.model.mapUpdateRequests.on("objectschanged", uroFilterURs_onObjectsChanged);
   W.model.mapUpdateRequests.on("objectsadded", uroFilterURs_onObjectsAdded);
   W.model.mapUpdateRequests.on("objectsremoved", uroFilterURs_onObjectsRemoved);

   W.model.updateRequestSessions.on("objectschanged", uroUREvent_onObjectsChanged);
   W.model.updateRequestSessions.on("objectsadded", uroUREvent_onObjectsAdded);
   W.model.updateRequestSessions.on("objectsremoved", uroUREvent_onObjectsRemoved);

   W.model.cameras.on("objectschanged", uroFilterCameras);
   W.model.cameras.on("objectsadded", uroFilterCameras);
   W.model.cameras.on("objectsremoved", uroFilterCameras);

   W.model.problems.on("objectschanged", uroFilterProblems);
   W.model.problems.on("objectsadded", uroFilterProblems);
   W.model.problems.on("objectsremoved", uroFilterProblems);
   
   W.model.venues.on("objectschanged", uroFilterPlaces);
   W.model.venues.on("objectsadded", uroFilterPlaces);
   W.model.venues.on("objectsremoved", uroFilterPlaces);
   
   ////var uroMO_MCLayer = new MutationObserver(uroMCLayerChanged);
   ////uroMO_MCLayer.observe(W.map.layers[uroMCLayerIdx].div,{childList: true, attributes : true, characterData: true, subtree: true});
   ////var uroMO_PlaceLayer = new MutationObserver(uroPlaceLayerChanged);
   ////uroMO_PlaceLayer.observe(W.map.landmarkLayer.div,{childList: true, attributes : true, characterData : true, subtree: true});
   var uroMO_URLayer = new MutationObserver(uroURLayerChanged);
   uroMO_URLayer.observe(W.map.updateRequestLayer.div,{childList : true});
   var uroMO_MPLayer = new MutationObserver(uroMPLayerChanged);
   uroMO_MPLayer.observe(W.map.problemLayer.div,{childList : true});
   var uroMO_PURLayer = new MutationObserver(uroPURLayerChanged);
   uroMO_PURLayer.observe(W.map.placeUpdatesLayer.div,{childList : true});
   
   var userTabs = document.getElementById(uroUserTabId);
   var tabContent = null;

   var navTabs = userTabs.getElementsByClassName('nav-tabs')[0];
   tabContent = document.getElementById('user-info').getElementsByClassName('tab-content')[0];
   var 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);

   uroAddEventListener('_btnUndoLastHide',"click", uroRemoveLastAddedIgnore, true);       
   uroAddEventListener('_btnClearSessionHides',"click", uroRemoveAllIgnores, true);       
   uroEnableIgnoreListControls();

   uroAddEventListener('_btnClearCamWatchList',"click", uroClearCamWatchList, true);
   uroAddEventListener('_btnSettingsToText',"click", uroSettingsToText, true);
   uroAddEventListener('_btnTextToSettings',"click", uroTextToSettings, true);
   uroAddEventListener('_btnResetSettings',"click", uroDefaultSettings, true);
   uroAddEventListener('_btnClearSettingsText',"click", uroClearSettingsText, true);
   uroAddEventListener('_cbMasterEnable',"click", uroFilterItems_MasterEnableClick, true);
   
/*
   uroAddEventListener('_btnDebugToScreen',"click", uroDumpDebug, true);
*/
   
   uroAddEventListener('uroDiv',"dblclick",uroSuppressPopup,true);
   
   uroAddEventListener('_selectCameraUserID',"change", uroCamEditorSelected, true);
   uroAddEventListener('_selectPlacesUserID',"change", uroPlacesEditorSelected, true);
   
   uroAddEventListener('uroAlertTickBtn','click',uroCloseAlertBoxWithTick,true);
   uroAddEventListener('uroAlertCrossBtn','click',uroCloseAlertBoxWithCross,true);      
   
   uroSetOnClick("_linkSelectUserRequests",uroShowURTab);
   uroSetOnClick("_linkSelectMapProblems",uroShowMPTab);
   uroSetOnClick("_linkSelectPlaces",uroShowPlacesTab);
   uroSetOnClick("_linkSelectCameras",uroShowCameraTab);
   uroSetOnClick("_linkSelectMisc",uroShowMiscTab);
   uroSetOnClick("_linkSelectOWL",uroShowOWLTab);

   for(var idx=0;idx<W.Config.venues.categories.length;idx++)
   {
      uroSetOnClick('_uroPlacesGroupState-'+idx,uroPlacesGroupCollapseExpand);
   }

   uroAddLog('finalise onload');
   uroLoadSettings();
   uroNewLookCheckDetailsRequest();
   if(uroGetCBChecked('_cbEnableDTE'))
   {
      if(dteControlsIdx != -1)
      {
         dteSetNewTabLength();
      }
      else
      {
         uroAddLog('ERROR - archive panel not found!');
         uroSetStyleDisplay(uroUserTabId,'');
      }
   }
   // filter markers as and when the map is moved
   W.map.events.register("moveend", null, uroFilterItems);
   W.map.events.register("mousemove", null, uroGetAMs);
   W.map.events.register("mousemove", null, uroNewLookHighlightedItemsCheck);
   W.map.events.registerPriority("mousedown", null, uroMouseDown);

   // trap mousedown on Streetview marker drag
   document.getElementsByClassName('street-view-control')[0].onmousedown = uroMouseDown;

   W.map.events.register("mouseup", null, uroMouseUp);
   W.map.events.register("mouseout", null, uroMouseOut);

   uroSetStyles(uroCtrlURs);
   uroSetStyles(uroCtrlMPs);
   uroSetStyles(uroCtrlPlaces);
   uroSetStyles(uroCtrlCameras);
   uroSetStyles(uroCtrlMisc);
   uroSetStyles(uroOWL);

   uroAddFeedFilterControls();

   uroShowURTab();

   uroUserID = W.loginManager.getLoggedInUser().id;

   uroFilterItems();

   uroShowDebugOutput = uroPersistentDebugOutput;
   var dbgMode = "none";
   if(uroShowDebugOutput)
   {
      dbgMode = "inline";
   }
   document.getElementById('_uroDebugMode').style.display = dbgMode;
   uroAddEventListener('_uroVersion',"click", uroToggleDebug, true);            

   // add exclusiveCB click handlers to all checkboxes with a pairedWith attribute
   var cbList = document.getElementsByTagName('input');
   for (var optIdx=0;optIdx<cbList.length;optIdx++)
   {
      if((cbList[optIdx].id.indexOf('_cb') === 0) && (cbList[optIdx].attributes.pairedWith != null))
      {
         uroSetOnClick(cbList[optIdx].id,uroExclusiveCB);
      }
   }
   
   // manually call the layer-change handlers on startup, since there's a good chance WME will already have
   // completed its own startup layer changes before our handlers get registered, preventing the marker handlers
   // from being set up as expected on any markers which are visible in the startup map view before the user forces
   // a layer update by panning/zooming/etc...
   ////uroMCLayerChanged();
   ////uroPlaceLayerChanged();
   uroURLayerChanged();
   uroMPLayerChanged();
   uroPURLayerChanged();
   
   uroSetupListeners = false; 
   uroInitialised = true;
}

function uroTSTPopupHandler()
{
   if(document.getElementsByClassName('panel')[0] === undefined)
   {
      uroHidePopupOnPanelOpen = true;
   }

         
   if(uroPopupShown === true)
   {
      var hidePopup = false;
      
      if(document.getElementsByClassName('dropdown action open').length > 0.5)
      {
         hidePopup = true;
      }
      if(hidePopup === false)
      {
         if(document.getElementsByClassName('layer-switcher-container').length === 0)
         {
            if(document.getElementById('layer-switcher-list') !== null)
            {
               hidePopup = (window.getComputedStyle(document.getElementById('layer-switcher-list').parentNode).getPropertyValue('opacity') > 0.5);
            }
            else if(document.getElementsByClassName('layer-switcher').length !== 0)
            {
               hidePopup = (window.getComputedStyle(document.getElementsByClassName('layer-switcher')[0].getElementsByClassName('content')[0]).getPropertyValue('visibility') == 'visible');
            }
         }
      }
      if(hidePopup === false)
      {
         hidePopup = (window.getComputedStyle(document.getElementsByClassName('toolbar-group-drawing')[0].childNodes[0]).getPropertyValue('opacity') > 0.5);
      }
      if(hidePopup === false)
      {
         hidePopup = (window.getComputedStyle(document.getElementsByClassName('toolbar-group-venues')[0].childNodes[0]).getPropertyValue('opacity') > 0.5);
      }
      if(hidePopup === false)
      {
         hidePopup = (window.getComputedStyle(document.getElementsByClassName('toolbar-group-map-comments')[0].childNodes[0]).getPropertyValue('opacity') > 0.5);
      }

      if(document.getElementsByClassName('panel')[0] != null)
      {
         if(uroHidePopupOnPanelOpen === true)
         {
            hidePopup = true;
            uroHidePopupOnPanelOpen = false;
         }
      }

      if(hidePopup === true)
      {        
         uroHidePopup();
      }
   }

   if((uroAreaNameHoverObj !== null) && (uroAreaNameHoverTime != -1) && (uroAreaNameOverlayShown === false))
   {
      if(++uroAreaNameHoverTime > 5)
      {
         uroAreaNameOverlaySetup();
      }
   }
   uroReplaceAreaNames(false);

   if(uroPopupTimer > 0)
   {
      if(uroMouseInPopup === false)
      {
         uroPopupTimer--;
      }
   }
   if(uroPopupTimer === 0)
   {         
      uroHidePopup();
   }

   if(uroPopupDwellTimer > 0)
   {
      uroPopupDwellTimer--;
      if(uroPopupDwellTimer === 0)
      {
         uroNewLookHighlightedItemsCheck('dwellTimeout');
      }
   }
}

function uroTSTDTEHandler()
{
   if(document.getElementsByClassName("archive-panel")[0] === undefined)
   {
      if(dteClearHighlightsOnPanelClose)
      {
         dteClearListHighlight();
         dteClearHighlightsOnPanelClose = false;
      }
   }
   else
   {
      if(dteArmClearHighlightsOnPanelClose)
      {
         dteArmClearHighlightsOnPanelClose = false;
         dteClearHighlightsOnPanelClose = true;
      }
   }
}

function uroTSTNextBtnHandler()
{
   // replace the "next xxx" button on UR, MP and PUR editing UIs
   if(W.map.panelRegion.hasView() === true)
   {
      var nurButton = W.map.panelRegion.$el[0].getElementsByClassName('btn btn-block')[0];
      if(nurButton != null)
      {
         var doneString = I18n.lookup('problems.panel.done');
         var nextURString = (nurButton.innerHTML.indexOf(I18n.lookup('update_requests.panel.next')) !== -1);
         var nextMPString = (nurButton.innerHTML.indexOf(I18n.lookup('problems.panel.next')) !== -1);
         var nextPURString = (nurButton.innerHTML.indexOf(I18n.lookup('venues.update_requests.panel.next_venue')) !== -1);
         var nextIssueString = (nurButton.innerHTML.indexOf(I18n.lookup('feed.issues.next')) !== -1);

         var updateButton = false;
         
         var panelClass = W.map.panelRegion.$el[0].childNodes[0].childNodes[0].className;
         var isURorMPPanel = (panelClass.indexOf('problem-edit') !== -1);
         var isPURPanel = (panelClass.indexOf('place-update') !== -1);   
         
         // "next" button class used for UR and MP edit panel
         if(isURorMPPanel === true)
         {
            // user has enabled UR button mod?
            if(uroGetCBChecked('_cbInhibitNURButton') === true)
            {
               // mod the button if this is a UR/MP panel rather than a PUR panel, and if the "Next update request" or "Next issue"
               // text is currently being used on the button - WME uses the former text when a UR is selected directly from the map
               // pin, and the latter text when a UR is selected from the feed.  However, it *also* uses the latter text for PURs
               // selected from the feed, hence the need to test the panel type here as well - having to work around odd
               // inconsistencies in WME behaviour, whatever next...
               updateButton = updateButton || ((nextURString === true) || (nextIssueString === true));
            }
            
            // user has enabled MP button mod?
            if(uroGetCBChecked('_cbInhibitNMPButton') === true)
            {
               // although there's no easy way to determine whether the panel is opened for a UR or MP, since the feed doesn't yet seem
               // to provide a means of accessing MPs then we don't yet have to worry about finding the "Next issue" text in a MP panel,
               // which makes life slightly easier here...
               updateButton = updateButton || (nextMPString === true);
            }         
         }
         else if(isPURPanel === true)
         {
            // "next-venue" class only used for PUR edit panel
            if(uroGetCBChecked('_cbInhibitNPURButton') === true)
            {
               // as noted above, PURs opened from the feed may also use the "Next issue" text, so we need to test for that as well,
               // knowing that in order to get this far we've already determined that the user really does want to mod the PUR
               // next button *and* that the currently open panel is a PUR panel...
               updateButton = updateButton || ((nextPURString === true) || (nextIssueString === true));
            }
         }

         if(updateButton === true)
         {
            // if we need to change the button label back to "Done", do it here...
            nurButton.innerHTML = doneString;
            uroAddLog('inhibit Next UR/MP/PUR button');   
         }
         
         // if updateButton isn't already set here, it suggests the panel is using the native "Done" button...
         if(updateButton === false)
         {
            nurButton = W.map.panelRegion.$el[0].getElementsByClassName('btn btn-block done')[0];
            if(nurButton != null)
            {
               updateButton = true;
            }
         }

         if(updateButton === true)
         {
            // Add a new click handler to override the native one - this acts both to prevent the normal action of the "Next UR/MP/PUR" button in
            // moving to the next UR/MP/PUR, and also allows us to warn about closing the UR panel if there's an unsent comment...
            nurButton.addEventListener("click", uroInhibitNextUpdateRequestButton, false);
         }
      }
   }   
}

function uroTSTCommentAddedHandler()
{
   // test for the opening or closing of the UR editing dialog so we can detect when a new comment is added
   var URDialogIsOpen = false;
   var panelOpen = (document.getElementById('panel-container').firstChild !== null);
   if(panelOpen)
   {
      if(document.getElementById('panel-container').firstChild.firstChild !== null)
      {
         var panelClass = document.getElementById('panel-container').firstChild.firstChild.className;
         if(panelClass === 'problem-edit severity-low')
         {
            URDialogIsOpen = true;
         }
      }
   }
   
   if(URDialogIsOpen)
   {
      var thisSelectedURID = document.getElementsByClassName('permalink')[0].href.split('&mapUpdateRequest=');
      if(thisSelectedURID.length > 1)
      {
         thisSelectedURID = thisSelectedURID[1].split('&')[0];
      }
      else
      {
         thisSelectedURID = null;
      }

      if(thisSelectedURID != uroSelectedURID)
      {
         // if the user selects a new UR whilst the editing dialog is still open, treat it in the
         // same way as if the user had selected that UR with the dialog closed
         uroURDialogIsOpen = false;
      }
      if(uroURDialogIsOpen === false)
      {
         // user is editing a new UR
         uroSelectedURID = thisSelectedURID;
         
         // add our own click event handler to the Send button, so we can do stuff whenever a new comment is added
         document.getElementsByClassName('new-comment-form')[0].getElementsByClassName('btn')[0].addEventListener("click", uroAddedComment, false);
         
         uroAddLog('user is editing UR '+uroSelectedURID);
         uroExpectedCommentCount = W.model.updateRequestSessions.objects[uroSelectedURID].comments.length;
         
         ////if(uroShowDebugOutput === true)
         {
            if((uroHoveredURID !== null) && (uroSelectedURID !== null) && (parseInt(uroHoveredURID) !== parseInt(uroSelectedURID)))
            {
               if(uroURReclickAttempts === 0)
               {
                  uroAddLog('DANGER, WILL ROBINSON!  You clicked on UR ID '+uroHoveredURID+' but WME has loaded the details for UR ID '+uroSelectedURID+' instead, attempting to fix...');
               }
               if(++uroURReclickAttempts < 3)
               {
                  //uroRestackMarkers();
                  W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.x = W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.realX;
                  W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.y = W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.realY;
                  W.map.updateRequestLayer.markers[uroHoveredURID].icon.$div.click();
                  return;
               }
               else
               {
                  uroAddLog('Woe is me, attempting to open UR ID '+uroHoveredURID+' has failed...');
                  uroShowAlertBox('fa-warning', 'URO+ Warning', 'WME may have opened the details panel for a different UR to the one you selected, proceed with caution', false, "OK", "", null, null);
               }
            }
            uroURReclickAttempts = 0;
         }
      }
   }
   else if(uroURDialogIsOpen === true)
   {
      // dialog was open and has now been closed
      uroSelectedURID = null;
   }
   uroURDialogIsOpen = URDialogIsOpen;

   if(((uroPendingCommentDataRefresh === true) || (uroWaitingCommentDataRefresh === true)) && (uroSelectedURID !== null))
   {
      uroAddLog('check completion of comment data refresh for UR '+uroSelectedURID+' ('+uroPendingCommentDataRefresh+','+uroWaitingCommentDataRefresh+')');
      uroGetSelectedURCommentCount();
   }

}

function uroTSTOWLHandler()
{
/*
   var selectedTotal = W.selectionManager.selectedItems.length;
   if((selectedTotal > 0) && (document.getElementById('_uroDivOWLBtns') === null))
   {
      var selectedClass = W.selectionManager.selectedItems[0].model.CLASS_NAME;
      var displayAddToOWLBtn = false;
      var displayUpdateOWLBtn = false;
      var displayRemoveFromOWLBtn = false;
      var selectedSegments = false;
      var selectedLandmarks = false;
      var fid;
      var loop;

      // WME only seems to allow multi-object selections for segments, so testing the class of the first object in the
      // selection list tells us the class of any other objects in the list too...
      if(selectedClass == "Waze.Feature.Vector.Segment")
      {
         selectedSegments = true;
         for(loop=0; loop<selectedTotal; loop++)
         {
            fid = W.selectionManager.selectedItems[loop].model.attributes.id;
            var segIdx = uroIsSegOnWatchList(fid);
            if(segIdx == -1)
            {
               displayAddToOWLBtn = true;
            }
            else
            {
               if(uroSegDataChanged(segIdx))
               {
                  displayUpdateOWLBtn = true;
               }
               displayRemoveFromOWLBtn = true;
            }
         }
      }

      else if(selectedClass == "Waze.Feature.Vector.Landmark")
      {
         selectedLandmarks = true;
         for(loop=0; loop<selectedTotal; loop++)
         {
            fid = W.selectionManager.selectedItems[loop].model.attributes.id;
            var placeIdx = uroIsPlaceOnWatchList(fid);
            if(placeIdx == -1)
            {
               displayAddToOWLBtn = true;
            }
            else
            {
               if(uroPlaceDataChanged(placeIdx))
               {
                  displayUpdateOWLBtn = true;
               }
               displayRemoveFromOWLBtn = true;
            }
         }
      }

      var btnHTML = '<div id="_uroDivOWLBtns">';
      if((displayAddToOWLBtn === true) && (displayUpdateOWLBtn === false))
      {
         btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Add to OWL</button>';
      }
      else if((displayUpdateOWLBtn === true) && (displayAddToOWLBtn === false))
      {
         btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Update OWL</button>';
      }
      else if((displayAddToOWLBtn === true) && (displayUpdateOWLBtn === true))
      {
         btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Add to & Update OWL</button>';
      }

      if(displayRemoveFromOWLBtn === true)
      {
         btnHTML += '<button class="btn btn-default" id="_btnRemoveOWL">Remove from OWL</button>';
      }
      btnHTML += '</div>';        

      // note to self...  altering the inner HTML of the segment-edit-general panel when the selected
      // segment is part of a roundabout always used to disable the onclick handler for the select
      // roundabout button.  will need to see how this behaves in the current WME given the changes in
      // panel arrangement and the introduction of the native select roundabout button
      if(selectedSegments === true)
      {
         document.getElementById("segment-edit-general").innerHTML += btnHTML;
      }
      else if(selectedLandmarks === true)
      {
         document.getElementById("landmark-edit-general").innerHTML += btnHTML;
      }

      if((displayAddToOWLBtn === true)||(displayUpdateOWLBtn === true))
      {
         if(selectedSegments === true)
         {
            uroAddEventListener('_btnAddUpdateOWL','click', uroAddUpdateSegWatchList, true);
         }
         else
         {
            uroAddEventListener('_btnAddUpdateOWL','click', uroAddUpdatePlaceWatchList, true);
         }
      }

      if(displayRemoveFromOWLBtn === true)
      {
         if(selectedSegments === true)
         {
            uroAddEventListener('_btnRemoveOWL','click', uroRemoveSegFromWatchList, true);
         }
         else
         {
            uroAddEventListener('_btnRemoveOWL','click', uroRemovePlaceFromWatchList, true);
         }
      }
   }
*/   
}

function uroTSTClosureCloningHandler()
{
   // closure cloning support...
   //
   // has the closures tab been generated?
   if(document.getElementById('segment-edit-closures') !== null)
   {
      // and is it active?
      if(document.getElementById('segment-edit-closures').className === 'tab-pane active')
      {
         // and are there any closures defined for all of the selected segment(s)...
         if(document.getElementsByClassName('full-closures').length > 0)
         {
            var nClosures = document.getElementsByClassName('full-closures')[0].childNodes.length;
            if(nClosures > 0)
            {
               // and last but by no means least, have we already added the clone icon to this closure?
               for(var cLoop = 0; cLoop < nClosures; cLoop++)
               {
                  var btnElm = document.getElementsByClassName('full-closures')[0].childNodes[cLoop].children[0].children[0];
                                    
                  if(btnElm.innerHTML.indexOf('_uroCloneClosure-') == -1)
                  {  
                     var newAnchor = document.createElement('a');
                     var anchorID = '_uroCloneClosure-'+cLoop;
                     newAnchor.href="#";
                     newAnchor.innerHTML = "<i class='fa fa-copy'></i>";                     
                     newAnchor.id = anchorID;
                     btnElm.appendChild(newAnchor);
                     uroAddEventListener(anchorID,"click",uroCloneClosure,false);
                  }
               }
            }
         }
         // if there's more than one closure (full or partial) listed, also add the delete all button if not already present...
         if(document.getElementsByClassName('closure-item').length > 1)
         {
            if(document.getElementById('_btnDeleteAllClosures') === null)
            {
               var daDiv = document.createElement('div');
               daDiv.className = 'delete-all-button btn btn-primary';
               daDiv.id = '_btnDeleteAllClosures';
               
               daDiv.innerHTML = '<i class="fa fa-trash"></i> '+I18n.lookup("closures.delete_confirm_no_reason")+' ('+I18n.lookup("closures.apply_to_all")+')';
               daDiv.style.width = '100%';
               daDiv.style.marginBottom = '10px';
               
               var acBtn = document.getElementsByClassName('add-closure-button')[0];
               acBtn.parentNode.insertBefore(daDiv, acBtn.nextSibling);
               uroAddEventListener('_btnDeleteAllClosures',"click", uroDeleteAllClosures, false);
            }
         }
      }
   }
}

function uroMiscUITweaksHandler()
{
   if(uroFilterPreamble())
   {
      // give user the option of setting their own background colour...
      {
         var mapviewport = document.getElementsByClassName("olMapViewport")[0];
         if((uroGetCBChecked('_cbWhiteBackground') === true) && (uroGetCBChecked('_cbMasterEnable') === true))
         {
            var customColour = '#' + uroToHex(uroGetElmValue('_inputCustomBackgroundRed'),2);
            customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundGreen'),2);
            customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundBlue'),2);
            mapviewport.style.backgroundColor = customColour;
         }
         else
         {
            mapviewport.style.backgroundColor = "#C2C2C2";
         }
      }

      // allows user to hide the area managers layer without switching off the layer completely...
      {
         // ...if this sounds like a weird option - why not just switch off the layer from the layers menu? - then
         // remember that in order for URO+ to be able to display in its own tab the list of AMs under the current
         // mouse pointer location, which is somewhat more useful than the list given in the topbar, it needs the
         // AM layer to be activated so that the AM areas data is loaded into WME.  It doesn't however need the layer
         // to then be visible, and since having a bunch of purple polygons covering the map can make for a rather
         // difficult editing experience, being able to hide the polys whilst retaining the area information is
         // of real benefit...
         if((uroGetCBChecked('_cbHideAMLayer')) && (uroGetCBChecked('_cbMasterEnable')))
         {
            W.map.managedAreasLayer.setOpacity(0);
         }
         else
         {
            W.map.managedAreasLayer.setOpacity(1);
         }
      }

      // gives user the option of minimising the size of the sidebar tabs to save space
      {
         if(!uroGetCBChecked('_cbDisableTabStyling'))
         {
            // The nav-tabs class is now also used for the General/Closures tabs on the segment edit panel, so we have
            // to restrict the scope of this code to just those nav-tab classed elements within the user-tabs element.
            var navTabs = document.getElementById('user-tabs').getElementsByClassName("nav-tabs")[0].children;
            for(var loop = 0; loop<navTabs.length; loop++)
            {
               navTabs[loop].children[0].style.padding = "4px";
            }
         }
      }   

      // gives user the option of hiding the somewhat unnecessary editor info panel at the top of the sidebar
      {
         var panelDisplay = '';
         if(uroGetCBChecked('_cbHideEditorInfo'))
         {
            panelDisplay = "none";
         }
         document.getElementById("user-details").style.display = panelDisplay;
      }
   }
}

function uroTenthSecondTick()
{
   if(uroMTEMode) return;
   if(uroSetupListeners)
   {
      if(uroFinalisingListenerSetup === false)
      {
         if(W.loginManager.isLoggedIn())
         {
            uroFinalizeListenerSetup();
         }
      }
   }
   else
   {
      uroTSTPopupHandler();
      uroTSTDTEHandler();
      uroTSTNextBtnHandler();

      uroTSTCommentAddedHandler();
      uroTSTOWLHandler();
      uroTSTClosureCloningHandler();
      uroTSTFeedFilter();
      uroMiscUITweaksHandler();

      uroTempFixMTEDropDown();
   }
}

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");
   uroInactiveTab("_tabSelectPlaces");

   if(!uroCtrlsHidden)
   {
      uroSetStyleDisplay('uroCtrlURs','none');
      uroSetStyleDisplay('uroCtrlMPs','none');
      uroSetStyleDisplay('uroCtrlCameras','none');
      uroSetStyleDisplay('uroCtrlMisc','none');
      uroSetStyleDisplay('uroOWL','none');
      uroSetStyleDisplay('uroCtrlPlaces','none');
   }
}

function uroShowURTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectUserRequests");
   uroCurrentTab = 1;
   if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlURs','block');
   return false;
}

function uroShowMPTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectMapProblems");
   uroCurrentTab = 2;
   if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMPs','block');
   return false;
}

function uroShowPlacesTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectPlaces");
   uroCurrentTab = 3;
   if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlPlaces','block');
   for(var idx=0;idx<uroPlacesGroupsCollapsed.length;idx++)
   {
      uroPlacesGroupCEHandler(idx);
   }
   return false;
}

function uroShowCameraTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectCameras");
   uroCurrentTab = 4;
   if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlCameras','block');
   return false;
}

function uroShowOWLTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectCWL");
   uroCurrentTab = 5;
   if(!uroCtrlsHidden) uroSetStyleDisplay('uroOWL','block');
   uroOWLUpdateHTML();
   return false;
}

function uroShowMiscTab()
{
   uroInactiveAllTabs();
   uroActiveTab("_tabSelectMisc");
   uroCurrentTab = 6;
   if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMisc','block');
   return false;
}

function uroNewLookCheckDetailsRequest()
{
   var thisurl = document.location.href;
   var doRetry = true;
   var urID;
   var endmarkerpos = thisurl.indexOf('&endshow');
   var showmarkerpos = thisurl.indexOf('&showturn=');
   
   if((endmarkerpos != -1) && (showmarkerpos != -1))
   {
      showmarkerpos += 10;
      uroAddLog('showturn tab opened');
      urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos);
      uroAddLog(' turn problem ID = '+urID);

      try
      {
         W.map.problemLayer.markers[urID].icon.imageDiv.click();
         doRetry = false;
      }
      catch(err)
      {
         uroAddLog('problems not fully loaded, retrying...');
      }

      if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
   }
   else
   {
      showmarkerpos = thisurl.indexOf('&showpur=');
      if((endmarkerpos != -1) && (showmarkerpos != -1))
      {
         showmarkerpos += 9;
         uroAddLog('showPUR tab opened');
         urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos);
         uroAddLog(' PUR ID = '+urID);

         try
         {
            W.map.placeUpdatesLayer.markers[urID].icon.imageDiv.click();
            doRetry = false;
         }
         catch(err)
         {
            uroAddLog('PURs not fully loaded, retrying...');
         }

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

}

function uroUpdateVenueEditorList()
{
   if(Object.keys(W.model.venues.objects).length === 0) return;

   var selector = document.getElementById('_selectPlacesUserID');
   var selectedUser = null;
   if(selector.selectedOptions[0] != null)
   {
      selectedUser = parseInt(selector.selectedOptions[0].value);
   }
   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   }

   var selectedIdx = null;
   var listedIDs = [];
   var idx;
   for(idx in W.model.venues.objects)
   {
      if(W.model.venues.objects.hasOwnProperty(idx))
      {
         var obj = W.model.venues.objects[idx].attributes;
         var cbID = obj.createdBy;
         var ubID = obj.updatedBy;
         
         if((cbID !== null) && (listedIDs.indexOf(cbID) == -1))
         {
            listedIDs.push(cbID);
         }
         if((ubID !== null) && (ubID !== cbID) && (listedIDs.indexOf(ubID) == -1))
         {
            listedIDs.push(ubID);
         }
      }
   }

   selector.options.add(new Option('<select a user>', null));
   if(listedIDs.length > 0)
   {
      var users = W.model.users.getByIds(listedIDs);   
      var selectorEntry = '';
      for(idx=0; idx<users.length; idx++)
      {
         if(users[idx].userName === undefined)
         {
            selectorEntry = users[idx].id;
         }
         else
         {
            selectorEntry = users[idx].userName;
         }
         selector.options.add(new Option(selectorEntry, users[idx].id));
         if(users[idx].id == selectedUser)
         {
            selectedIdx = idx+1;
         }
      }
   }

   if(selectedIdx !== null)
   {
      selector.selectedIndex = selectedIdx;
   }
}

function uroPlacesEditorSelected()
{
   var selector = document.getElementById('_selectPlacesUserID');
   if(selector.selectedIndex > 0)
   {
      document.getElementById('_textPlacesEditor').value = document.getElementById('_selectPlacesUserID').selectedOptions[0].innerHTML;
   }
}

function uroUpdateMPSolverList()
{
   if(Object.keys(W.model.problems.objects).length === 0)
   {
      return;
   }

   var resolverList = [];
   var selector = document.getElementById('_selectMPUserID');
   var selectedUser = null;
   if(selector.selectedOptions[0] != null)
   {
      selectedUser = parseInt(selector.selectedOptions[0].value);
   }
   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   }
   var selectedIdx = 0;
   var idx = 0;

   for (var mpobj in W.model.problems.objects)
   {
      if(W.model.problems.objects.hasOwnProperty(mpobj))
      {
         var prob = W.model.problems.objects[mpobj];
         if(prob.attributes.resolvedBy !== null)
         {
            var userID = prob.attributes.resolvedBy;
            var userName = W.model.users.objects[userID].userName;
            if(resolverList.indexOf(userName) == -1)
            {
               resolverList.push(userName);
               selector.options.add(new Option(userName, userID));
               if(userID == selectedUser)
               {
                  selectedIdx = idx;
               }
               idx++;
            }
         }
      }
   }

   if(selectedIdx !== null)
   {
      selector.selectedIndex = selectedIdx;
   }
}

function uroUpdateResolverList()
{
   if(Object.keys(W.model.mapUpdateRequests.objects).length === 0)
   {
      return;
   }

   var resolverList = [];
   var selector = document.getElementById('_selectURResolverID');
   var selectedUser = null;
   if(selector.selectedOptions[0] != null)
   {
      selectedUser = parseInt(selector.selectedOptions[0].value);
   }
   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   }
   var selectedIdx = 0;
   var idx = 0;

   for (var urobj in W.model.mapUpdateRequests.objects)
   {
      if(W.model.mapUpdateRequests.objects.hasOwnProperty(urobj))
      {
         var ureq = W.model.mapUpdateRequests.objects[urobj];
         if(ureq.attributes.resolvedBy !== null)
         {
            var userID = ureq.attributes.resolvedBy;
            var userName = W.model.users.objects[userID].userName;
            if(resolverList.indexOf(userName) == -1)
            {
               resolverList.push(userName);
               selector.options.add(new Option(userName, userID));
               if(userID == selectedUser)
               {
                  selectedIdx = idx;
               }
               idx++;
            }
         }
      }
   }
   if(selectedIdx !== null)
   {
      selector.selectedIndex = selectedIdx;
   }
}

function uroUpdateUserList()
{
   if(Object.keys(W.model.updateRequestSessions.objects).length === 0) return;

   var selector = document.getElementById('_selectURUserID');

   var selectedUser = null;
   if(selector.selectedOptions[0] != null)
   {
      selectedUser = parseInt(selector.selectedOptions[0].value);
   }

   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   }

   var selectedIdx = null;

   var listedIDs = [];
   for(var ursIdx in W.model.updateRequestSessions.objects)
   {
      if(W.model.updateRequestSessions.objects.hasOwnProperty(ursIdx))
      {
         var ursObj = W.model.updateRequestSessions.objects[ursIdx];
         if(ursObj.comments.length > 0)
         {
            for(var cidx=0; cidx < ursObj.comments.length; cidx++)
            {
               var userID = ursObj.comments[cidx].userID;
               if((listedIDs.indexOf(userID) == -1) && (userID != -1))
               {
                  listedIDs.push(userID);
               }
            }
         }
      }
   }

   if(listedIDs.length > 0)
   {
      var users = W.model.users.getByIds(listedIDs);
      for(var idx=0; idx<listedIDs.length; idx++)
      {
         selector.options.add(new Option(users[idx].userName, listedIDs[idx]));
         if(listedIDs[idx] == selectedUser)
         {
            selectedIdx = idx;
         }
      }
   }


   if(selectedIdx !== null)
   {
      selector.selectedIndex = selectedIdx;
   }
}

function uroUpdateCamEditorList()
{
   if(Object.keys(W.model.cameras.objects).length === 0) return;

   var selector = document.getElementById('_selectCameraUserID');

   var selectedUser = null;
   if(selector.selectedOptions[0] != null)
   {
      selectedUser = parseInt(selector.selectedOptions[0].value);
   }

   while(selector.options.length > 0)
   {
      selector.options.remove(0);
   }

   var selectedIdx = null;
   var listedIDs = [];
   for(var camIdx in W.model.cameras.objects)
   {
      if(W.model.cameras.objects.hasOwnProperty(camIdx))
      {
         var camObj = W.model.cameras.objects[camIdx].attributes;
         var cbID = camObj.createdBy;
         var ubID = camObj.updatedBy;
         
         if((cbID !== null) && (listedIDs.indexOf(cbID) == -1))
         {
            listedIDs.push(cbID);
         }
         if((ubID !== null) && (ubID !== cbID) && (listedIDs.indexOf(ubID) == -1))
         {
            listedIDs.push(ubID);
         }
      }
   }

   selector.options.add(new Option('<select a user>', null));
   if(listedIDs.length > 0)
   {
      var users = W.model.users.getByIds(listedIDs);   
      var selectorEntry = '';
      for(var idx=0; idx<users.length; idx++)
      {
         if(users[idx].userName === undefined)
         {
            selectorEntry = users[idx].id;
         }
         else
         {
            selectorEntry = users[idx].userName;
         }
         selector.options.add(new Option(selectorEntry, users[idx].id));
         if(users[idx].id == selectedUser)
         {
            selectedIdx = idx+1;
         }
      }
   }

   if(selectedIdx !== null)
   {
      selector.selectedIndex = selectedIdx;
   }
}

function uroCamEditorSelected()
{
   var selector = document.getElementById('_selectCameraUserID');
   if(selector.selectedIndex > 0)
   {
      document.getElementById('_textCameraEditor').value = document.getElementById('_selectCameraUserID').selectedOptions[0].innerHTML;
   }
}

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

function uroPlacesGroupCEHandler(groupidx)
{
   if(uroPlacesGroupsCollapsed[groupidx] === false)
   {
      document.getElementById('_uroPlacesGroup-'+groupidx).style.display = "block";
      document.getElementById('_uroPlacesGroupState-'+groupidx).className = "fa fa-minus-square-o";
   }
   else
   {
      document.getElementById('_uroPlacesGroup-'+groupidx).style.display = "none";
      document.getElementById('_uroPlacesGroupState-'+groupidx).className = "fa fa-plus-square-o";
   }
}
function uroPlacesGroupCollapseExpand()
{
   var groupidx = this.id.substr(21);
   if(uroPlacesGroupsCollapsed[groupidx] === true) uroPlacesGroupsCollapsed[groupidx] = false;
   else uroPlacesGroupsCollapsed[groupidx] = true;
   uroPlacesGroupCEHandler(groupidx);
   return false;
}
function uroPopulateProblemsTab()
{
   var tHTML = '';
   tHTML += '<input type="checkbox" id="_cbMPFilterOutsideArea">Hide MPs outside my editable area</input><br><br>';
   tHTML += '<b>Filter MPs by type:</b><br>';
   var i;
   for(i=0; i<uroKnownProblemTypeNames.length; i++)
   {
      tHTML += '<input type="checkbox" id="_cbMPFilter_T'+uroKnownProblemTypeIDs[i]+'">'+uroKnownProblemTypeNames[i]+'</input><br>';
   }      
   tHTML += '<br><input type="checkbox" id="_cbMPFilterUnknownProblem">Unknown problem type</input><br><br>';

   tHTML += '&nbsp;&nbsp;<i>Specially tagged types</i><br>';
   tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterElgin">[Elgin]</input><br>';
   tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterTrafficCast">[TrafficCast]</input><br>';
   tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterTrafficMaster">[TM]</input><br>';
   tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterCaltrans">[Caltrans]</input><br>';
   tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterTFL">TfL</input><br>';
   
   tHTML += '<input type="checkbox" id="_cbMPFilterReopenedProblem">Reopened Problems</input><br><br>';

   tHTML += '<input type="checkbox" id="_cbInvertMPFilter">Invert operation of type filters?</input><br>';

   

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

   tHTML += '<input type="checkbox" id="_cbMPClosedUserIDFilter" pairedWith="_cbMPNotClosedUserIDFilter">Closed</input> or ';
   tHTML += '<input type="checkbox" id="_cbMPNotClosedUserIDFilter" pairedWith="_cbMPClosedUserIDFilter">Not Closed</input> by user';
   tHTML += '<select id="_selectMPUserID" style="width:80%; height:22px;"></select><br>';

   tHTML += '<br><b>Hide problems (not turn) by severity:</b><br>';
   tHTML += '<input type="checkbox" id="_cbMPFilterLowSeverity">Low</input>&nbsp;&nbsp;';
   tHTML += '<input type="checkbox" id="_cbMPFilterMediumSeverity">Medium</input>&nbsp;&nbsp;';
   tHTML += '<input type="checkbox" id="_cbMPFilterHighSeverity">High</input><br>';
   
   uroCtrlMPs.innerHTML = tHTML;
}
function uroPopulatePlacesTab()
{
   var tHTML = '';
   tHTML += '<b>Filter PURs by category/status:</b><br>';
   tHTML += '<input type="checkbox" id="_cbFilterUneditablePlaceUpdates">Ones I can\'t edit</input><br>';
   tHTML += '<input type="checkbox" id="_cbFilterLockRankedPlaceUpdates">Ones with non-zero lockRanks</input><br>';
   tHTML += '<input type="checkbox" id="_cbFilterNewPlacePUR">Ones for new places</input><br>';
   tHTML += '<input type="checkbox" id="_cbFilterUpdatedDetailsPUR">Ones for updated place details</input><br>';
   tHTML += '<input type="checkbox" id="_cbFilterNewPhotoPUR">Ones for new photos</input><br>';
   tHTML += '<input type="checkbox" id="_cbFilterFlaggedPUR">Ones flagged for attention</input><br>';
   tHTML += '<br><input type="checkbox" id="_cbLeavePURGeos">Don\'t hide place polygons/points</input><br>';
   tHTML += '<br><input type="checkbox" id="_cbInvertPURFilters">Invert PUR filters</input><br>';

   tHTML += '<br><b>Filter PURs by severity:</b><br>';
   tHTML += '<input type="checkbox" id="_cbPURFilterLowSeverity">Low</input>&nbsp;&nbsp;';
   tHTML += '<input type="checkbox" id="_cbPURFilterMediumSeverity">Medium</input>&nbsp;&nbsp;';
   tHTML += '<input type="checkbox" id="_cbPURFilterHighSeverity">High</input>';

   tHTML += '<br><b>Filter PURs by age of submission:</b><br>';
   tHTML += '<input type="checkbox" id="_cbEnablePURMinAgeFilter">Hide PURs less than </input>';
   tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPURFilterMinDays"> days old<br>';
   tHTML += '<input type="checkbox" id="_cbEnablePURMaxAgeFilter">Hide PURs more than </input>';
   tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPURFilterMaxDays"> days old<br>';

   tHTML += '<hr>';

   tHTML += '<br><b>Filter Places by state:</b><br>';
   tHTML += 'Hide if last edited<br>';
   tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedLessThan"> less than </input>';
   tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMinDays"> days ago<br>';
   tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedMoreThan"> more than </input>';
   tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMaxDays"> days ago<br>';

   tHTML += '<br>Hide if locked at level:<br>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL0">1</input>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL1">2</input>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL2">3</input>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL3">4</input>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL4">5</input>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL5">6</input>'; 
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesStaff">Staff</input>';
   tHTML += '<br>&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesAdLocked">AdLocked</input><br>';
   
   tHTML += '<br>Hide by geometry:<br>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideAreaPlaces">Areas</input>';
   tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePointPlaces">Points</input>';   

   tHTML += '<br><br><input type="checkbox" id="_cbHidePhotoPlaces" pairedWith="_cbHideNoPhotoPlaces">Hide or </input>';
   tHTML += '<input type="checkbox" id="_cbHideNoPhotoPlaces" pairedWith="_cbHidePhotoPlaces">show ones with photos</input><br>';

   tHTML += '<input type="checkbox" id="_cbHideLinkedPlaces" pairedWith="_cbHideNoLinkedPlaces">Hide or </input>';
   tHTML += '<input type="checkbox" id="_cbHideNoLinkedPlaces" pairedWith="_cbHideLinkedPlaces">show ones with external links</input><br>';
   
   tHTML += '<input type="checkbox" id="_cbHideKeywordPlaces" pairedWith="_cbHideNoKeywordPlaces">Hide or </input>';
   tHTML += '<input type="checkbox" id="_cbHideNoKeywordPlaces" pairedWith="_cbHideKeywordPlaces">show ones with a name including</input><br>';
   tHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPlace"><br>';
   
   tHTML += '<br><b>Show Places touched by a specific editor:</b><br>';
   tHTML += '<input type="checkbox" id="_cbShowOnlyPlacesCreatedBy">Created by</input>&nbsp;/&nbsp;';
   tHTML += '<input type="checkbox" id="_cbShowOnlyPlacesEditedBy">edited by</input><br>'; 
   tHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textPlacesEditor"><br>';   
   tHTML += '<select id="_selectPlacesUserID" style="width:80%; height:22px;"></select><br>';   

   tHTML += '<br><br><b>Filter Places by category:</b><br>';

   var nCategories = W.Config.venues.categories.length;
   var i;
   if(uroPlacesGroupsCollapsed.length != nCategories)
   {
      for(i=0; i<nCategories; i++)
      {
         uroPlacesGroupsCollapsed.push(false);
      }
   }

   for(i=0; i<nCategories; i++)
   {
      var parentCategory = W.Config.venues.categories[i];
      var localisedName = I18n.lookup("venues.categories." + parentCategory);

      if(uroPlacesGroupsCollapsed[i] === true)
      {
         tHTML += '<i class="fa fa-plus-square-o" style="cursor:pointer;font-size:14px;" id="_uroPlacesGroupState-'+i+'"></i>';
      }
      else
      {
         tHTML += '<i class="fa fa-minus-square-o" style="cursor:pointer;font-size:14px;" id="_uroPlacesGroupState-'+i+'"></i>';
      }

      tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbPlacesFilter-'+parentCategory+'"><b>'+localisedName+'</b></input><br>';
      tHTML += '<div id="_uroPlacesGroup-'+i+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF">';

      for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++)
      {
         var subCategory = W.Config.venues.subcategories[parentCategory][ii];
         localisedName = I18n.lookup("venues.categories." + subCategory);
         tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbPlacesFilter-'+subCategory+'">'+localisedName+'</input><br>';
      }
      tHTML += '</div>';
   }
   tHTML += '<input type="checkbox" id="_cbFilterPrivatePlaces"><b>Residential Places</b></input><br>';
   tHTML += '<br><input type="checkbox" id="_cbInvertPlacesFilter">Invert Place filters?</input>';

   uroCtrlPlaces.innerHTML = tHTML;
}

function uroWazeBits()
{
   // "fake" uroWazeBits() function which only performs layer scan, to stop the uroWazeBits() call in WMETB from
   // messing around with other stuff in the actual uroWazeBits() function (now renamed uroRealWazeBits...) that
   // really only ought to be called once.
   
   var i;
      
   uroTurnsLayerIdx = null;
   uroMCLayerIdx = null;
   for(i=0;i<W.map.layers.length;i++)
   {
      if(W.map.layers[i].CLASS_NAME == 'OpenLayers.Layer.Vector.RootContainer') uroRootContainer = W.map.layers[i].div.id;
      if(W.map.layers[i].name == 'Node Connections') uroTurnsLayerIdx = i;
	   if(W.map.layers[i].featureType == 'mapComment') uroMCLayerIdx = i;
   }
   uroPlacesRoot = W.map.landmarkLayer.id + '_vroot';

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

      if(W.map.controls[i].id !== null)
      {
         if(W.map.controls[i].id.indexOf('UpdateRequests') != -1) uroURControlsIdx = i;
         if(W.map.controls[i].id.indexOf('MapProblems') != -1) uroProblemControlsIdx = i;
      }
   }
   uroAddLog('Turns layer at idx '+uroTurnsLayerIdx);
   uroAddLog('MC layer at idx '+uroMCLayerIdx);
   uroAddLog('uroRootContainer = '+uroRootContainer);
   uroAddLog('Places root layer = '+uroPlacesRoot);
}
function uroRealWazeBits()
{
   if(document.getElementsByClassName("sandbox").length > 0)
   {
      uroAddLog('WME practice mode detected, script is disabled...');
      return;
   }

   if(document.location.href.indexOf('user') !== -1)
   {
      uroAddLog('User profile page detected, script is disabled...');
      return;
   }
   uroAddLog('adding WazeBits...'+uroToHex(uroWazeBitsPresent,4));
   if((uroWazeBitsPresent & 0x0001) === 0)
   {
      if(typeof W != "undefined")
      {
         if(typeof W.map != "undefined")
         {
            uroAddLog('   W.map OK');
            uroWazeBitsPresent |= 0x0001;
         }
      }
   }
   if((uroWazeBitsPresent & 0x0002) === 0)
   {
      if(typeof W != "undefined")
      {
         if(typeof W.model != "undefined")
         {
            uroAddLog('   W.model OK');
            uroWazeBitsPresent |= 0x0002;
         }
      }
   }
   if((uroWazeBitsPresent & 0x0004) === 0)
   {
      if(typeof W != "undefined")
      {
         if(typeof W.loginManager != "undefined")
         {
            uroAddLog('   loginManager OK');
            uroWazeBitsPresent |= 0x0004;
         }
      }
   }
   if((uroWazeBitsPresent & 0x0008) === 0)
   {
      if(typeof W != "undefined")
      {
         if(typeof W.selectionManager != "undefined")
         {
            uroAddLog('   selectionManager OK');
            uroWazeBitsPresent |= 0x0008;
         }
      }
   }
   if((uroWazeBitsPresent & 0x0010) === 0)
   {
      if(typeof OpenLayers != "undefined")
      {
         uroAddLog('   OpenLayers OK');
         uroWazeBitsPresent |= 0x0010;
      }
   }
   if((uroWazeBitsPresent & 0x0020) === 0)
   {
      if(typeof Waze != "undefined")
      {
         uroAddLog('   Waze OK');
         uroWazeBitsPresent |= 0x0020;
      }
   }
   if((uroWazeBitsPresent & 0x0040) === 0)
   {
      if(document.getElementById('user-tabs') !== null)
      {
         uroUserTabId = 'user-tabs';
         uroAddLog('   user-tabs OK');
         uroWazeBitsPresent |= 0x0040;
      }
   }
   if((uroWazeBitsPresent & 0x0080) === 0)
   {
      if(document.getElementById('sidepanel-drives') !== null)
      {
         uroAddLog('   sidepanel-drives OK');
         uroWazeBitsPresent |= 0x0080;
      }
   }
   if((uroWazeBitsPresent & 0x0100) === 0)
   {
      if(typeof I18n != "undefined")
      {
         uroAddLog('   I18n OK');
         uroWazeBitsPresent |= 0x0100;
      }
   }

   if(uroWazeBitsPresent !== 0x01FF) 
   {
      setTimeout(uroRealWazeBits,250);
   }
   else if(W.loginManager.isLoggedIn() === false)
   {
      uroAddLog('Waiting for user log-in...');
      setTimeout(uroRealWazeBits,1000);
   }
   else
   {
      uroAddLog('All WazeBits present and correct...');
      W.app.modeController.model.bind("change:mode",uroInitialise);
      if(W.app.modeController.mode.mteModeState !== undefined)
      {
         uroMTEMode = true;
         uroSetupListeners = true;
         uroFinalisingListenerSetup = false;
         uroHidePopup();
         uroAddLog('MTE mode, sleeping until normal service is resumed...');
         return;
      }
      uroMTEMode = false;
      uroSetupUI();
      uroDOMHasTurnProblems = (W.model.turnProblems != null);
      uroGetProblemTypes();
      uroPopulateProblemsTab();
      uroPopulatePlacesTab();
      
      uroControls.appendChild(uroCtrlURs);
      uroControls.appendChild(uroCtrlMPs);
      uroControls.appendChild(uroCtrlPlaces);
      uroControls.appendChild(uroCtrlCameras);
      uroControls.appendChild(uroOWL);
      uroControls.appendChild(uroCtrlMisc);
      uroControls.appendChild(uroCtrlHides);
      uroControls.appendChild(uroAMList);

      uroCtrlURs.onclick = uroFilterItems_URTabClick;
      uroCtrlMPs.onclick = uroFilterItems_MPTabClick;
      uroCtrlPlaces.onclick = uroFilterItems_PlacesTabClick;
      uroCtrlCameras.onclick = uroFilterItems_CamerasTabClick;
      uroCtrlMisc.onclick = uroFilterItems_MiscTabClick;

      uroWazeBits();

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

      if(sessionStorage.UROverview_FID_IgnoreList === undefined) sessionStorage.UROverview_FID_IgnoreList = '';
      if(sessionStorage.UROverview_FID_WatchList === undefined) sessionStorage.UROverview_FID_WatchList = '';
      if(uroConfirmIntercepted === false) uroAddInterceptor();
      
      setInterval(uroTenthSecondTick,100);
   }
}

function uroAddInterceptor()
{
   uroAddLog('Adding interceptor function...');
   // add interceptor function for confirm(), so that we can auto-select the "OK" option when solving URs
   // which have pending question...

   var _confirm = window.confirm;
   window.confirm = function(msg)
   {
      var cm_delete_confirm = I18n.lookup("closures.delete_confirm").split('"')[0].trimRight(1);
      
      if((I18n.lookup("update_requests.panel.confirm") == msg) && (uroGetCBChecked('_cbDisablePendingQuestions') === true))
      {
         uroAddLog('Intercepted pending comments confirmation...');
         return true;
      }
      else if(msg.indexOf(cm_delete_confirm) != -1)
      {
         uroAddLog('intercepted closure delete confirmation...');
         if(uroConfirmClosureDelete)
         {
            return _confirm(msg);
         }
         else
         {
            return true;
         }
      }
      else if(typeof(msg) == 'undefined')
      {
         uroAddLog('Intercepted blank confirmation...');
         return true;
      }
      else
      {
         return _confirm(msg);
      }
   };   
   
   uroConfirmIntercepted = true;
}

function uroEnterPopup()
{
   uroMouseInPopup = true;
}

function uroExitPopup()
{
   uroMouseInPopup = false;
}

function uroToggleDebug()
{
   uroShowDebugOutput = !uroShowDebugOutput;
   var dbgMode = "none";
   if(uroShowDebugOutput)
   {
      dbgMode = "inline";
   }
   document.getElementById('_uroDebugMode').style.display = dbgMode;
}

function uroInitialise()
{
   uroInitialised = false;
   
   if(document.URL.indexOf('beta') != -1) uroBetaEditor = true;
   
   var urlBits = document.URL.split("&mapUpdateRequest=");
   if(urlBits.length == 2)
   {
      uroURIDInURL = parseInt(urlBits[1].split('&')[0]);
      uroAddLog('found UR ID '+uroURIDInURL+' in URL');
   }
   uroRealWazeBits();
}

function uroSetupUI()
{
   // 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 = 'solid';
   uroDiv.style.borderRadius = '10px';
   uroDiv.style.boxShadow = '5px 5px 10px Silver';
   uroDiv.style.padding = '4px';
   document.body.appendChild(uroDiv);

   // create a new div to display script alerts
   uroAlerts = document.createElement('div');
   uroAlerts.id = "uroAlerts";
   uroAlerts.style.position = 'fixed';
   uroAlerts.style.visibility = 'hidden';
   uroAlerts.style.top = '50%';
   uroAlerts.style.left = '50%';
   uroAlerts.style.zIndex = 100;
   uroAlerts.style.backgroundColor = 'aliceblue';
   uroAlerts.style.borderWidth = '3px';
   uroAlerts.style.borderStyle = 'solid';
   uroAlerts.style.borderRadius = '10px';
   uroAlerts.style.boxShadow = '5px 5px 10px Silver';
   uroAlerts.style.padding = '4px';   
   uroAlerts.style.webkitTransform = "translate(-50%, -50%)";
   uroAlerts.style.transform = "translate(-50%, -50%)";
   
   var alertsHTML = '<div id="header" style="padding: 4px; background-color:LightGreen; font-weight: bold;">Alert title goes here...</div>';
   alertsHTML += '<div id="content" style="padding: 4px; background-color:White">Alert content goes here...</div>';
   alertsHTML += '<div id="controls" style="padding: 4px;">';   
   alertsHTML += '<span id="uroAlertTickBtn" style="cursor:pointer;font-size:14px;border:thin outset black;padding:2px;">';
   alertsHTML += '<i class="fa fa-check"> </i>';
   alertsHTML += '<span id="uroAlertTickBtnCaption" style="font-weight: bold;"></span>';
   alertsHTML += '</span>';
   alertsHTML += '&nbsp;&nbsp;';
   alertsHTML += '<span id="uroAlertCrossBtn" style="cursor:pointer;font-size:14px;border:thin outset black;padding:2px;">';
   alertsHTML += '<i class="fa fa-times"> </i>';
   alertsHTML += '<span id="uroAlertCrossBtnCaption" style="font-weight: bold;"></span>';
   alertsHTML += '</span>';
   alertsHTML += '</div>';
   uroAlerts.innerHTML = alertsHTML;
   document.body.appendChild(uroAlerts);


   uroControls = document.createElement('section');
   uroControls.style.fontSize = '12px';
   uroControls.id = 'uroControls';
   var updateURL;
   if(navigator.userAgent.indexOf('Chrome') == -1)
   {
      updateURL = 'https://greasyfork.org/scripts/1952-uroverview-plus-uro';
   }
   else
   {
      updateURL = 'https://chrome.google.com/webstore/detail/uroverview/amdamgkgchnbaopmphhjapmjcdghdphi';
   }
   var tabbyHTML = '<b><a href="'+updateURL+'" target="_blank">UROverview Plus</a></b> <label id="_uroVersion">'+uroVersion+'</label>';
   tabbyHTML += '<label id="_uroDebugMode">(dbg)</label>';
   tabbyHTML += '&nbsp;<input type="checkbox" id="_cbMasterEnable" checked>Enabled</input>';
   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="_tabSelectPlaces"><a href="#" id="_linkSelectPlaces" style="text-decoration:none;font-size:12px">Places</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="_linkSelectOWL" style="text-decoration:none;font-size:12px">OWL</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');
   uroOWL = document.createElement('p');
   uroCtrlMisc = document.createElement('p');
   uroAMList = document.createElement('div');
   uroCtrlHides = document.createElement('div');
   uroCtrlPlaces = document.createElement('p');

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

   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURFilterOutsideArea">Hide URs outside my editable area</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbNoFilterForURInURL">Don\'t filter UR in URL</input><br><br>';
   
   uroCtrlURs.innerHTML += '<b>Filter 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="_cbFilterSpeedLimits">Missing or Invalid Speed limit</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUndefined">Undefined</input><br>';

   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<i>Specially tagged types</i><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterRoadworks">[ROADWORKS]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterConstruction">[CONSTRUCTION]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterClosure">[CLOSURE]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterEvent">[EVENT]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterNote">[NOTE]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterBOG">[BOG]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterDifficult">[DIFFICULT]</input><br>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterWSLM">[WSLM]</input><br><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbInvertURFilter">Invert operation of type filters?</input><br>';

   uroCtrlURs.innerHTML += '<hr>';

   uroCtrlURs.innerHTML += '<br><b>Hide by state:</b><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterOpenUR">Open</input><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 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 by description/comments/following:</b><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyFollowed" pairedWith="_cbHideMyUnfollowed">Ones I am or </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyUnfollowed" pairedWith="_cbHideMyFollowed">am not following</input><br><br>';

   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBePresent" pairedWith="_cbURDescriptionMustBeAbsent">Hide</input> or ';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBeAbsent" pairedWith="_cbURDescriptionMustBePresent">show</input> URs with no description<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"><i>Case-insensitive matches?</i></input><br><br>';

   uroCtrlURs.innerHTML += 'With comments from me?<br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyComments" pairedWith="_cbHideAnyComments">Yes </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideAnyComments" pairedWith="_cbHideMyComments">No</input><br>';
   uroCtrlURs.innerHTML += 'If last comment made by me?<br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfLastCommenter" pairedWith="_cbHideIfNotLastCommenter">Yes </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfNotLastCommenter" pairedWith="_cbHideIfLastCommenter">No </input><br>';
   uroCtrlURs.innerHTML += 'If last comment made by UR reporter?<br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterLastCommenter" pairedWith="_cbHideIfReporterNotLastCommenter">Yes </input>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterNotLastCommenter" pairedWith="_cbHideIfReporterLastCommenter">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><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>';
   uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbIgnoreOtherEditorComments"><i>Ignore other editor comments?</i></input><br><br>';

   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURUserIDFilter">Without comments from user</input>';
   uroCtrlURs.innerHTML += '<select id="_selectURUserID" style="width:80%; height:22px;"></select><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURResolverIDFilter">Not resolved by user</input>';
   uroCtrlURs.innerHTML += '<select id="_selectURResolverID" style="width:80%; height:22px;"></select>';

   uroCtrlURs.innerHTML += '<br><br><input type="checkbox" id="_cbInvertURStateFilter">Invert operation of state/age filters?</input><br>';
   uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbNoFilterForTaggedURs">Don\'t apply state/age filters to tagged URs</input><br>';


   // Map problems controls tab
   uroCtrlMPs.id = "uroCtrlMPs";
   uroCtrlMPs.innerHTML = 'MP filter list being populated, please wait...';


   // Places filtering tab
   uroCtrlPlaces.id = "uroCtrlPlaces";
   uroCtrlPlaces.innerHTML = 'Places filter list being populated, please wait...';


   // Camera controls tab
   uroCtrlCameras.id = "uroCtrlCameras";
   uroCtrlCameras.innerHTML = '<br><b>Show Cameras created by:</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><b>Show Cameras touched by a specific editor:</b><br>';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowOnlyCamsCreatedBy">Created by</input>&nbsp;/&nbsp;';
   uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowOnlyCamsEditedBy">edited by</input><br>'; 
   uroCtrlCameras.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textCameraEditor"><br>';   
   uroCtrlCameras.innerHTML += '<select id="_selectCameraUserID" style="width:80%; height:22px;"></select><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="_cbShowIfSpeedSet" checked> with speed data</input><br>';
   uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfNoSpeedSet" checked> with no speed data</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 watchlist</input></b><br>';


   // Object watchlist tab
   uroOWL.id = "uroOWL";
   uroCWLGroups = [];
   uroOWLUpdateHTML();


   // 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<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeBetaConvoMarkers" checked />in beta WME<br>';

   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCommentCount" />Show comment count on UR markers</b><br>';

   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbURBackfill" />Backfill UR data</b><br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Marker Unstacking:</b><br>';
   uroCtrlMisc.innerHTML += 'Distance threshold: <input type="number" min="1" max="30" value="15" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputUnstackSensitivity" /><br>';
   uroCtrlMisc.innerHTML += 'Disable below zoom: <input type="number" min="0" max="10" value="3" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputUnstackZoomLevel" /><br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for URs tagged as:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomRoadworksMarkers" />[ROADWORKS]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomConstructionMarkers" />[CONSTRUCTION]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomClosuresMarkers" />[CLOSURE]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomEventsMarkers" />[EVENT]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomNotesMarkers" />[NOTE]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomBOGMarkers" />[BOG]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomDifficultMarkers" />[DIFFICULT]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomWSLMMarkers" />[WSLM]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomNativeSLMarkers" />Native speed limit reports<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomKeywordMarkers" />';
   uroCtrlMisc.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textCustomKeyword" /><br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for MPs tagged as:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomElginMarkers" />[Elgin]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomTrafficMasterMarkers" />[TM]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomTrafficCastMarkers" />[TrafficCast]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomCaltransMarkers" />[Caltrans]<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomTFLMarkers" />[TfL Open Data]<br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Popup mouse behaviour:</b><br>';
   uroCtrlMisc.innerHTML += 'Mouse idle <input type="number" min="1" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPopupDwellTimeout" /> *100ms<br>';
   uroCtrlMisc.innerHTML += 'Mouse over <input type="number" min="1" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPopupEntryTimeout" /> *100ms<br>';
   uroCtrlMisc.innerHTML += 'Distance <input type="number" min="0" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputMaxJitter" /> pixels<br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Disable popup for:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitURPopup" />URs<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMPPopup" />MPs<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitCamPopup" />Cameras<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitSegPopup" />Segments<br>';
   uroCtrlMisc.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbInhibitSegGenericPopup" />Speed limit info<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitTurnsPopup" />Restricted Turns<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitLandmarkPopup" />Places<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitPUPopup" />Place Updates<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMapCommentPopup" />Map Comments<br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Date/Time formatting for popups:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbDateFmtDDMMYY" pairedWith="_cbDateFmtMMDDYY,_cbDateFmtYYMMDD" checked />day/month/year<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbDateFmtMMDDYY" pairedWith="_cbDateFmtDDMMYY,_cbDateFmtYYMMDD" />month/day/year<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbDateFmtYYMMDD" pairedWith="_cbDateFmtMMDDYY,_cbDateFmtDDMMYY" />year/month/day<br><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbTimeFmt24H" pairedWith="_cbTimeFmt12H" checked />24 hour<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbTimeFmt12H" pairedWith="_cbTimeFmt24H" />12 hour<br><br>';
   uroCtrlMisc.innerHTML += '<i>Unticked uses browser default setting</i>';

   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbWhiteBackground" />Use custom background colour</b><br>';
   uroCtrlMisc.innerHTML += 'R:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundRed" />';
   uroCtrlMisc.innerHTML += 'G:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundGreen" />';
   uroCtrlMisc.innerHTML += 'B:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundBlue" /><br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Replace "Next ..." button with "Done" for:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitNURButton" />URs<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitNMPButton" />MPs<br>';
   uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitNPURButton" />PURs<br>';
   
   uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideAMLayer" />Hide Area Manager polygons</b><br>';
   uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbDisablePlacesFiltering" />Disable Places filtering</b><br>';
   ////uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbDisablePendingQuestions">Disable UR Pending Questions confirmation</input></b><br>';
   uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbDisableTabStyling" />Use default tab styling</b><br>';
   uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbHideEditorInfo" />Hide sidebar editor info</b><br>';
   uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbEnableDTE" />Drive Tab Enhancement (DTE)</b><br>';

   uroCtrlMisc.innerHTML += '<br><br><b>Settings backup/restore/reset:</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="_btnResetSettings" value="Reset" /><br><br>';
   uroCtrlMisc.innerHTML += '<textarea id="_txtSettings" value="" /><br>';
   uroCtrlMisc.innerHTML += '<input type="button" id="_btnClearSettingsText" value="Clear" /><br>';

/*
   uroCtrlMisc.innerHTML += '<br><br><b>Debug:</b><br>';
   uroCtrlMisc.innerHTML += '<input type="button" id="_btnDebugToScreen" value="Show debug data" />';
*/
   
   // 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" /><p>';

   // footer for AM list
   uroAMList.id = 'uroAMList';
   
   window.addEventListener("beforeunload", uroSaveSettings, false);

   //uroRealWazeBits();
}

function dteAddHeader()
{
   if(uroMTEMode) return;
   if(!uroInitialised) return;
   
   var 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 dteGetData()
{
   var loc = 'https://'+window.location.hostname+Waze.Config.api_base+'/Archive/MyList?minDistance=1000';
   loc += '&offset='+dteOffset+'&count=5';
   var dteReq = new XMLHttpRequest();
   dteReq.onreadystatechange = function()
   {
      var foundMissingDrive = false;
      
      if(dteReq.readyState == 4)
      {
         uroAddLog('drive data request, response '+dteReq.status+' received');
         if(dteReq.status == 200)
         {
            if(dteReq.responseText !== "")
            {
               var drives = JSON.parse(dteReq.responseText);
               var loadedDrives = drives.archives.objects.length;
               uroAddLog('received '+loadedDrives+' drives');
               if(loadedDrives != 5) foundMissingDrive = true;

               for(var loop=0; loop < loadedDrives; loop++)
               {
                  if(drives.archives.objects[loop].hasFullSession === false)
                  {
                     foundMissingDrive = true;
                  }
                  else
                  {
                     dteOffset++;
                     dteOldestFullDrive = new Date(drives.archives.objects[loop].startTime);
                  }
               }
            }
            else
            {
               foundMissingDrive = true;
            }            
         }
         if(foundMissingDrive === false)
         {
            dteGetData();
         }
         else
         {
            uroAddLog(dteOffset+' full drives in history');
            uroAddLog('oldest drives are on '+dteOldestFullDrive.toDateString());
            if(dteOffset < 5)
            {
               dteOffset = 5;
               uroAddLog('insufficient full drives, using standard drives tab');
            }
            else if(dteOffset > 50)
            {
               var nPages = Math.ceil(dteOffset / 50);
               uroAddLog('too many full drives for a single tab page, splitting over '+nPages+' pages...');
               dteOffset = Math.ceil(dteOffset/nPages);
            }

            if((dteOldestFullDrive - dteEpoch) > 0)
            {
               var totalDrives = 0;
               if(W.model.archives.additionalInfo !== null)
               {
                  totalDrives = W.model.archives.additionalInfo.totalSessions;
               }
               if(totalDrives !== null)
               {
                  uroAddLog('updating drives tab...');
                  W.map.controls[dteControlsIdx].sidePanelView.ResultsPerPage = dteOffset;
                  uroAddLog(totalDrives+' drives in history');
                  W.map.controls[dteControlsIdx].sidePanelView.setSessions(totalDrives);
                  W.map.controls[dteControlsIdx].loadSessions(0);
               }
               setInterval(dteAddHeader,250);
               setInterval(dteCheckDriveListChanges,250);
            }            
         }
      }
   };
   dteReq.open('GET',loc,true);
   dteReq.send();   

}

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

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

function dteListClick()
{
   dteClearListHighlight();
   this.style.backgroundColor = "lightgreen";
   dteArmClearHighlightsOnPanelClose = true;
}

function dteClearListHighlight()
{
   var drivesShown = document.getElementById('sidepanel-drives').getElementsByClassName('result session').length;
   if(drivesShown > 0)
   {
      for(var loop = 0;loop < drivesShown; loop++)
      {
         var listEntry = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[loop];
         listEntry.style.backgroundColor = "";
      }
   }
}

function dteCheckDriveListChanges()
{
   if(uroMTEMode) return;
   if(!uroInitialised) return;
   
   var drivesShown = document.getElementById('sidepanel-drives').getElementsByClassName('result session').length;
   if(drivesShown > 0)
   {
      var topID = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[0].getAttribute('data-id');
      if(topID != dteTopID)
      {
         dteTopID = topID;
         for(var loop = 0;loop < drivesShown; loop++)
         {
            var listEntry = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[loop];
            var driveID = listEntry.getAttribute('data-id');
            var driveObj = W.model.archives.objects[driveID];
            var driveSecs = Math.floor((driveObj.endTime - driveObj.startTime) / 1000);
            var driveHours = Math.floor(driveSecs / 3600);
            driveSecs -= (driveHours * 3600);
            var driveMins = Math.floor(driveSecs / 60);
            driveSecs -= (driveMins * 60);
            var trueTime = (driveHours+':'+("0"+driveMins).slice(-2)+'.'+("0"+driveSecs).slice(-2));
            listEntry.getElementsByTagName('span')[1].innerHTML = trueTime;
            listEntry.addEventListener("click", dteListClick, false);
         }
      }
   }
}

uroInitialise();