Add embedded example

This commit is contained in:
Dave Conway-Jones 2016-11-22 08:21:56 +00:00
parent e1cc6209bf
commit bf2aad4bf6
6 changed files with 250 additions and 43 deletions

View File

@ -7,6 +7,7 @@ map web page for plotting "things" on.
![Map Image](https://dceejay.github.io/pages/images/redmap.png) ![Map Image](https://dceejay.github.io/pages/images/redmap.png)
### Changes ### Changes
- v1.0.22 - Add example how to embed into Node-RED-Dashboard template.
- v1.0.21 - If you specify range and icon then you get a marker and a range circle, if you just specify range with no icon, you just get a circle, and vice versa. - v1.0.21 - If you specify range and icon then you get a marker and a range circle, if you just specify range with no icon, you just get a circle, and vice versa.
- v1.0.20 - Add buildings overlay. - v1.0.20 - Add buildings overlay.
- v1.0.19 - Add circle mode - specify name, lat, lon and radius. - v1.0.19 - Add circle mode - specify name, lat, lon and radius.

View File

@ -0,0 +1,158 @@
[
{
"id": "104f9b89.5daf04",
"type": "worldmap",
"z": "5ab56e5e.449a5",
"name": "",
"lat": "",
"lon": "",
"zoom": "",
"layer": "OSM",
"cluster": "",
"maxage": "",
"usermenu": "hide",
"panit": "true",
"x": 490,
"y": 280,
"wires": []
},
{
"id": "7892d55a.40864c",
"type": "inject",
"z": "5ab56e5e.449a5",
"name": "",
"topic": "",
"payload": "",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 130,
"y": 220,
"wires": [
[
"45dc04c5.811fcc"
]
]
},
{
"id": "45dc04c5.811fcc",
"type": "function",
"z": "5ab56e5e.449a5",
"name": "",
"func": "// create random position\nvar lat = 51 + Math.random() * 0.2;\nvar lon = -1.45 + Math.random() * 0.2;\nmsg.payload={lat:lat, lon:lon, name:\"Mike\", icon:\"male\", url:\"<a href=\\\"/red/ui/#/0\\\">IBM link</a>\"};\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 310,
"y": 280,
"wires": [
[
"104f9b89.5daf04"
]
]
},
{
"id": "39ae2a4d.5a6f06",
"type": "inject",
"z": "5ab56e5e.449a5",
"name": "",
"topic": "",
"payload": "/red/worldmap",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": true,
"x": 140,
"y": 340,
"wires": [
[
"a8660ccf.d7166"
]
]
},
{
"id": "be72c0ae.5925b",
"type": "ui_template",
"z": "5ab56e5e.449a5",
"group": "c60f4e05.ebb48",
"name": "",
"order": 0,
"width": "6",
"height": "6",
"format": "<div ng-bind-html=\"msg.payload | trusted\"></div>",
"storeOutMessages": true,
"fwdInMessages": true,
"x": 480,
"y": 340,
"wires": [
[]
]
},
{
"id": "a8660ccf.d7166",
"type": "template",
"z": "5ab56e5e.449a5",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "<iframe src={{{payload}}} height=300px ></iframe>",
"x": 310,
"y": 340,
"wires": [
[
"be72c0ae.5925b"
]
]
},
{
"id": "79411e5e.1af57",
"type": "ui_button",
"z": "5ab56e5e.449a5",
"name": "",
"group": "c60f4e05.ebb48",
"order": 0,
"width": 0,
"height": 0,
"label": "Move Mike",
"color": "",
"icon": "fa-male",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 130,
"y": 280,
"wires": [
[
"45dc04c5.811fcc"
]
]
},
{
"id": "235ad210.492b0e",
"type": "comment",
"z": "5ab56e5e.449a5",
"name": "How to embed Map in Dashboard",
"info": "This example shows how to embed the Worldmap \ninto a template node within the `node-red-dashboard`\n\nThe first flow creates a dashboard button that \ngenerates a randon position, with the required \nicon, and passes that to the worldmap. The\nmap is configured to automatically pan to the\nposition of any point that arrives.\n\nThe second flow initialise the dashboard template\nwith the initial map and sets it to a more square shape\nby adjusting the height.",
"x": 180,
"y": 160,
"wires": []
},
{
"id": "c60f4e05.ebb48",
"type": "ui_group",
"z": "5ab56e5e.449a5",
"name": "Default",
"tab": "6a3aec18.0bc474",
"disp": true,
"width": "6"
},
{
"id": "6a3aec18.0bc474",
"type": "ui_tab",
"z": "5ab56e5e.449a5",
"name": "Home",
"icon": "dashboard"
}
]

View File

@ -43,11 +43,22 @@
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-cluster"><i class="fa fa-gears"></i> Cluster at</label> <label for="node-input-cluster"><i class="fa fa-gears"></i> Cluster at</label>
zoom levels less than <input type="text" id="node-input-cluster" placeholder="10 (0-19)" style="width:60px;"> zoom levels less than <input type="text" id="node-input-cluster" placeholder="10 (0-19)" style="width:70px;">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-maxage"><i class="fa fa-timer"></i> Max age</label> <label for="node-input-maxage"><i class="fa fa-clock-o"></i> Max age</label>
Remove markers after <input type="text" id="node-input-maxage" style="width:60px;"> seconds Remove markers after <input type="text" id="node-input-maxage" style="width:67px;"> seconds
</div>
<div class="form-row">
<label for="node-input-usermenu"><i class="fa fa-user"></i> User Menu</label>
<select id="node-input-usermenu" style="width:70px;">
<option value="show">Show</option>
<option value="hide">Hide</option>
</select>
<i class="fa fa-arrows-alt" style="margin-left:50px"></i> Auto-pan <select id="node-input-panit" style="width:70px;">
<option value="false">False</option>
<option value="true">True</option>
</select>
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-name"><i class="fa fa-file"></i> Name</label> <label for="node-input-name"><i class="fa fa-file"></i> Name</label>
@ -84,13 +95,15 @@
category: 'location', category: 'location',
color:"darksalmon", color:"darksalmon",
defaults: { defaults: {
name: {value:""},
lat: {value:""}, lat: {value:""},
lon: {value:""}, lon: {value:""},
zoom: {value:""}, zoom: {value:""},
layer: {value:""}, layer: {value:""},
cluster: {value:""}, cluster: {value:""},
maxage: {value:""}, maxage: {value:""},
name: {value:""} usermenu: {value:"show"},
panit: {value:"false"}
}, },
inputs:1, inputs:1,
outputs:0, outputs:0,

View File

@ -29,6 +29,8 @@ module.exports = function(RED) {
this.layer = n.layer || ""; this.layer = n.layer || "";
this.cluster = n.cluster || ""; this.cluster = n.cluster || "";
this.maxage = n.maxage || ""; this.maxage = n.maxage || "";
this.showmenu = n.usermenu || "show";
this.panit = n.panit || "false";
var node = this; var node = this;
//node.log("Serving map from "+__dirname+" as "+RED.settings.httpNodeRoot.slice(0,-1)+"/worldmap"); //node.log("Serving map from "+__dirname+" as "+RED.settings.httpNodeRoot.slice(0,-1)+"/worldmap");
RED.httpNode.use("/worldmap", express.static(__dirname + '/worldmap')); RED.httpNode.use("/worldmap", express.static(__dirname + '/worldmap'));
@ -49,6 +51,8 @@ module.exports = function(RED) {
if (node.layer && node.layer.length > 0) { c.layer = node.layer; } if (node.layer && node.layer.length > 0) { c.layer = node.layer; }
if (node.cluster && node.cluster.length > 0) { c.cluster = node.cluster; } if (node.cluster && node.cluster.length > 0) { c.cluster = node.cluster; }
if (node.maxage && node.maxage.length > 0) { c.maxage = node.maxage; } if (node.maxage && node.maxage.length > 0) { c.maxage = node.maxage; }
c.showmenu = node.showmenu;
c.panit = node.panit;
client.emit("worldmapdata",{command:c}); client.emit("worldmapdata",{command:c});
} }
}); });
@ -57,14 +61,11 @@ module.exports = function(RED) {
node.status({fill:"green",shape:"ring",text:"connected "+socket.engine.clientsCount}); node.status({fill:"green",shape:"ring",text:"connected "+socket.engine.clientsCount});
}); });
node.on("close", function() { node.on("close", function() {
node.status({});
client.disconnect(true); client.disconnect(true);
}); });
} }
node.status({});
node.on("close", function() {
node.status({});
//socket.close();
});
socket.on('connection', callback); socket.on('connection', callback);
} }
RED.nodes.registerType("worldmap",WorldMap); RED.nodes.registerType("worldmap",WorldMap);

View File

@ -77,7 +77,7 @@
<tr><td style="cursor:default"><span id="showHelp" ><i class="fa fa-info fa-lg fa-fw"></i>Help</span></td></tr> <tr><td style="cursor:default"><span id="showHelp" ><i class="fa fa-info fa-lg fa-fw"></i>Help</span></td></tr>
</table></div> </table></div>
<div id="map"></div> <div id="map"></div>
<div id="foot">&nbsp;&copy; IBM 2015,2016</div> <div id="foot"></div>
<!-- <div id="heat"><button type="button" onclick="clearHeat();">Clear Heatmap</button></div> --> <!-- <div id="heat"><button type="button" onclick="clearHeat();">Clear Heatmap</button></div> -->
<dialog id="helpWindow"> <dialog id="helpWindow">
@ -120,25 +120,33 @@ var maxage = 600; // default max age of icons on map in seconds - cleared afte
var baselayername = "OSM grey"; // Default base layer OSM but uniform grey var baselayername = "OSM grey"; // Default base layer OSM but uniform grey
var ibmfoot = "&nbsp;&copy; IBM 2015,2016" var ibmfoot = "&nbsp;&copy; IBM 2015,2016"
var initialposition = false; var initialposition = false;
var inIframe = false;
var showUserMenu = true;
// Create the socket // Create the socket
var ws = io(); var ws = io();
ws.on('connect', function() { ws.on('connect', function() {
console.log("CONNECTED"); console.log("CONNECTED");
document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>"; if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
}
ws.emit("worldmap",{action:"connected"}); ws.emit("worldmap",{action:"connected"});
}); });
ws.on('disconnect', function() { ws.on('disconnect', function() {
console.log("DISCONNECTED"); console.log("DISCONNECTED");
document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>"; if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
}
setTimeout(function() { ws.connect(); }, 2500); setTimeout(function() { ws.connect(); }, 2500);
}); });
ws.on('error', function() { ws.on('error', function() {
console.log("ERROR"); console.log("ERROR");
document.getElementById("foot").innerHTML = "<font color='#C00'>"+ibmfoot+"</font>"; if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#C00'>"+ibmfoot+"</font>";
}
setTimeout(function() { ws.connect(); }, 2500); setTimeout(function() { ws.connect(); }, 2500);
}); });
@ -171,6 +179,7 @@ map = new L.map('map').setView(startpos, startzoom);
// Move some bits around if in an iframe // Move some bits around if in an iframe
if (window.self !== window.top) { if (window.self !== window.top) {
console.log("IN an iframe"); console.log("IN an iframe");
inIframe = true;
(document.getElementById("topbar").style.display="none"); (document.getElementById("topbar").style.display="none");
(document.getElementById("map").style.top="0px"); (document.getElementById("map").style.top="0px");
(document.getElementById("results").style.right="50px"); (document.getElementById("results").style.right="50px");
@ -181,36 +190,43 @@ if (window.self !== window.top) {
(document.getElementById("bars").style.display="none"); (document.getElementById("bars").style.display="none");
(document.getElementById("menu").style.right="8px"); (document.getElementById("menu").style.right="8px");
(document.getElementById("menu").style.borderRadius="6px"); (document.getElementById("menu").style.borderRadius="6px");
L.easyButton( 'fa-bars fa-lg', function() { toggleMenu(); }, "Toggle menu", "topright").addTo(map); if (showUserMenu) {
var menuButton = L.easyButton( 'fa-bars fa-lg', function() { toggleMenu(); }, "Toggle menu", "topright").addTo(map);
}
} }
else { else {
console.log("NOT in an iframe") console.log("NOT in an iframe")
window.onbeforeunload = function(e) { window.onbeforeunload = function(e) {
return 'Reloading will delete all the local markers, including any drawing on the "drawing" layer'; return 'Reloading will delete all the local markers, including any drawing on the "drawing" layer';
}; };
if (!showUserMenu) {
document.getElementById("bars").style.display="none";
}
} }
// Add the fullscreen button if (!inIframe) {
L.control.fullscreen().addTo(map); // Add the fullscreen button
L.control.fullscreen().addTo(map);
// map.on('fullscreenchange', function () { // map.on('fullscreenchange', function () {
// if (map.isFullscreen()) { console.log('entered fullscreen') } // if (map.isFullscreen()) { console.log('entered fullscreen') }
// else { console.log('exited fullscreen'); } // else { console.log('exited fullscreen'); }
// }); // });
// Add the locate my position button // Add the locate my position button
L.easyButton( 'fa-crosshairs fa-lg', function() { L.easyButton( 'fa-crosshairs fa-lg', function() {
map.locate({setView:true, maxZoom:16}); map.locate({setView:true, maxZoom:16});
}, "Locate me").addTo(map); }, "Locate me").addTo(map);
// Add the measure/ruler button // Add the measure/ruler button
L.Control.measureControl().addTo(map); L.Control.measureControl().addTo(map);
// Create the clear heatmap button // Create the clear heatmap button
var clrHeat = L.easyButton( '<b>Reset Heatmap</b>', function() { var clrHeat = L.easyButton( '<b>Reset Heatmap</b>', function() {
console.log("reset heatmap"); console.log("reset heatmap");
heat.setLatLngs([]); heat.setLatLngs([]);
}, "Clears the current heatmap", "bottomright"); }, "Clears the current heatmap", "bottomright");
}
// Handle the dialog for popup help // Handle the dialog for popup help
var dialog = document.querySelector('dialog'); var dialog = document.querySelector('dialog');
@ -511,30 +527,30 @@ basemaps["OSM"] = osm;
// Extra Leaflet map layers from http://leaflet-extras.github.io/leaflet-providers/preview/ // Extra Leaflet map layers from http://leaflet-extras.github.io/leaflet-providers/preview/
var Esri_WorldStreetMap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', { var Esri_WorldStreetMap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' attribution: 'Tiles &copy; Esri'
}); });
basemaps["Esri"] = Esri_WorldStreetMap; basemaps["Esri"] = Esri_WorldStreetMap;
var Esri_WorldImagery = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { var Esri_WorldImagery = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' attribution: 'Tiles &copy; Esri'
}); });
basemaps["Esri Satellite"] = Esri_WorldImagery; basemaps["Esri Satellite"] = Esri_WorldImagery;
var Esri_WorldShadedRelief = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', { var Esri_WorldShadedRelief = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri', attribution: 'Tiles &copy; Esri',
maxNativeZoom: 13 maxNativeZoom: 13
}); });
basemaps["Esri Terrain"] = Esri_WorldShadedRelief; basemaps["Esri Terrain"] = Esri_WorldShadedRelief;
var Esri_OceanBasemap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', { var Esri_OceanBasemap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri', attribution: 'Tiles &copy; Esri',
maxNativeZoom: 10 maxNativeZoom: 10
}); });
basemaps["Esri Ocean"] = Esri_OceanBasemap; basemaps["Esri Ocean"] = Esri_OceanBasemap;
var OpenMapSurfer_Roads = L.tileLayer('http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}', { var OpenMapSurfer_Roads = L.tileLayer('http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}', {
maxZoom: 18, maxZoom: 18,
attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">University of Heidelberg</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}); });
basemaps["Mapsurfer"] = OpenMapSurfer_Roads; basemaps["Mapsurfer"] = OpenMapSurfer_Roads;
@ -548,7 +564,7 @@ basemaps["Mapsurfer"] = OpenMapSurfer_Roads;
//basemaps["MapQuest OSM"] = MapQuestOpen_OSM; //basemaps["MapQuest OSM"] = MapQuestOpen_OSM;
var Esri_NatGeoWorldMap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', { var Esri_NatGeoWorldMap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC', attribution: 'Tiles &copy; Esri',
maxNativeZoom: 12 maxNativeZoom: 12
}); });
basemaps["Nat Geo"] = Esri_NatGeoWorldMap; basemaps["Nat Geo"] = Esri_NatGeoWorldMap;
@ -563,7 +579,7 @@ var NLS_OS_opendata = L.tileLayer('http://geo.nls.uk/maps/opendata/{z}/{x}/{y}.p
basemaps["UK OS Opendata"] = NLS_OS_opendata; basemaps["UK OS Opendata"] = NLS_OS_opendata;
var NLS_OS_1919_1947 = L.tileLayer( 'http://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', { var NLS_OS_1919_1947 = L.tileLayer( 'http://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
attribution: 'Historical Maps Layer, 1919-1947 from the <a href="http://maps.nls.uk/projects/api/">NLS Maps API</a>', attribution: 'Historical Maps Layer, from <a href="http://maps.nls.uk/projects/api/">NLS Maps</a>',
bounds: [[49.6, -12], [61.7, 3]], bounds: [[49.6, -12], [61.7, 3]],
minZoom: 1, minZoom: 1,
maxZoom: 18, maxZoom: 18,
@ -635,7 +651,7 @@ map.on('draw:created', function (e) {
overlays["roads"] = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', { overlays["roads"] = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
type: 'hyb', type: 'hyb',
ext: 'png', ext: 'png',
attribution: 'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>', attribution: '<a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
subdomains: '1234', subdomains: '1234',
opacity: 0.9 opacity: 0.9
}); });
@ -671,7 +687,9 @@ if ( window.localStorage.hasOwnProperty("lastlayer") ) {
basemaps[baselayername].addTo(map); basemaps[baselayername].addTo(map);
// Add the layers control widget // Add the layers control widget
var layercontrol = L.control.layers(basemaps, overlays).addTo(map); if (!inIframe) {
var layercontrol = L.control.layers(basemaps, overlays).addTo(map);
}
// Layer control based on select box rather than radio buttons. // Layer control based on select box rather than radio buttons.
//var layercontrol = L.control.selectLayers(basemaps, overlays).addTo(map); //var layercontrol = L.control.selectLayers(basemaps, overlays).addTo(map);
@ -693,7 +711,7 @@ var delMarker = function(dname) {
// the MAIN add something to map function // the MAIN add something to map function
function setMarker(data) { function setMarker(data) {
//console.log(typeof data, data); console.log(typeof data, data);
var ll; var ll;
var stay = popped; var stay = popped;
@ -707,7 +725,9 @@ function setMarker(data) {
//zoomToBoundsOnClick:false //zoomToBoundsOnClick:false
}).addTo(map); }).addTo(map);
overlays[lay] = layers[lay]; overlays[lay] = layers[lay];
layercontrol.addOverlay(layers[lay],lay); if (!inIframe) {
layercontrol.addOverlay(layers[lay],lay);
}
} }
if (typeof markers[data.name] != "undefined") { layers[lay].removeLayer(markers[data.name]); } if (typeof markers[data.name] != "undefined") { layers[lay].removeLayer(markers[data.name]); }
@ -927,6 +947,20 @@ function doCommand(cmd) {
if (cmd.hasOwnProperty("init") && initialposition) { if (cmd.hasOwnProperty("init") && initialposition) {
return; return;
} }
if (cmd.hasOwnProperty("panit")) {
if (cmd.panit === "true") { panit = true; }
else { panit = false; }
}
if (cmd.hasOwnProperty("showmenu")) {
if ((cmd.showmenu === "hide") && (showUserMenu === true)) {
showUserMenu = false;
map.removeControl(menuButton);
}
else if ((cmd.showmenu === "show") && (showUserMenu === false)) {
showUserMenu = true;
map.addControl(menuButton);
}
}
var existsalready = false; var existsalready = false;
// Add a new base map layer // Add a new base map layer
if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) { if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {

View File

@ -1,5 +1,5 @@
CACHE MANIFEST CACHE MANIFEST
# date: Nov 11th v1.0.21 # date: Nov 22nd v1.0.22
CACHE: CACHE:
index.html index.html