Index: trunk/webapps/cptms.html
===================================================================
--- trunk/webapps/cptms.html	(revision 325)
+++ trunk/webapps/cptms.html	(revision 326)
@@ -6,8 +6,10 @@
   <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
     <title>CPTMS Map v0.6.2</title> 
-    <style>
+  <!--  Styles  -->
+  <link rel="stylesheet" href="">    
+<style>
         @font-face {
           font-family: Scoreboard;
-          src: url('scoreboard.ttf');
+          src: url('js/scoreboard.ttf');
         }
       /* Set the size of the div element that contains the map */
@@ -22,4 +24,5 @@
         padding: 0;
       }
+        /* A line of the CMS message display */
         textarea {
            height: 33px;
@@ -31,4 +34,5 @@
            color: yellow;
         }
+        /* Field for entering CMS Message line */
        input {
            border: thin solid #333;
@@ -49,5 +53,4 @@
         width: 400px;
       }
-
       #search-input:focus {
         border-color: #E6E6FA; 
@@ -79,4 +82,5 @@
            float: left;
        }
+        /* CMS Dialog button panel */
        #buttonPanel {
            height: 122px;
@@ -90,4 +94,5 @@
            position: relative;\
         }
+        /* CMS Edit Message Dialog */
        #dialog {
           position: absolute;
@@ -125,4 +130,5 @@
   <body>
     <!-- 
+         Version 6.3 decomposed into modules for each layer
          Version 6.2 puts cctv and cms and vds in separate data layers.   
          Version 6.1 Puts cms messages in json formatted file.  Polls for updates.
@@ -146,7 +152,7 @@
     <!-- The text area input for the Search Box -->
     <input id="search-input" class="controls" type="text" placeholder="Search Box">
-    <!--The div element where the map appears -->
+    <!--The div element where the map appears. -->
     <div id="mapdiv"></div>
-    <!-- The div element for the popup dialog -->
+    <!-- The div element for the popup dialog. Best results when placed here. -->
     <div id="dialog" style="display:none;">
         <span class="close">&#x2612;</span>  <!-- close button symbol -->
@@ -176,9 +182,5 @@
     <button id="cmsButton" class="unstyled-button"><img id="cmsBtnImg" src="images/btnReady_CMS.png"></button>
     <button id="vdsButton" class="unstyled-button"><img id="vdsBtnImg" src="images/btnDepressed_VDS.png"></button>
-
     <script>
-//TODO:  
-// Add phase 2 to messages.
-// cms set visible gets undefined error after last icon is processed.
 
     // a global variable for the google map
@@ -188,4 +190,6 @@
     // a global variable to hold locations of marked search places
     var placePins = [];
+    // the cms message local dictionary
+    var messageDict = {}; 
     // Constant for map center location: The John Wayne Airport
     //var centerPoint = {lat: 33.687228, lng: -117.872148};
@@ -208,5 +212,5 @@
 
     var kMapPointsFile = "highways.json"; // dynamic json data file created by CADserver
-    var kMapStartupFile = "highways_startup.json"; // initial (static) highways file used once at startup
+    var kMapStartupFile = "data_layers/highways_startup.json"; // initial (static) highways file used once at startup
     var kCMSfile = "data_layers/cms_locations_D12.gjson"; // CMS locations 
     var kCCTVfile = "data_layers/cctv_locations_D12.gjson"; // CCTV locations
@@ -218,6 +222,4 @@
     var vdsIconYellow = "images/circle-yellow.png"
     var vdsIconRed = "images/circle-red.png"
-    var cms_info;
-    var messageDict = {};
     var cms_showing = false;
     var vds_showing = true;
@@ -225,551 +227,11 @@
     var cctv_infowindow; // We create just a single instance of info window.
 
-    // Build a solid colored icon to use instead of the classic pin
-    // Use a diamond on N and E directions, circle on S and W directions
-    function dotSymbol(color) //,direction)
-    {
-//        var circle = google.maps.SymbolPath.CIRCLE;
-//        var diamond = 'M -1,0 0,-1 1,0 0,1 z';
-//        var myShape = circle;
-        var iconPath = vdsIconGreen;
-        if (color == 'red')
-        {
-           iconPath = vdsIconRed;
-        }
-        else if (color == 'yellow')
-        {
-            iconPath = vdsIconYellow;
-        }
-        return {
-//            path: iconPath,
-//            icon: 
-//                    {
-                        url: iconPath, 
-                        anchor: new google.maps.Point(6, 6)
-//                    };
-//            anchor: new google.maps.Point(6, 6),
-//            scale: 5,
-//            strokeColor: "black", // the border color
-//            strokeWeight: 1, // the border thickness
-//            fillColor: color,
-//            fillOpacity: 1.0
-        };
-    }
-
-    // Load the map data from a json file and style all the points
-    function loadVDSlayer()
-    {
-        // Load the static map data and call saveCoords when done
-        map.data.loadGeoJson(kMapStartupFile, null, saveCoords)
-//        var d = new Date();
-//        var start = d.getTime();
-        // Style the map data by applying the desired properties to each feature (marker)
-        // The function will be called every time a feature's properties are updated.
-        map.data.setStyle(function(feature)
-        {
-            // Get the postmile id 
-            var name = feature.getId();
-            // Get the desired color value
-            var ptColor = feature.getProperty("color");
-            var street = feature.getProperty("street");
-            // Build the marker
-            var iconSymbol = dotSymbol(ptColor);
-            // return the StyleOptions
-            return {
-                icon: iconSymbol,
-/*                    icon: 
-                    {
-                        url: vdsIconGreen, 
-                        anchor: new google.maps.Point(6, 6)
-                    }, */
-                title: name + " @" + street, // set rollover text
-                // set zIndex for slowed traffic to a higher value so they overlap
-                zIndex: colorZvalues[ptColor]
-            };
-        });
-    }
-    // callback when load GeoJson completes
-    // save each feature's Point as the original coordinates for later reference
-    function saveCoords(features)
-    {
-        // Iterate over all the features in the map
-        features.forEach(function(feature)
-        {
-            var pt = feature.getGeometry().get();
-            vds_coords[feature.getId()] = pt; // save the Point in a dictionary
-        });
-        // update the dot colors from the dynamic json data 
-        updateVDSlayer();
-        // go adjust the marker coordinates so dots don't overlap
-        adjustCoords(calcDistanceFactor());
-    }
-
-    // magic formula controls distance between dots proportionate to zoom factor
-    function calcDistanceFactor()
-    {
-        // 15 is maximum zoom, the point at which no adjustment is needed
-        return (.0005 * (15 - map.getZoom()));
-    }
-
-    // Adjust the coordinates of dots so they appear side-by-side
-    // The perpendicular vector for each dot has been provided,
-    // so we just need to multiply by a scaling factor (adjAmount) 
-    // @param adjAmount amount by which to adjust coordinate 
-    function adjustCoords(adjAmount)
-    {
-        // Adjust the NB points a slight amount
-        map.data.forEach(function(feature)
-        {
-            // get the name of the current feature
-            var name = feature.getId();
-            // lookup the original coordinates for this feature
-            var coords = vds_coords[name];
-
-            //retrieve the perpendicular vector (precomputed)
-            var perpx = feature.getProperty("perpx")
-            var perpy = feature.getProperty("perpy")
-                // Make adjustment and save it
-            var myLat = coords.lat() + perpy * adjAmount
-            var myLong = coords.lng() + perpx * adjAmount
-            feature.setGeometry(
-            {
-                lat: myLat,
-                lng: myLong
-            });
-        });
-    }
-
-    // update the color (as needed) for a given marker
-    function updateMarker(marker)
-    {
-        target = marker.id;
-        newColor = marker.properties.color;
-        // see if new color is different than current color
-        currentFeature = map.data.getFeatureById(target);
-        currentColor = currentFeature.getProperty("color");
-        // if a new color is desired then assign it to the feature's color property
-        if (currentColor != newColor)
-        {
-            currentFeature.setProperty("color", newColor);
-            // set zIndex for slowed traffic to a higher value so they overlap
-            currentFeature.setProperty("zIndex", colorZvalues[newColor]);
-        }
-    }
-
-    // Load the dynamic json file for highways, etc.
-    // Ref: https://codepen.io/KryptoniteDove/post/load-json-file-locally-using-pure-javascript
-    function loadJSON(inFile, callback)
-    {
-        var xobj = new XMLHttpRequest();
-        xobj.overrideMimeType("application/json");
-        xobj.open('GET', inFile, true);
-        xobj.onreadystatechange = function()
-        {
-            if (xobj.readyState == 4 && xobj.status == "200")
-            {
-                callback(xobj.responseText);
-            }
-        };
-        // We want ajax to ignore any cached responses
-        xobj.setRequestHeader('If-Modified-Since', 'Sat, 01 Jan 2000 01:01:01 GMT')
-        xobj.send(null);
-    }
-    // Load the highways dynamic json file and update the map
-    function updateVDSlayer()
-    {
-        var parsed_JSON;
-        loadJSON(kMapPointsFile, function(response)
-        {
-            // Parse JSON string into object
-            parsed_JSON = JSON.parse(response);
-            // Process each new marker - lookup in current map
-            parsed_JSON.features.forEach(updateMarker);
-        });
-    }
-
-    // Initialize the center button (to re-center the map)
-    function initCenter()
-    {
-        var centerBtnDiv = document.getElementById('ctrButton');
-        map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(centerBtnDiv)
-        centerBtnDiv.title = 'Click to recenter the map';
-
-        // Setup the click event listeners: reset center location and zoom factor
-        centerBtnDiv.addEventListener('click', function()
-        {
-            map.setCenter(centerPoint);
-            map.setZoom(initZoom);
-            clearPlacePins();
-        });
-    }
-
-    // Initialize the search box and listener 
-    function initSearch()
-    {
-        // Create the search box and link it to the UI element.
-        var input = document.getElementById('search-input');
-        var searchBox = new google.maps.places.SearchBox(input);
-        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
-
-        // Bias the SearchBox results towards current map's viewport.
-        map.addListener('bounds_changed', function()
-        {
-            searchBox.setBounds(map.getBounds());
-        });
-
-        // Listen for the event fired when the user selects a prediction and retrieve
-        // more details for that place.
-        searchBox.addListener('places_changed', function()
-        {
-            var places = searchBox.getPlaces();
-
-            if (places.length == 0)
-            {
-                return;
-            }
-
-            clearPlacePins();
-
-            // Create a bounding region to include the search result places
-            var bounds = new google.maps.LatLngBounds();
-            // For each place, get the icon, name and location.
-            // There may be multiple search results
-            places.forEach(function(place)
-            {
-                if (!place.geometry)
-                {
-                    console.log("Returned place contains no geometry");
-                    return;
-                }
-
-                // Create a marker for each place.
-                placeMarker = new google.maps.Marker(
-                {
-                    map: map,
-                    title: place.name,
-                    position: place.geometry.location
-                })
-
-                // Click on the marker to remove it from the display
-                placeMarker.addListener('click', function()
-                {
-                    placeMarker.setMap(null);
-                });
-
-                // Add this marker to the collection of current markers 
-                placePins.push(placeMarker);
-
-                // Create a bounding region to include this place
-                if (place.geometry.viewport)
-                {
-                    // Only geocodes have viewport.
-                    bounds.union(place.geometry.viewport);
-                }
-                else
-                {
-                    bounds.extend(place.geometry.location);
-                }
-            });
-            // This will pan and zoom to the area around the marker
-            //map.fitBounds(bounds);
-            // This will center the map on the new marker(s) but not zoom
-            map.setCenter(bounds.getCenter());
-        });
-    }
-
-    // Remove any place pins from a previous search
-    function clearPlacePins()
-    {
-        placePins.forEach(function(marker)
-        {
-            marker.setMap(null);
-        });
-        placePins = [];
-    }
+
     // Initialize the view/hide buttons 
     function initLayerButtons()
     {
-        var cctvBtnDiv = document.getElementById('cctvButton');
-        map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(cctvBtnDiv)
-        cctvBtnDiv.title = 'Click to toggle cctv view';
-        // Setup the click event listeners to toggle icon display
-        cctvBtnDiv.addEventListener('click', function()
-        {
-            cctv_showing = !cctv_showing;
-            // reveal or hide all the icons
-            cctvLayer.forEach(function(feature)
-            {
-                cctvLayer.overrideStyle(feature,
-                {
-                    visible: cctv_showing
-                });
-            });
-            // Determine which button image to show
-            if (cctv_showing)
-            {
-                pic = "images/btnDepressed_CCTV.png"
-            }
-            else
-            {
-                pic = "images/btnReady_CCTV.png"
-            }
-            document.getElementById('cctvBtnImg').src = pic;
-        });
-
-        var cmsBtnDiv = document.getElementById('cmsButton');
-        map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(cmsBtnDiv)
-        cmsBtnDiv.title = 'Click to toggle cms view';
-        // Setup the click event listeners to toggle icon display
-        cmsBtnDiv.addEventListener('click', function()
-        {
-            cms_showing = !cms_showing;
-            // Determine which button image to show
-            if (cms_showing)
-            {
-                pic = "images/btnDepressed_CMS.png"
-                // It's nice when icons become visible that the messages have been refreshed.
-                loadAllMessages();
-            }
-            else
-            {
-                pic = "images/btnReady_CMS.png"
-            }
-            document.getElementById('cmsBtnImg').src = pic;
-            // reveal or hide all the icons
-            cmsLayer.forEach(function(feature)
-            {
-                cmsLayer.overrideStyle(feature,
-                {
-                    visible: cms_showing
-                });
-            });
-        });
-
-        var vdsBtnDiv = document.getElementById('vdsButton');
-        map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(vdsBtnDiv)
-        vdsBtnDiv.title = 'Click to toggle vds view';
-
-        // Setup the click event listeners to toggle icon display
-        vdsBtnDiv.addEventListener('click', function()
-        {
-            vds_showing = !vds_showing;
-            // reveal or hide all the dots
-            map.data.forEach(function(feature)
-            {
-                map.data.overrideStyle(feature,
-                {
-                    visible: vds_showing
-                });
-            });
-            // Determine which button image to show
-            if (vds_showing)
-            {
-                pic = "images/btnDepressed_VDS.png"
-            }
-            else
-            {
-                pic = "images/btnReady_VDS.png"
-            }
-            document.getElementById('vdsBtnImg').src = pic;
-        });
-    }
-
-function loadCMSlayer()
-{
-    cmsLayer = new google.maps.Data();
-    cmsLayer.setMap(map);
-    cmsLayer.loadGeoJson(kCMSfile);  
-    cmsLayer.setStyle(function(feature)
-    {
-        // return the StyleOptions
-        return {
-            icon: yellowFlag,
-            title: feature.getId()+ " " +feature.getProperty("location"),
-            visible: false
-        };
-    });
-    
-    cmsLayer.addListener('click', function(event)
-    {
-        var dialog = document.getElementById('dialog');
-        // Note: If the dialog is already being displayed when someone else
-        // updates the message, it won't be reflected in the dialog, until
-        // you close and reopen it.
-        dialog.style.display = 'block';
-        cmsID = event.feature.getId();
-        // Assign to the hidden field
-        document.getElementById('cmsID').value = cmsID;
-        showMessage(cmsID); // note: this is async
-        document.getElementById('cms-info-label').innerHTML = "CMS ID: " +
-            cmsID + "&nbsp;&nbsp;&nbsp;LOCATION: " + event.feature.getProperty("location");
-        // clear input fields
-        document.getElementById('msgcontent1').value = "";
-        document.getElementById('msgcontent2').value = "";
-        document.getElementById('msgcontent3').value = "";
-        document.getElementById('msgcontent1').focus();
-        var span = document.getElementsByClassName("close")[0]
-            // When the user clicks on <span> (x), close the modal
-        span.onclick = function()
-        {
-            handleDialogClose();
-        }
-    });
-}
-function makecctvIcon(nearVDS)
-{
-    var imgIcon = cctvIcon
-    if ((typeof map.data.getFeatureById(nearVDS)) == "undefined")
-    {
-        imgIcon = cctvIconWhite;
-    }
-    return imgIcon
-}
-function loadCCTVlayer()
-{
-    var imgTag = '<IMG WIDTH="700" SRC="images/';
-    cctv_infowindow = new google.maps.InfoWindow();
-    cctvLayer = new google.maps.Data();
-    cctvLayer.loadGeoJson(kCCTVfile);
-    cctvLayer.setStyle(function(feature)
-    {
-        // return the StyleOptions
-        return {
-            icon: makecctvIcon(feature.getProperty("nearVDS")),
-            title: feature.getId() + " " +feature.getProperty('locationName'),
-            visible: false  
-        };
-    });
-    cctvLayer.addListener('click', function(event)
-    {
-        //console.log("cctv layer was clicked at " + event.feature.getId());
-        cctvIndex = event.feature.getId();
-        //console.log(this.title + " is looking for " + this.nearVDS);
-        nearVDS = map.data.getFeatureById(event.feature.getProperty("nearVDS"));
-        currentColor = nearVDS.getProperty("color");
-        var imgDir = "CCTVFast/";
-        if (currentColor == "red" || currentColor == "yellow")
-        {
-            imgDir = "CCTVSlow/"
-        }
-
-        cctv_infowindow.setContent('<div style="font-weight:bold;font-family: monospace">' +  nearVDS.getId() + "&nbsp;" + currentColor + "<BR>" + imgTag + imgDir + cctvIndex + '.jpg">' + "</div>");
-        cctv_infowindow.setPosition(event.feature.getGeometry().get());
-        cctv_infowindow.open(map);
-
-    });
-    cctvLayer.setMap(map);
-}
-
-    // Center justify message text in a 16 column field
-    function justifyCMStext(message)
-    {
-        var kBlanks = "                ";
-        var padLen = (16 - message.length) / 2;
-        var padding = kBlanks.substring(0, padLen);
-        return padding + message;
-    }
-
-    function handleCMSsubmit()
-    {
-        // recover the user's response
-        var response1 = justifyCMStext(document.getElementById('msgcontent1').value.trim());
-        var response2 = justifyCMStext(document.getElementById('msgcontent2').value.trim());
-        var response3 = justifyCMStext(document.getElementById('msgcontent3').value.trim());
-        var newMsg = response1 + response2 + response3;
-        if (newMsg.length == 0)
-        {
-            alert("Nothing to Send ... Proposed is empty.");
-        }
-        else
-        {
-            document.getElementById('msgdisplay1').value = response1;
-            document.getElementById('msgdisplay2').value = response2;
-            document.getElementById('msgdisplay3').value = response3;
-            saveMessage(response1 + "|" + response2 + "|" + response3);
-        }
-    }
-
-    function handleDialogClose()
-    {
-        // hide the display
-        document.getElementById('dialog').style.display = 'none'
-    }
-
-    function handleCMSclear()
-    {
-        document.getElementById('msgdisplay1').value = "";
-        document.getElementById('msgdisplay2').value = "";
-        document.getElementById('msgdisplay3').value = "";
-        saveMessage("||");
-    }
-    // retrieve the current cms message file
-    function showMessage(cmsID)
-    {
-        loadAllMessages();  // because someone else may have made a recent update
-        // lookup the message for this cms ID
-        var message = messageDict[cmsID].cms.message;
-        // show the message in the display
-        document.getElementById('msgdisplay1').value = message.phase1.Line1;
-        document.getElementById('msgdisplay2').value = message.phase1.Line2;
-        document.getElementById('msgdisplay3').value = message.phase1.Line3;
-    }
-    function loadAllMessages()
-    {
-        loadJSON("cms_messages.json", function(response)
-        {
-            // Parse JSON string into object
-            messagejson = JSON.parse(response);
-            // Add each message to a lookup dictionary 
-            for (var i = 0; i < messagejson.data.length; i++)
-            {
-                var item = messagejson.data[i];
-                messageDict[item.cms.index] = item;
-                // Set the appropriate icon on the cms icon
-                // set a yellow flag if there's currently no message
-                if (item.cms.message.phase1.Line1 + 
-                    item.cms.message.phase1.Line2 +
-                    item.cms.message.phase1.Line3 == "")
-                {
-                    cmsLayer.overrideStyle(cmsLayer.getFeatureById(item.cms.index), {icon: yellowFlag})
-                }
-                else
-                {
-                    cmsLayer.overrideStyle(cmsLayer.getFeatureById(item.cms.index), {icon: blueFlag})
-                }
-            }
-        });
-    }
-
-    // Save an updated cms message to the file
-    function saveMessage(outMessage)
-    {
-        // Fetch cmsID from hidden field where it was put when dialog opened.
-        var cmsID = document.getElementById('cmsID').value;
-        //console.log("Saving " + outMessage + " for cmsID " + cmsID)
-        msgParts = outMessage.split("|");
-        messageDict[cmsID].cms.message.phase1.Line1 = msgParts[0];
-        messageDict[cmsID].cms.message.phase1.Line2 = msgParts[1];
-        messageDict[cmsID].cms.message.phase1.Line3 = msgParts[2];
-        // Set icon to reflect message state
-        if (outMessage == "||")
-        {
-            currentIcon = {icon: yellowFlag};
-        }
-        else
-        {
-            currentIcon = {icon: blueFlag};
-        }
-        cmsLayer.overrideStyle(cmsLayer.getFeatureById(cmsID), currentIcon)
-        outString = "{\n\t\"data\":\n\t\t" + JSON.stringify(Object.values(messageDict)) + "}";
-
-        var xhttp = new XMLHttpRequest();
-        xhttp.open("GET", "cgi-bin/saveMessage.py?msg=" + outString, true);
-        xhttp.send();
-        // Using POST might be a better idea ... haven't tried this yet
-        //      var xhr = new XMLHttpRequest();
-        //      xhr.open("POST", "/cgi-bin/saveMessage.py?", true);
-        //      xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
-        // send the collected data as JSON
-        //      xhr.send(JSON.stringify(messageList));
+        initCCTVbutton();
+        initCMSbutton();
+        initVDSbutton();
     }
 
@@ -786,14 +248,14 @@
             streetViewControl: false
         });
-        loadVDSlayer(); // go load the map data
+
         // setup the search box and center button
         initSearch();
         initCenter();
 
-loadCMSlayer();
-
-loadCCTVlayer();
-
-        initLayerButtons();
+        loadVDSlayer(); // go load the map data
+        loadCMSlayer();
+        loadCCTVlayer();
+
+        initLayerButtons(); // setup the show/hide layer buttons
 
         // Start a timer to refresh the vds dots every 10 seconds
@@ -801,5 +263,5 @@
         // start an interval timer to refresh the cms icons every 10 seconds
         var cmsTimer = setInterval(loadAllMessages, 10000);
-        // Listen for zoom changes and move the placePins so as to keep a nice
+        // Listen for zoom changes and move the vds dots so as to keep a nice
         // visual distance between them appropriate to the zoom factor
         map.addListener('zoom_changed', function()
@@ -816,89 +278,13 @@
 
     }
-    // Styles array for Night Mode map
-    // Ref: https://developers.google.com/maps/documentation/javascript/styling
-    var night_mode = [
-                {elementType: 'geometry', stylers: [{color: '#242f3e'}]},
-                {elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
-                {elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
-                {
-                  featureType: 'administrative.locality',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#d59563'}]
-                },
-                {
-                  featureType: 'poi',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#d59563'}]
-                },
-                {
-                  featureType: 'poi.park',
-                  elementType: 'geometry',
-                  stylers: [{color: '#263c3f'}]
-                },
-                {
-                  featureType: 'poi.park',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#6b9a76'}]
-                },
-                {
-                  featureType: 'road',
-                  elementType: 'geometry',
-                  stylers: [{color: '#38414e'}]
-                },
-                {
-                  featureType: 'road',
-                  elementType: 'geometry.stroke',
-                  stylers: [{color: '#212a37'}]
-                },
-                {
-                  featureType: 'road',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#9ca5b3'}]
-                },
-                {
-                  featureType: 'road.highway',
-                  elementType: 'geometry',
-                  stylers: [{color: '#746855'}]
-                },
-                {
-                  featureType: 'road.highway',
-                  elementType: 'geometry.stroke',
-                  stylers: [{color: '#1f2835'}]
-                },
-                {
-                  featureType: 'road.highway',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#f3d19c'}]
-                },
-                {
-                  featureType: 'transit',
-                  elementType: 'geometry',
-                  stylers: [{color: '#2f3948'}]
-                },
-                {
-                  featureType: 'transit.station',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#d59563'}]
-                },
-                {
-                  featureType: 'water',
-                  elementType: 'geometry',
-                  stylers: [{color: '#17263c'}]
-                },
-                {
-                  featureType: 'water',
-                  elementType: 'labels.text.fill',
-                  stylers: [{color: '#515c6d'}]
-                },
-                {
-                  featureType: 'water',
-                  elementType: 'labels.text.stroke',
-                  stylers: [{color: '#17263c'}]
-                }
-              ]
-
-    // Using John's API Key
+
     </script>
+    <script  src="js/common.js"></script>
+    <script  src="js/vdsLayer.js"></script>
+    <script  src="js/cmsLayer.js"></script>
+    <script  src="js/cctvLayer.js"></script>
+    <script  src="js/controls.js"></script>
+    <script  src="js/night_mode.js"></script>
+    <!-- Using John's API Key -->
     <script async defer
     src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD6iTyN0DjP-9OVkAgicyp4tkC10naE_B8&libraries=places&callback=initMap">
