2025-07-18 14:49:10 +02:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<link rel="stylesheet" href="./css/style.css" />
|
|
|
|
|
<link rel="stylesheet" href="./lib/css/beer.css" />
|
|
|
|
|
<link rel="stylesheet" href="./lib/css/leaflet.css" />
|
|
|
|
|
<link rel="stylesheet" href="./lib/css/MarkerCluster.css" />
|
|
|
|
|
<link rel="stylesheet" href="./lib/css/MarkerCluster.Default.css" />
|
|
|
|
|
<script src="./lib/beer.min.js" type="module"></script>
|
|
|
|
|
<script src="./lib/leaflet.js"></script>
|
|
|
|
|
<script src="./lib/leaflet.markercluster.js"></script>
|
|
|
|
|
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
|
|
|
|
|
<title>MeshCore Node Map</title>
|
|
|
|
|
</head>
|
|
|
|
|
<body class="light">
|
|
|
|
|
<div class="container">
|
|
|
|
|
<div id="map"></div>
|
2026-01-18 16:04:46 +01:00
|
|
|
<div id="app" v-cloak>
|
|
|
|
|
<div class="loading" v-if="app.loading"></div>
|
|
|
|
|
<a class="manual-add square round light-blue extra" title="Add node to map" target="_blank" href="https://github.com/meshcore-dev/MeshCore/blob/main/docs/faq.md#512-q-how-do-i-add-a-node-to-the-meshcore-map"><i class="extra">add</i></a>
|
2025-07-18 14:49:10 +02:00
|
|
|
<div class="stats">
|
|
|
|
|
<span title="Stats">
|
|
|
|
|
<i>monitoring</i>
|
|
|
|
|
</span>
|
|
|
|
|
<span v-for="stat in stats" v-html="stat"></span>
|
2025-07-18 16:55:13 +02:00
|
|
|
<span style="flex-grow: 1"></span>
|
|
|
|
|
<a href="https://github.com/recrof/map.meshcore.dev" class="github" title="go to github repo" target="_blank">
|
|
|
|
|
<img src="./lib/images/github-mark.svg">
|
|
|
|
|
</a>
|
2025-07-18 14:49:10 +02:00
|
|
|
</a>
|
|
|
|
|
</div>
|
2026-03-27 18:12:00 +01:00
|
|
|
<form class="search no-margin" data-ui action="javascript:;">
|
|
|
|
|
<menu class="left no-wrap" id="node-filter">
|
2026-01-18 16:04:46 +01:00
|
|
|
<li>
|
|
|
|
|
<label class="checkbox">
|
|
|
|
|
<input type="checkbox" value="1" v-model="app.nodeFilter"><span>Clients</span>
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<label class="checkbox">
|
|
|
|
|
<input type="checkbox" value="2" v-model="app.nodeFilter"><span>Repeaters</span>
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<label class="checkbox">
|
|
|
|
|
<input type="checkbox" value="3" v-model="app.nodeFilter"><span>Room Servers</span>
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<label class="checkbox">
|
|
|
|
|
<input type="checkbox" value="4" v-model="app.nodeFilter"><span>Sensors</span>
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
|
|
|
|
<!--li v-if="app.presets.length > 0">
|
|
|
|
|
<label class="select">
|
|
|
|
|
<select v-model="app.presetIndex">
|
|
|
|
|
<option v-for="(preset, i) of app.presets" :value="i">{{ preset.name }}</option>
|
|
|
|
|
</select>
|
|
|
|
|
</label>
|
|
|
|
|
</li-->
|
2026-03-06 16:56:03 +01:00
|
|
|
<li>
|
2026-01-18 16:04:46 +01:00
|
|
|
<div class="field label prefix fill small">
|
|
|
|
|
<i>today</i>
|
|
|
|
|
<input type="date" v-model="app.fromDate" placeholder=" ">
|
|
|
|
|
<label>Last updated</label>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
2026-03-06 16:56:03 +01:00
|
|
|
<li>
|
|
|
|
|
<div class="field label prefix fill small">
|
|
|
|
|
<i>today</i>
|
|
|
|
|
<input type="date" v-model="app.fromInsertDate" placeholder=" ">
|
|
|
|
|
<label>Inserted</label>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
2026-01-18 16:04:46 +01:00
|
|
|
<li style="flex-direction:column;gap:0">
|
|
|
|
|
<span>Clustering zoom level</span>
|
|
|
|
|
<label class="slider tiny">
|
|
|
|
|
<input min="10" max="17" type="range" v-model="app.clusteringZoom">
|
|
|
|
|
<span></span>
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
2026-03-27 18:12:00 +01:00
|
|
|
<li v-if="app.availableFreqs.length > 0" style="flex-direction:column;gap:4px">
|
|
|
|
|
<span>Frequency</span>
|
|
|
|
|
<label class="checkbox" v-for="freq in app.availableFreqs" :key="freq">
|
|
|
|
|
<input type="checkbox" :value="freq" v-model="app.freqFilter">
|
|
|
|
|
<span>{{ freq }} MHz</span>
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
2026-01-18 16:04:46 +01:00
|
|
|
<li v-if="filtersActive">
|
|
|
|
|
<button class="small max" @click="clearFilters">Clear filters</button>
|
|
|
|
|
</li>
|
|
|
|
|
</menu>
|
2025-07-18 14:49:10 +02:00
|
|
|
<div class="field border no-margin">
|
2026-01-18 16:04:46 +01:00
|
|
|
<input type="text" class="background" list="nodes" v-model="app.search" placeholder="Search Nodes" v-if="app.nodes">
|
|
|
|
|
<button type="button" class="filter" :class="{ circle: !filtersActive, transparent: !filtersActive, 'error-container': filtersActive }" data-ui="#node-filter">
|
2025-07-18 14:49:10 +02:00
|
|
|
<i>filter_alt</i>
|
2026-01-18 16:04:46 +01:00
|
|
|
<span v-if="filtersActive">Filters active</span>
|
2025-07-18 14:49:10 +02:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<article class="search-results no-margin no-padding" v-if="searchResults?.length > 0">
|
|
|
|
|
<ul class="list no-space border">
|
|
|
|
|
<li v-for="node in searchResults" tabindex="0" @click="showNode(node)" @keyup.enter="showNode(node)">
|
|
|
|
|
<img :src="`./img/node_types/${node.type}.svg`" width="32">
|
|
|
|
|
<div class="max search-text">
|
|
|
|
|
<h6 class="small" v-html="highlightString(node.adv_name, app.search)"></h6>
|
|
|
|
|
<div class="search-pkey" v-html="highlightString(node.public_key, app.search)"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</article>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
<script type="module" src="./src/map.js"></script>
|
|
|
|
|
</html>
|