diff --git a/.gitignore b/.gitignore
index 25ab2bc..1708808 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,7 @@
*.swp
*.pyc
*.log
-js/mobile.js
-js/init_plot.js
-css/mobile.css
-cache.manifest
+/index.html
+/service-worker.js
+/js/version.json
tiles/
diff --git a/.htaccess b/.htaccess
deleted file mode 100644
index 3d763d3..0000000
--- a/.htaccess
+++ /dev/null
@@ -1,38 +0,0 @@
-
- # Compress HTML, CSS, JavaScript, Text, XML and fonts
- AddOutputFilterByType DEFLATE application/javascript
- AddOutputFilterByType DEFLATE application/rss+xml
- AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
- AddOutputFilterByType DEFLATE application/x-font
- AddOutputFilterByType DEFLATE application/x-font-opentype
- AddOutputFilterByType DEFLATE application/x-font-otf
- AddOutputFilterByType DEFLATE application/x-font-truetype
- AddOutputFilterByType DEFLATE application/x-font-ttf
- AddOutputFilterByType DEFLATE application/x-javascript
- AddOutputFilterByType DEFLATE application/xhtml+xml
- AddOutputFilterByType DEFLATE application/xml
- AddOutputFilterByType DEFLATE font/opentype
- AddOutputFilterByType DEFLATE font/otf
- AddOutputFilterByType DEFLATE font/ttf
- AddOutputFilterByType DEFLATE image/svg+xml
- AddOutputFilterByType DEFLATE image/x-icon
- AddOutputFilterByType DEFLATE text/css
- AddOutputFilterByType DEFLATE text/html
- AddOutputFilterByType DEFLATE text/javascript
- AddOutputFilterByType DEFLATE text/plain
- AddOutputFilterByType DEFLATE text/xml
-
- # Remove browser bugs (only needed for ancient browsers)
- BrowserMatch ^Mozilla/4 gzip-only-text/html
- BrowserMatch ^Mozilla/4\.0[678] no-gzip
- BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
- Header append Vary User-Agent
-
-
-AddType text/cache-manifest .manifest
-AddType text/cache-manifest .appcache
-
-AddType application/x-font-woff .woff
-AddType application/x-font-ttf .ttf
-AddType application/vnd.ms-fontobject .eot
-AddType image/svg+xml .svg
diff --git a/DEVELOPER_README.md b/DEVELOPER_README.md
index 3272308..6f38d04 100644
--- a/DEVELOPER_README.md
+++ b/DEVELOPER_README.md
@@ -4,6 +4,6 @@ To get a copy of the code and run a test web server:
1. [Fork the repository](https://github.com/projecthorus/sondehub-tracker/fork) by visiting [https://github.com/projecthorus/sondehub-tracker/fork](https://github.com/projecthorus/sondehub-tracker/fork).
2. Clone the repository with your git tool of choice.
-3. Run `build.sh` to compile the javascript files. (This requires Java to be installed and in your path.)
+3. Run `build.sh` to generate `index.html`, `service-worker.js`, and `js/version.json`.
4. Run `python serve.py` to run a simple web server to (This requires python 3.x)
5. Visit [http://localhost:8000](http://localhost:8000) to view the local version of the server!
diff --git a/Dockerfile b/Dockerfile
index fbb1bdb..53107d5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
FROM alpine:latest
-RUN apk add --no-cache python3 openjdk11 sed git
+RUN apk add --no-cache python3 sed git
WORKDIR /app
ADD . .
diff --git a/README.md b/README.md
index ce5a68a..42427be 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ A fork of [habitat-mobile-tracker](https://github.com/rossengeorgiev/habitat-mob

A webapp for tracking radiosondes. Works an desktop and mobile devices.
-The SondeHub tracker is a continuation of [spacenear.us/tracker](http://spacenear.us/tracker).
+The SondeHub tracker is a continuation of the [HabHub Tracker](http://tracker.habhub.org).
## Features
@@ -36,8 +36,6 @@ Pull requests are welcome.
## Installation
-Requirements: Java
-
$ git clone https://github.com/projecthorus/sondehub-tracker.git
$ ./build.sh
$ python serve.py
diff --git a/build.sh b/build.sh
index fd6e6d2..948cde1 100755
--- a/build.sh
+++ b/build.sh
@@ -1,45 +1,22 @@
#!/bin/bash
-# compile stylesheet
-echo -n "Compiling CSS... "
-cd css
-rm -f mobile.css
-cat base.css skeleton.css layout.css habitat-font.css main.css leaflet.css leaflet.fullscreen.css skewt.css > mobile.tmp
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=css mobile.tmp > mobile.css
-rm -f mobile.tmp
-cd ..
-echo "Done!"
-
-#compile javascript
-echo -n "Compiling JavaScript... "
-cd js
-rm -f mobile.js init_plot.js
-# precompiled libs
-cat jquery* >> mobile.js
+set -e
VERSION="`git rev-parse --short HEAD`"
+BUILD_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"
-# compile the rest
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge iscroll.js >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge chasecar.lib.js | sed "s/{VER}/$VERSION/" >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge tracker.js >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge app.js >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge colour-map.js >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge xdata.js >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge station.js >> mobile.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge format.js >> mobile.js
-
-#compile plot lib and config
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge _jquery.flot.js >> init_plot.js
-java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge plot_config.js >> init_plot.js
-
-cd ..
+# create version check file
+echo -n "Generating js/version.json... "
+echo "{\"build_date\": \"$BUILD_DATE\", \"version\": \"$VERSION\", \"refresh\": 86400}" > js/version.json
echo "Done!"
-echo -n "Generate cache.manifest..."
-
-sed "s/^\(# version\) .*$/\1 $VERSION `date +%s`/" cache.manifest-dev > cache.manifest
+# cache fixes
+echo -n "Generating index.html... "
+sed -e "s/{VER}/$VERSION/" -e "s/{BUILD_DATE}/$BUILD_DATE/" index.template.html > index.html
+echo "Done!"
+echo -n "Generating service-worker.js... "
+sed -e "s/{VER}/$VERSION/" service-worker.template.js > service-worker.js
echo "Done!"
-echo "Build version: $VERSION"
+echo "Build version: $VERSION Build date: $BUILD_DATE"
diff --git a/cache.manifest-dev b/cache.manifest-dev
deleted file mode 100644
index 701d56c..0000000
--- a/cache.manifest-dev
+++ /dev/null
@@ -1,75 +0,0 @@
-CACHE MANIFEST
-# version {VERSION}
-
-# gogole maps files
-http://maps.google.com/maps/api/js?v=3.22&sensor=false&libraries=map,common,controls,util,marker,onion,kml,ga,infowindow,stats,poly,overlay,weather,weather_impl,geometry&language=en_us&key=AIzaSyCOqkcNey4CCyG4X0X5qxHAhCgD8g5DwXg
-http://fonts.googleapis.com/css?family=Roboto:300,400,500,700
-http://maps.gstatic.com/mapfiles/undo_poly.png
-http://maps.gstatic.com/mapfiles/mv/imgs8.png
-http://maps.gstatic.com/mapfiles/transparent.png
-http://maps.gstatic.com/mapfiles/api-3/images/mapcnt3.png
-http://maps.gstatic.com/mapfiles/api-3/images/google_white2_hdpi.png
-http://maps.gstatic.com/mapfiles/api-3/images/google_white2.png
-http://maps.gstatic.com/mapfiles/openhand_8_8.cur
-
-# app files
-img/closedhand.cur
-img/openhand.cur
-img/logo.png
-img/blank.png
-img/marker-you.png
-img/apple-touch-icon.png
-img/markers/hab_nyan.gif
-img/markers/nyan.gif
-img/markers/antenna-green.png
-img/markers/balloon-red.png
-img/markers/balloon-blue.png
-img/markers/balloon-green.png
-img/markers/balloon-purple.png
-img/markers/balloon-cyan.png
-img/markers/balloon-orange.png
-img/markers/balloon-yellow.png
-img/markers/balloon-rpi.png
-img/markers/car-blue.png
-img/markers/car-green.png
-img/markers/car-red.png
-img/markers/car-yellow.png
-img/markers/parachute-blue.png
-img/markers/parachute-green.png
-img/markers/parachute-red.png
-img/markers/parachute-yellow.png
-img/markers/parachute-cyan.png
-img/markers/parachute-orange.png
-img/markers/parachute-purple.png
-img/markers/parachute-rpi.png
-img/markers/payload-blue.png
-img/markers/payload-cyan.png
-img/markers/payload-green.png
-img/markers/payload-orange.png
-img/markers/payload-purple.png
-img/markers/payload-red.png
-img/markers/payload-yellow.png
-img/markers/payload-rpi.png
-img/markers/shadow.png
-img/markers/target-blue.png
-img/markers/target-cyan.png
-img/markers/target-green.png
-img/markers/target-orange.png
-img/markers/target-purple.png
-img/markers/target-red.png
-img/markers/target-yellow.png
-img/hab-spinner.gif
-css/mobile.css
-js/mobile.js
-js/init_plot.js
-font/HabitatFont.eot
-font/HabitatFont.svg
-font/HabitatFont.ttf
-font/HabitatFont.woff
-font/Roboto-regular.woff
-
-NETWORK:
-*
-
-FALLBACK:
-/ index.html
diff --git a/css/base.css b/css/base.css
index 8c20088..016fe3e 100644
--- a/css/base.css
+++ b/css/base.css
@@ -29,257 +29,572 @@
/* #Reset & Basics (Inspired by E. Meyers)
================================================== */
- html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline; }
- sup {
- font-size: smaller;
- vertical-align: +0.4em; }
- sub {
- font-size: smaller;
- vertical-align: -0.25em; }
- article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
- display: block; }
- body {
- line-height: 1; }
- ol, ul {
- list-style: none; }
- blockquote, q {
- quotes: none; }
- blockquote:before, blockquote:after,
- q:before, q:after {
- content: '';
- content: none; }
- table {
- border-collapse: collapse;
- border-spacing: 0; }
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+sup {
+ font-size: smaller;
+ vertical-align: +0.4em;
+}
+
+sub {
+ font-size: smaller;
+ vertical-align: -0.25em;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+}
+
+ol,
+ul {
+ list-style: none;
+}
+
+blockquote,
+q {
+ quotes: none;
+}
+
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
/* #Basic Styles
================================================== */
- body {
- background: #fff;
- font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #666;
- -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
- -webkit-text-size-adjust: 100%;
- }
+body {
+ background: #fff;
+ font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #666;
+ -webkit-font-smoothing: antialiased;
+ /* Fix for webkit rendering */
+ -webkit-text-size-adjust: 100%;
+}
/* #Typography
================================================== */
- h1, h2, h3, h4, h5, h6 {
- font-weight: normal; }
- h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
- h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;}
- h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }
- h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }
- h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }
- h5 { font-size: 17px; line-height: 24px; }
- h6 { font-size: 14px; line-height: 21px; }
- .subheader { color: #777; }
-
- p { margin: 0 0 20px 0; }
- p img { margin: 0; }
- p.lead { font-size: 21px; line-height: 27px; color: #777; }
-
- em { font-style: italic; }
- strong { font-weight: bold; color: #333; }
- b { font-weight: bold; }
- small { font-size: 80%; }
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-weight: normal;
+}
+
+h1 a,
+h2 a,
+h3 a,
+h4 a,
+h5 a,
+h6 a {
+ font-weight: inherit;
+}
+
+h1 {
+ font-size: 46px;
+ line-height: 50px;
+ margin-bottom: 14px;
+}
+
+h2 {
+ font-size: 35px;
+ line-height: 40px;
+ margin-bottom: 10px;
+}
+
+h3 {
+ font-size: 28px;
+ line-height: 34px;
+ margin-bottom: 8px;
+}
+
+h4 {
+ font-size: 21px;
+ line-height: 30px;
+ margin-bottom: 4px;
+}
+
+h5 {
+ font-size: 17px;
+ line-height: 24px;
+}
+
+h6 {
+ font-size: 14px;
+ line-height: 21px;
+}
+
+.subheader {
+ color: #777;
+}
+
+p {
+ margin: 0 0 20px 0;
+}
+
+p img {
+ margin: 0;
+}
+
+p.lead {
+ font-size: 21px;
+ line-height: 27px;
+ color: #777;
+}
+
+em {
+ font-style: italic;
+}
+
+strong {
+ font-weight: bold;
+ color: #333;
+}
+
+b {
+ font-weight: bold;
+}
+
+small {
+ font-size: 80%;
+}
/* Blockquotes */
- blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }
- blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }
- blockquote cite { display: block; font-size: 12px; color: #555; }
- blockquote cite:before { content: "\2014 \0020"; }
- blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }
-
- hr { border: solid #ddd; border-width: 1px 0 0; clear: both; height: 0; }
+blockquote,
+blockquote p {
+ font-size: 17px;
+ line-height: 24px;
+ color: #777;
+ font-style: italic;
+}
+
+blockquote {
+ margin: 0 0 20px;
+ padding: 9px 20px 0 19px;
+ border-left: 1px solid #ddd;
+}
+
+blockquote cite {
+ display: block;
+ font-size: 12px;
+ color: #555;
+}
+
+blockquote cite:before {
+ content: "\2014 \0020";
+}
+
+blockquote cite a,
+blockquote cite a:visited,
+blockquote cite a:visited {
+ color: #555;
+}
+
+hr {
+ border: solid #ddd;
+ border-width: 1px 0 0;
+ clear: both;
+ height: 0;
+}
/* #Links
================================================== */
- a, a:visited { color: #333; text-decoration: underline; outline: 0; }
- a:hover, a:focus { color: #000; }
- p a, p a:visited { line-height: inherit; }
+a,
+a:visited {
+ color: #333;
+ text-decoration: underline;
+ outline: 0;
+}
+
+a:hover,
+a:focus {
+ color: #000;
+}
+
+p a,
+p a:visited {
+ line-height: inherit;
+}
/* #Lists
================================================== */
- ul, ol { margin-bottom: 20px; }
- ul { list-style: none outside; }
- ol { list-style: decimal; }
- ol, ul.square, ul.circle, ul.disc { margin-left: 30px; }
- ul.square { list-style: square outside; }
- ul.circle { list-style: circle outside; }
- ul.disc { list-style: disc outside; }
- ul ul, ul ol,
- ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }
- ul ul li, ul ol li,
- ol ol li, ol ul li { margin-bottom: 6px; }
- li { line-height: 18px; margin-bottom: 12px; }
- ul.large li { line-height: 21px; }
- li p { line-height: 21px; }
+ul,
+ol {
+ margin-bottom: 20px;
+}
+
+ul {
+ list-style: none outside;
+}
+
+ol {
+ list-style: decimal;
+}
+
+ol,
+ul.square,
+ul.circle,
+ul.disc {
+ margin-left: 30px;
+}
+
+ul.square {
+ list-style: square outside;
+}
+
+ul.circle {
+ list-style: circle outside;
+}
+
+ul.disc {
+ list-style: disc outside;
+}
+
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+ margin: 4px 0 5px 30px;
+ font-size: 90%;
+}
+
+ul ul li,
+ul ol li,
+ol ol li,
+ol ul li {
+ margin-bottom: 6px;
+}
+
+li {
+ line-height: 18px;
+ margin-bottom: 12px;
+}
+
+ul.large li {
+ line-height: 21px;
+}
+
+li p {
+ line-height: 21px;
+}
/* #Images
================================================== */
- img.scale-with-grid {
- max-width: 100%;
- height: auto; }
+img.scale-with-grid {
+ max-width: 100%;
+ height: auto;
+}
/* #Buttons
================================================== */
- .button,
- button,
- input[type="submit"],
- input[type="reset"],
- input[type="button"] {
- background: #eee; /* Old browsers */
- background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */
- background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */
- background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */
- background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */
- background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */
- background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */
- border: 1px solid #aaa;
- border-top: 1px solid #ccc;
- border-left: 1px solid #ccc;
- margin-right: 1px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- color: #444;
- display: inline-block;
- font-size: 11px;
- font-weight: bold;
- text-decoration: none;
- text-shadow: 0 1px rgba(255, 255, 255, .75);
- cursor: pointer;
- line-height: normal;
- padding: 8px 10px;
- font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }
-
- .button:hover,
- button:hover,
- input[type="submit"]:hover,
- input[type="reset"]:hover,
- input[type="button"]:hover {
- color: #222;
- background: #ddd; /* Old browsers */
- background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */
- background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */
- background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */
- background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */
- background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */
- background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */
- border: 1px solid #888;
- border-top: 1px solid #aaa;
- border-left: 1px solid #aaa; }
-
- .button:active,
- button:active,
- input[type="submit"]:active,
- input[type="reset"]:active,
- input[type="button"]:active {
- border: 1px solid #666;
- background: #ccc; /* Old browsers */
- background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */
- background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */
- background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */
- background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */
- background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */
- background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }
-
- .button.full-width,
- button.full-width,
- input[type="submit"].full-width,
- input[type="reset"].full-width,
- input[type="button"].full-width {
- width: 100%;
- padding-left: 0 !important;
- padding-right: 0 !important;
- text-align: center; }
-
- /* Fix for odd Mozilla border & padding issues */
- button::-moz-focus-inner,
- input::-moz-focus-inner {
- border: 0;
- padding: 0;
- }
-
- .button.disabled,
- button.disabled,
- input[type="submit"].disabled,
- input[type="reset"].disabled,
- input[type="button"].disabled {
- border: 1px solid #aaa;
- color: #aaa;
- background: #fff;
- }
+.button,
+button,
+input[type="submit"],
+input[type="reset"],
+input[type="button"] {
+ background: #eee;
+ /* Old browsers */
+ background: #eee -moz-linear-gradient(top, rgba(255, 255, 255, .2) 0%, rgba(0, 0, 0, .2) 100%);
+ /* FF3.6+ */
+ background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, .2)), color-stop(100%, rgba(0, 0, 0, .2)));
+ /* Chrome,Safari4+ */
+ background: #eee -webkit-linear-gradient(top, rgba(255, 255, 255, .2) 0%, rgba(0, 0, 0, .2) 100%);
+ /* Chrome10+,Safari5.1+ */
+ background: #eee -o-linear-gradient(top, rgba(255, 255, 255, .2) 0%, rgba(0, 0, 0, .2) 100%);
+ /* Opera11.10+ */
+ background: #eee -ms-linear-gradient(top, rgba(255, 255, 255, .2) 0%, rgba(0, 0, 0, .2) 100%);
+ /* IE10+ */
+ background: #eee linear-gradient(top, rgba(255, 255, 255, .2) 0%, rgba(0, 0, 0, .2) 100%);
+ /* W3C */
+ border: 1px solid #aaa;
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #ccc;
+ margin-right: 1px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ color: #444;
+ display: inline-block;
+ font-size: 11px;
+ font-weight: bold;
+ text-decoration: none;
+ text-shadow: 0 1px rgba(255, 255, 255, .75);
+ cursor: pointer;
+ line-height: normal;
+ padding: 8px 10px;
+ font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+.button:hover,
+button:hover,
+input[type="submit"]:hover,
+input[type="reset"]:hover,
+input[type="button"]:hover {
+ color: #222;
+ background: #ddd;
+ /* Old browsers */
+ background: #ddd -moz-linear-gradient(top, rgba(255, 255, 255, .3) 0%, rgba(0, 0, 0, .3) 100%);
+ /* FF3.6+ */
+ background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, .3)), color-stop(100%, rgba(0, 0, 0, .3)));
+ /* Chrome,Safari4+ */
+ background: #ddd -webkit-linear-gradient(top, rgba(255, 255, 255, .3) 0%, rgba(0, 0, 0, .3) 100%);
+ /* Chrome10+,Safari5.1+ */
+ background: #ddd -o-linear-gradient(top, rgba(255, 255, 255, .3) 0%, rgba(0, 0, 0, .3) 100%);
+ /* Opera11.10+ */
+ background: #ddd -ms-linear-gradient(top, rgba(255, 255, 255, .3) 0%, rgba(0, 0, 0, .3) 100%);
+ /* IE10+ */
+ background: #ddd linear-gradient(top, rgba(255, 255, 255, .3) 0%, rgba(0, 0, 0, .3) 100%);
+ /* W3C */
+ border: 1px solid #888;
+ border-top: 1px solid #aaa;
+ border-left: 1px solid #aaa;
+}
+
+.button:active,
+button:active,
+input[type="submit"]:active,
+input[type="reset"]:active,
+input[type="button"]:active {
+ border: 1px solid #666;
+ background: #ccc;
+ /* Old browsers */
+ background: #ccc -moz-linear-gradient(top, rgba(255, 255, 255, .35) 0%, rgba(10, 10, 10, .4) 100%);
+ /* FF3.6+ */
+ background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, .35)), color-stop(100%, rgba(10, 10, 10, .4)));
+ /* Chrome,Safari4+ */
+ background: #ccc -webkit-linear-gradient(top, rgba(255, 255, 255, .35) 0%, rgba(10, 10, 10, .4) 100%);
+ /* Chrome10+,Safari5.1+ */
+ background: #ccc -o-linear-gradient(top, rgba(255, 255, 255, .35) 0%, rgba(10, 10, 10, .4) 100%);
+ /* Opera11.10+ */
+ background: #ccc -ms-linear-gradient(top, rgba(255, 255, 255, .35) 0%, rgba(10, 10, 10, .4) 100%);
+ /* IE10+ */
+ background: #ccc linear-gradient(top, rgba(255, 255, 255, .35) 0%, rgba(10, 10, 10, .4) 100%);
+ /* W3C */
+}
+
+.button.full-width,
+button.full-width,
+input[type="submit"].full-width,
+input[type="reset"].full-width,
+input[type="button"].full-width {
+ width: 100%;
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ text-align: center;
+}
+
+/* Fix for odd Mozilla border & padding issues */
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+.button.disabled,
+button.disabled,
+input[type="submit"].disabled,
+input[type="reset"].disabled,
+input[type="button"].disabled {
+ border: 1px solid #aaa;
+ color: #aaa;
+ background: #fff;
+}
/* #Forms
================================================== */
- fieldset {
- margin-bottom: 20px; }
- input[type="text"],
- input[type="password"],
- input[type="email"],
- textarea,
- select {
- border: 1px solid #ccc;
- padding: 6px 4px;
- outline: none;
- -moz-border-radius: 4px;
- -webkit-border-radius: 4px;
- border-radius: 4px;
- font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #888;
- margin: 0;
- max-width: 100%;
- background: #fff; }
- select {
- padding: 0; }
- input[type="text"]:focus,
- input[type="password"]:focus,
- input[type="email"]:focus,
- textarea:focus {
- border: 1px solid #aaa;
- color: #444;
- -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
- -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
- box-shadow: 0 0 3px rgba(0,0,0,.2); }
- textarea {
- min-height: 60px; }
- label,
- legend {
- display: block;
- font-weight: bold;
- font-size: 13px; }
- select {
- width: 220px; }
- input[type="checkbox"] {
- display: inline; }
- label span,
- legend span {
- font-weight: normal;
- font-size: 13px;
- color: #444; }
+fieldset {
+ margin-bottom: 20px;
+}
+
+input[type="text"],
+input[type="password"],
+input[type="email"],
+textarea,
+select {
+ border: 1px solid #ccc;
+ padding: 6px 4px;
+ outline: none;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #888;
+ margin: 0;
+ max-width: 100%;
+ background: #fff;
+}
+
+input[type="text"]:focus,
+input[type="password"]:focus,
+input[type="email"]:focus,
+textarea:focus {
+ border: 1px solid #aaa;
+ color: #444;
+ -moz-box-shadow: 0 0 3px rgba(0, 0, 0, .2);
+ -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .2);
+ box-shadow: 0 0 3px rgba(0, 0, 0, .2);
+}
+
+textarea {
+ min-height: 60px;
+}
+
+label,
+legend {
+ display: block;
+ font-weight: bold;
+ font-size: 13px;
+}
+
+select {
+ width: 220px;
+}
+
+input[type="checkbox"] {
+ display: inline;
+}
+
+label span,
+legend span {
+ font-weight: normal;
+ font-size: 13px;
+ color: #444;
+}
/* #Misc
================================================== */
- .remove-bottom { margin-bottom: 0 !important; }
- .half-bottom { margin-bottom: 10px !important; }
- .add-bottom { margin-bottom: 20px !important; }
- .no-margin { margin: 0 !important; padding: 0; }
-
-
+.remove-bottom {
+ margin-bottom: 0 !important;
+}
+
+.half-bottom {
+ margin-bottom: 10px !important;
+}
+
+.add-bottom {
+ margin-bottom: 20px !important;
+}
+
+.no-margin {
+ margin: 0 !important;
+ padding: 0;
+}
\ No newline at end of file
diff --git a/css/layout.css b/css/layout.css
index 009cdaf..8ebfd8f 100644
--- a/css/layout.css
+++ b/css/layout.css
@@ -164,3 +164,35 @@ header h1{
font-weight: normal;
font-style: normal; }
*/
+
+#reload_warning {
+ position: absolute;
+ left: 20px;
+ bottom: 20px;
+ font-size: 12;
+ width: 300px;
+ height: auto;
+ background-color: white;
+ z-index: 10;
+ box-shadow: rgba(9, 20, 66, 0.25) 0px 20px 32px -8px;
+ border: #ddd solid;
+ padding: 10px;
+ border-width: 1px;
+ display: none;
+}
+
+#banner {
+ display: none
+}
+@media only screen and (min-width: 768px){
+ #banner {
+ line-height: 1.1;
+ font-size: small;
+ display: block;
+ margin-left: 300px;
+ text-align: center;
+ overflow-y: auto;
+ font-weight: bold;
+ height: 100%;
+ }
+}
\ No newline at end of file
diff --git a/css/main.css b/css/main.css
index e273a77..ee57d7f 100644
--- a/css/main.css
+++ b/css/main.css
@@ -99,11 +99,13 @@ body {
#timebox {
top: 7px;
right: 5px;
+ width: 205px;
}
#lookanglesbox {
top: 40px;
right: 5px;
+ width: 205px;
}
#timebox.past svg path {
diff --git a/img/apple-touch-icon.png b/img/apple-touch-icon.png
index b16c0d7..380f8a3 100644
Binary files a/img/apple-touch-icon.png and b/img/apple-touch-icon.png differ
diff --git a/img/ardc_logo_small.png b/img/ardc_logo_small.png
new file mode 100644
index 0000000..9fe7e31
Binary files /dev/null and b/img/ardc_logo_small.png differ
diff --git a/img/graw_logo_small.png b/img/graw_logo_small.png
new file mode 100644
index 0000000..dedb4f3
Binary files /dev/null and b/img/graw_logo_small.png differ
diff --git a/img/icons/icon_x192.png b/img/icons/icon_x192.png
index 618ae3a..bcf4bac 100644
Binary files a/img/icons/icon_x192.png and b/img/icons/icon_x192.png differ
diff --git a/img/icons/icon_x512.png b/img/icons/icon_x512.png
index 9654aad..5795d0f 100644
Binary files a/img/icons/icon_x512.png and b/img/icons/icon_x512.png differ
diff --git a/img/icons/maskable_icon_x128.png b/img/icons/maskable_icon_x128.png
index ed395e1..1101d10 100644
Binary files a/img/icons/maskable_icon_x128.png and b/img/icons/maskable_icon_x128.png differ
diff --git a/img/icons/maskable_icon_x192.png b/img/icons/maskable_icon_x192.png
index 1ec5586..87b550d 100644
Binary files a/img/icons/maskable_icon_x192.png and b/img/icons/maskable_icon_x192.png differ
diff --git a/img/icons/maskable_icon_x384.png b/img/icons/maskable_icon_x384.png
index ef558c9..31c9d5c 100644
Binary files a/img/icons/maskable_icon_x384.png and b/img/icons/maskable_icon_x384.png differ
diff --git a/img/icons/maskable_icon_x48.png b/img/icons/maskable_icon_x48.png
index 56ae4a7..dad2250 100644
Binary files a/img/icons/maskable_icon_x48.png and b/img/icons/maskable_icon_x48.png differ
diff --git a/img/icons/maskable_icon_x512.png b/img/icons/maskable_icon_x512.png
index f00d755..8dff53a 100644
Binary files a/img/icons/maskable_icon_x512.png and b/img/icons/maskable_icon_x512.png differ
diff --git a/img/icons/maskable_icon_x72.png b/img/icons/maskable_icon_x72.png
index 1388186..34e3a9e 100644
Binary files a/img/icons/maskable_icon_x72.png and b/img/icons/maskable_icon_x72.png differ
diff --git a/img/icons/maskable_icon_x96.png b/img/icons/maskable_icon_x96.png
index febd7c0..4d7b7a3 100644
Binary files a/img/icons/maskable_icon_x96.png and b/img/icons/maskable_icon_x96.png differ
diff --git a/img/logo.png b/img/logo.png
deleted file mode 100644
index cc06274..0000000
Binary files a/img/logo.png and /dev/null differ
diff --git a/img/markers/balloon-adafruit.png b/img/markers/balloon-adafruit.png
deleted file mode 100644
index 4c715f2..0000000
Binary files a/img/markers/balloon-adafruit.png and /dev/null differ
diff --git a/img/markers/balloon-blue.png b/img/markers/balloon-blue.png
deleted file mode 100644
index 9888487..0000000
Binary files a/img/markers/balloon-blue.png and /dev/null differ
diff --git a/img/markers/balloon-buzz.png b/img/markers/balloon-buzz.png
deleted file mode 100644
index 17097b5..0000000
Binary files a/img/markers/balloon-buzz.png and /dev/null differ
diff --git a/img/markers/balloon-cyan.png b/img/markers/balloon-cyan.png
deleted file mode 100644
index 9eae707..0000000
Binary files a/img/markers/balloon-cyan.png and /dev/null differ
diff --git a/img/markers/balloon-green.png b/img/markers/balloon-green.png
deleted file mode 100644
index 126a0b0..0000000
Binary files a/img/markers/balloon-green.png and /dev/null differ
diff --git a/img/markers/balloon-invisible.png b/img/markers/balloon-invisible.png
deleted file mode 100644
index 19464e9..0000000
Binary files a/img/markers/balloon-invisible.png and /dev/null differ
diff --git a/img/markers/balloon-iss.png b/img/markers/balloon-iss.png
deleted file mode 100644
index 23d2a49..0000000
Binary files a/img/markers/balloon-iss.png and /dev/null differ
diff --git a/img/markers/balloon-orange.png b/img/markers/balloon-orange.png
deleted file mode 100644
index b0c5d09..0000000
Binary files a/img/markers/balloon-orange.png and /dev/null differ
diff --git a/img/markers/balloon-pop.png b/img/markers/balloon-pop.png
index cb65773..eac488b 100644
Binary files a/img/markers/balloon-pop.png and b/img/markers/balloon-pop.png differ
diff --git a/img/markers/balloon-purple.png b/img/markers/balloon-purple.png
deleted file mode 100644
index e129b1c..0000000
Binary files a/img/markers/balloon-purple.png and /dev/null differ
diff --git a/img/markers/balloon-red.png b/img/markers/balloon-red.png
deleted file mode 100644
index f079bfe..0000000
Binary files a/img/markers/balloon-red.png and /dev/null differ
diff --git a/img/markers/balloon-rob.png b/img/markers/balloon-rob.png
deleted file mode 100644
index 819a558..0000000
Binary files a/img/markers/balloon-rob.png and /dev/null differ
diff --git a/img/markers/balloon-rpi.png b/img/markers/balloon-rpi.png
deleted file mode 100644
index c340631..0000000
Binary files a/img/markers/balloon-rpi.png and /dev/null differ
diff --git a/img/markers/balloon-shockpink.png b/img/markers/balloon-shockpink.png
deleted file mode 100644
index 49ad112..0000000
Binary files a/img/markers/balloon-shockpink.png and /dev/null differ
diff --git a/img/markers/balloon-thereg.png b/img/markers/balloon-thereg.png
deleted file mode 100644
index f26068f..0000000
Binary files a/img/markers/balloon-thereg.png and /dev/null differ
diff --git a/img/markers/balloon-yellow.png b/img/markers/balloon-yellow.png
deleted file mode 100644
index 66fc042..0000000
Binary files a/img/markers/balloon-yellow.png and /dev/null differ
diff --git a/img/markers/balloon.svg b/img/markers/balloon.svg
new file mode 100755
index 0000000..8966505
--- /dev/null
+++ b/img/markers/balloon.svg
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/img/markers/car-blue.png b/img/markers/car-blue.png
deleted file mode 100644
index 09192f0..0000000
Binary files a/img/markers/car-blue.png and /dev/null differ
diff --git a/img/markers/car-green.png b/img/markers/car-green.png
deleted file mode 100644
index c42da50..0000000
Binary files a/img/markers/car-green.png and /dev/null differ
diff --git a/img/markers/car-purple.png b/img/markers/car-purple.png
deleted file mode 100644
index a281513..0000000
Binary files a/img/markers/car-purple.png and /dev/null differ
diff --git a/img/markers/car-red.png b/img/markers/car-red.png
deleted file mode 100644
index ce44c92..0000000
Binary files a/img/markers/car-red.png and /dev/null differ
diff --git a/img/markers/car-teal.png b/img/markers/car-teal.png
deleted file mode 100644
index f0e6fe8..0000000
Binary files a/img/markers/car-teal.png and /dev/null differ
diff --git a/img/markers/car-yellow.png b/img/markers/car-yellow.png
deleted file mode 100644
index 5c35476..0000000
Binary files a/img/markers/car-yellow.png and /dev/null differ
diff --git a/img/markers/car.svg b/img/markers/car.svg
new file mode 100644
index 0000000..c277ce8
--- /dev/null
+++ b/img/markers/car.svg
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/img/markers/parachute-blue.png b/img/markers/parachute-blue.png
deleted file mode 100644
index ff4dc5d..0000000
Binary files a/img/markers/parachute-blue.png and /dev/null differ
diff --git a/img/markers/parachute-cyan.png b/img/markers/parachute-cyan.png
deleted file mode 100644
index bf83a49..0000000
Binary files a/img/markers/parachute-cyan.png and /dev/null differ
diff --git a/img/markers/parachute-green.png b/img/markers/parachute-green.png
deleted file mode 100644
index f41d7e1..0000000
Binary files a/img/markers/parachute-green.png and /dev/null differ
diff --git a/img/markers/parachute-orange.png b/img/markers/parachute-orange.png
deleted file mode 100644
index e3f2d16..0000000
Binary files a/img/markers/parachute-orange.png and /dev/null differ
diff --git a/img/markers/parachute-purple.png b/img/markers/parachute-purple.png
deleted file mode 100644
index adae959..0000000
Binary files a/img/markers/parachute-purple.png and /dev/null differ
diff --git a/img/markers/parachute-red.png b/img/markers/parachute-red.png
deleted file mode 100644
index 603c60f..0000000
Binary files a/img/markers/parachute-red.png and /dev/null differ
diff --git a/img/markers/parachute-rpi.png b/img/markers/parachute-rpi.png
deleted file mode 100644
index ad421b6..0000000
Binary files a/img/markers/parachute-rpi.png and /dev/null differ
diff --git a/img/markers/parachute-yellow.png b/img/markers/parachute-yellow.png
deleted file mode 100644
index 4d85a51..0000000
Binary files a/img/markers/parachute-yellow.png and /dev/null differ
diff --git a/img/markers/parachute.svg b/img/markers/parachute.svg
new file mode 100644
index 0000000..8b10853
--- /dev/null
+++ b/img/markers/parachute.svg
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/img/markers/payload-blue.png b/img/markers/payload-blue.png
deleted file mode 100644
index c03caee..0000000
Binary files a/img/markers/payload-blue.png and /dev/null differ
diff --git a/img/markers/payload-cyan.png b/img/markers/payload-cyan.png
deleted file mode 100644
index 226bfa8..0000000
Binary files a/img/markers/payload-cyan.png and /dev/null differ
diff --git a/img/markers/payload-green.png b/img/markers/payload-green.png
deleted file mode 100644
index f524a73..0000000
Binary files a/img/markers/payload-green.png and /dev/null differ
diff --git a/img/markers/payload-orange.png b/img/markers/payload-orange.png
deleted file mode 100644
index 20e5b05..0000000
Binary files a/img/markers/payload-orange.png and /dev/null differ
diff --git a/img/markers/payload-purple.png b/img/markers/payload-purple.png
deleted file mode 100644
index 80e1e1a..0000000
Binary files a/img/markers/payload-purple.png and /dev/null differ
diff --git a/img/markers/payload-recovery-planned.png b/img/markers/payload-recovery-planned.png
new file mode 100644
index 0000000..e314714
Binary files /dev/null and b/img/markers/payload-recovery-planned.png differ
diff --git a/img/markers/payload-red.png b/img/markers/payload-red.png
deleted file mode 100644
index 7ad8acc..0000000
Binary files a/img/markers/payload-red.png and /dev/null differ
diff --git a/img/markers/payload-rpi.png b/img/markers/payload-rpi.png
deleted file mode 100644
index 9f533fb..0000000
Binary files a/img/markers/payload-rpi.png and /dev/null differ
diff --git a/img/markers/payload-yellow.png b/img/markers/payload-yellow.png
deleted file mode 100644
index e9b7bb5..0000000
Binary files a/img/markers/payload-yellow.png and /dev/null differ
diff --git a/img/markers/payload.svg b/img/markers/payload.svg
new file mode 100644
index 0000000..b89d7d6
--- /dev/null
+++ b/img/markers/payload.svg
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/img/markers/target-blue.png b/img/markers/target-blue.png
deleted file mode 100644
index fae5796..0000000
Binary files a/img/markers/target-blue.png and /dev/null differ
diff --git a/img/markers/target-cyan.png b/img/markers/target-cyan.png
deleted file mode 100644
index ba30743..0000000
Binary files a/img/markers/target-cyan.png and /dev/null differ
diff --git a/img/markers/target-green.png b/img/markers/target-green.png
deleted file mode 100644
index 56b4682..0000000
Binary files a/img/markers/target-green.png and /dev/null differ
diff --git a/img/markers/target-orange.png b/img/markers/target-orange.png
deleted file mode 100644
index 4b353b6..0000000
Binary files a/img/markers/target-orange.png and /dev/null differ
diff --git a/img/markers/target-purple.png b/img/markers/target-purple.png
deleted file mode 100644
index 4510158..0000000
Binary files a/img/markers/target-purple.png and /dev/null differ
diff --git a/img/markers/target-red.png b/img/markers/target-red.png
deleted file mode 100644
index 5987df9..0000000
Binary files a/img/markers/target-red.png and /dev/null differ
diff --git a/img/markers/target-yellow.png b/img/markers/target-yellow.png
deleted file mode 100644
index 8dc2d08..0000000
Binary files a/img/markers/target-yellow.png and /dev/null differ
diff --git a/img/markers/target.svg b/img/markers/target.svg
new file mode 100644
index 0000000..e80875e
--- /dev/null
+++ b/img/markers/target.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/img/sondehub_au.png b/img/sondehub_au.png
new file mode 100644
index 0000000..069c3c0
Binary files /dev/null and b/img/sondehub_au.png differ
diff --git a/img/sondehub_supporters.kra b/img/sondehub_supporters.kra
new file mode 100644
index 0000000..6728b1b
Binary files /dev/null and b/img/sondehub_supporters.kra differ
diff --git a/img/splash/splash-wide.png b/img/splash/splash-wide.png
index d7eff35..59b1fcb 100644
Binary files a/img/splash/splash-wide.png and b/img/splash/splash-wide.png differ
diff --git a/index.html b/index.template.html
similarity index 81%
rename from index.html
rename to index.template.html
index cf46f36..964bc91 100644
--- a/index.html
+++ b/index.template.html
@@ -9,6 +9,7 @@
+
@@ -19,19 +20,45 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
@@ -57,21 +84,70 @@
no location
+
-
Recoveries
+
Report Recovery
-
Recovery reports can be added on the Chase-Car pane.
+
+ Please report recovered radiosondes! Don't waste others time and effort with a frustrating failed recovery!
+ Enter the serial number, select recovered / planned, and add some notes. If marking as planned, please add contact information!
+ If the sonde is not on the map, type its serial into the top-left search box (may require landscape mode on mobile) and press enter to retrieve historical data.
+
+
+
+ Recovered By
+
+
+
+
Recovery Success
+
+
+
+
+
+
+
Recovery Planned
+
+
+
+
+
+
+
Use Browser Position
+
+
+
+
+
+
+ Notes
+
+
+
+
+
+
+
+ Report Result
+ none
+
+
+
+
-
-
-
-
Statistics
+
Statistics
+
+
Recoveries
+
@@ -81,48 +157,52 @@
Welcome
User Guide
A User Guide for the tracker is
available here.
-
+
+
Check the SondeHub-Tracker Changelog to find info on recent updates.
+
Radiosondes?
To learn more check out our
-
LCA video .
-
-
How do I receive?
- Set up a receiver station using
+
LCA video .
+ You can set up a receiver station using
auto_rx or
rdzTTGOsonde .
-
Recovered a Sonde?
- Click the 'car' icon on the top-right to submit a recovery notification.
+
Found a Radiosonde?
+
Please click the 'balloon' icon on the top-right to submit a recovery notification!
Support Us!
- AWS hosting unfortunately does not come cheap.
- If you use SondeHub regularly, please consider
supporting us on Patreon , or with a
donation on Paypal .
+ If you use SondeHub regularly, please consider
supporting us on Patreon , or with a
donation on Paypal .
+ We gratefully thank our major supporters:
+
+
+
Contact Us!
+ For SondeHub usage questions and support, feel free to email us at
support@sondehub.org .
+
+ You can also find us on
Discord and on IRC in
#habhub at
libera.chat .
Amateur HAB Launches?
- You can find Amateur High-Altitude Balloon launches on the
HabHub Tracker .
+ You can find Amateur High-Altitude Balloon launches on the
Sondehub-Amateur Tracker .
SondeHub Status Pages
+ This site uses data from the
SondeHub database.
You can find the status of the SondeHub Database on the
SondeHub Dashboard .
You can view outages of the SondeHub Database at
SondeHub Status .
-
Info
- This site uses data from the
SondeHub database.
-
Chase Cars
Chase Cars can show up on the map using this tracker's chase-car features (look for the car icon at top-right)
or upload their position from
Chasemapper or
rdzTTGOsonde .
-
Contribute
-
+
Contribute
Did you know the tracker is open-source? Check it out on
github/sondehub-tracker .
- Bug reports, suggestions and pull requests are welcome.
-
- A huge thanks to RGP for developing the mobile tracker that this site is based on.
+ Bug reports, suggestions and pull requests are welcome. A huge thanks to RGP for developing the mobile tracker that this site is based on.
- You can also find us on IRC in #highaltitude at libera.chat .
+ Tracker Revision: {VER}
+
+ Build Date: {BUILD_DATE}
+
@@ -289,10 +369,10 @@ Chase Mode
Callsign
-
+
- Notice: If you enable this, your location will be uploaded to SondeHub; making it publicly visible on the map.
+ Notice: If you enable this, your location will be uploaded to SondeHub, making it publicly visible on the map for up to 12 hours.
@@ -320,48 +400,20 @@
Chase Mode
none
- Report Recovery
-
-
- You can report a recovery here. Enter the serial number (no type code, e.g. 'S1234567'), tick recovered/not recovered, and add some notes. If the sonde is not on the map, type its callsign into the top-left search box and press enter to retrieve historical data. You can then mark it as recovered. Optionally, you can use your location instead of the sonde's last location.
-
-
- Serial
-
-
-
-
Recovery Success
-
-
-
-
-
-
-
Use Car Position
-
-
-
-
-
-
- Notes
-
-
-
- Report Result
- none
-
-
-
-
-
+ Recovery reporting is now on the recoveries tab! (Balloon icon)
+
+
+
Zoom in for realtime data!
+
+
+
Please report recovered sondes!
+
+
@@ -392,35 +444,21 @@ Report Recovery
+
+
+
+
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/js/app.js b/js/app.js
index de44b5e..2731e23 100644
--- a/js/app.js
+++ b/js/app.js
@@ -40,6 +40,13 @@ function lhash_update(history_step) {
hash += "&nyan=1";
}
+ if(wvar.nena) {
+ hash += "&nena=1";
+ }
+ if(wvar.box) { // We just need something to change so we can trigger the back button correctly
+ hash += "&box="+wvar.box;
+ }
+
hash = encodeURI(hash);
// set state
if(history_supported) {
@@ -64,7 +71,9 @@ var wvar = {
zoom: true,
query: "",
nyan: false,
+ nena: false,
site: 0,
+ box: ""
};
@@ -87,6 +96,8 @@ function load_hash(no_refresh) {
focus: "",
query: "",
nyan: false,
+ nena: false,
+ box: ""
};
parms.forEach(function(v) {
@@ -96,23 +107,28 @@ function load_hash(no_refresh) {
switch(k) {
case "mt":
- if( baseMaps.hasOwnProperty(v) ) {
+ if( baseMaps.hasOwnProperty(v) && map) {
map.removeLayer(baseMaps[selectedLayer]);
selectedLayer = v;
map.addLayer(baseMaps[v]);
}
break;
case "mz":
- map.setZoom(parseInt(v));
+ if (map){
+ map.setZoom(parseInt(v));
+ }
break;
case "mc":
def.zoom = false;
manual_pan = true;
v = v.split(',');
var latlng = new L.LatLng(v[0], v[1]);
- map.panTo(latlng);
+ if (map){
+ map.panTo(latlng);
+ }
break;
case "f":
+ v = v.toUpperCase();
refocus = (follow_vehicle != v);
follow_vehicle = v;
def.focus = v;
@@ -122,40 +138,59 @@ function load_hash(no_refresh) {
if(modeList.indexOf(def.mode) == -1) def.mode = (is_mobile) ? modeDefaultMobile : modeDefault;
break;
case "q":
+ v = v.toUpperCase();
def.query = v;
$("header .search input[type='text']").val(v);
break;
case "nyan":
def[k] = !!parseInt(v);
break;
+ case "nena":
+ def[k] = !!parseInt(v);
+ break;
case "site":
focusID = v;
gotoSite(v);
break;
+ case "box":
+ def[k] = v;
+ break;
}
});
// check if we should force refresh
- ['mode','query','nyan'].forEach(function(k) {
+ ['mode','query','nyan','nena'].forEach(function(k) {
if(wvar[k] != def[k]) refresh = true;
});
+
+
$.extend(true, wvar, def);
+ if(map){
+ if (!def["box"]){
+ $(".flatpage").hide()
+ } else {
+ $(".flatpage").hide()
+ $("#"+def["box"]).show()
+ }
+ checkSize();
+ wvar["box"]= def["box"];
- // force refresh
- if(!no_refresh) {
- if(refresh) {
- zoomed_in = false;
- clean_refresh(wvar.mode, true);
- }
- else if(refocus) {
- $(".row.active").removeClass('active');
- $(".vehicle"+vehicles[wvar.focus].uuid).addClass('active');
- followVehicle(wvar.focus, manual_pan, true);
- }
- }
+ // force refresh
+ if(!no_refresh) {
+ if(refresh) {
+ zoomed_in = false;
+ clean_refresh(wvar.mode, true);
+ }
+ else if(refocus) {
+ $(".row.active").removeClass('active');
+ $(".vehicle"+vehicles[wvar.focus].uuid).addClass('active');
+ followVehicle(wvar.focus, manual_pan, true);
+ }
+ }
- lhash_update();
+ lhash_update();
+ }
}
window.onhashchange = load_hash;
@@ -180,6 +215,7 @@ for(var idx in params) {
$("header .search input[type='text']").val(wvar.query);
break;
case "nyan": wvar.nyan = true; break;
+ case "nena": wvar.nena = true; break;
case "focus": wvar.focus = decodeURIComponent(line[1]); break;
case "docid": wvar.docid = line[1]; break;
case "mode": wvar.mode = decodeURIComponent(line[1]); break;
@@ -188,24 +224,38 @@ for(var idx in params) {
// loads the tracker interface
function trackerInit() {
+ // update current position if we geolocation is available
+ if(currentPosition) updateCurrentPosition(currentPosition.lat, currentPosition.lon);
+
+
+
+ if (currentPosition && manual_pan == false){
+ coords = [currentPosition.lat, currentPosition.lon]
+ zoomLevel = 9;
+ map.setView(coords, zoomLevel, {animate: false});
+ }
$('#loading,#settingsbox,#aboutbox,#chasebox').hide(); // welcome screen
$('header,#main').show(); // interface elements
checkSize();
- if(map) return;
+ // if we there is enough screen space open aboutbox on startup
+ if(!is_mobile && !offline.get('opt_nowelcome') && $(window).width() > 900) $('.nav li.about').click();
+
if(is_mobile || wvar.enabled) $(".nav .wvar").hide();
if(!is_mobile) {
- $.getScript("js/init_plot.js", function() { checkSize(); if(!map) load(); });
+ $.getScript("js/_jquery.flot.js", function() {
+ $.getScript("js/plot_config.js", function() { checkSize(); if(!map) load(); });
+ });
if(wvar.graph) $('#telemetry_graph').attr('style','');
return;
}
- if(!map) load();
+ lhash_update(true);
}
-// if for some reason, applicationCache is not working, load the app after a 3s timeout
+// load the app after a 3s timeout
var initTimer = setTimeout(trackerInit, 3000);
var listScroll;
@@ -289,8 +339,7 @@ function positionUpdateError(error) {
switch(error.code)
{
case error.PERMISSION_DENIED:
- alert("no permission to use your location");
- $('#sw_chasecar').click(); // turn off chase car
+ $('#sw_chasecar').removeClass('on').addClass('off');
break;
default:
break;
@@ -305,89 +354,83 @@ var positionUpdateHandle = function(position) {
}
}
- //navigator.geolocation.getCurrentPosition(function(position) {
- var lat = position.coords.latitude;
- var lon = position.coords.longitude;
- var alt = (position.coords.altitude) ? position.coords.altitude : 0;
- var accuracy = (position.coords.accuracy) ? position.coords.accuracy : 0;
- var speed = (position.coords.speed) ? position.coords.speed : 0;
-
- // constantly update 'last updated' field, and display friendly time since last update
- if(!GPS_ts) {
- GPS_ts = parseInt(position.timestamp/1000);
-
- setInterval(function() {
- var delta_ts = parseInt(Date.now()/1000) - GPS_ts;
-
- // generate friendly timestamp
- var hours = Math.floor(delta_ts / 3600);
- var minutes = Math.floor(delta_ts / 60) % 60;
- var ts_str = (delta_ts >= 60) ?
- ((hours)?hours+'h ':'') +
- ((minutes)?minutes+'m':'') +
- ' ago'
- : 'just now';
- $('#cc_timestamp').text(ts_str);
- }, 30000);
-
- $('#cc_timestamp').text('just now');
- }
+ var lat = position.coords.latitude;
+ var lon = position.coords.longitude;
+ var alt = (position.coords.altitude) ? position.coords.altitude : 0;
+ var accuracy = (position.coords.accuracy) ? position.coords.accuracy : 0;
+ var speed = (position.coords.speed) ? position.coords.speed : 0;
+
+ // constantly update 'last updated' field, and display friendly time since last update
+ if(!GPS_ts) {
+ GPS_ts = parseInt(position.timestamp/1000);
+
+ setInterval(function() {
+ var delta_ts = parseInt(Date.now()/1000) - GPS_ts;
+
+ // generate friendly timestamp
+ var hours = Math.floor(delta_ts / 3600);
+ var minutes = Math.floor(delta_ts / 60) % 60;
+ var ts_str = (delta_ts >= 60) ?
+ ((hours)?hours+'h ':'') +
+ ((minutes)?minutes+'m':'') +
+ ' ago'
+ : 'just now';
+ $('#cc_timestamp').text(ts_str);
+ }, 30000);
+
+ $('#cc_timestamp').text('just now');
+ }
- // save position and update only if different is available
- if(CHASE_timer < (new Date()).getTime() &&
- (
- GPS_lat != lat ||
- GPS_lon != lon ||
- GPS_alt != alt ||
- GPS_speed != speed
- )
+ // save position and update only if different is available
+ if(CHASE_timer < (new Date()).getTime() &&
+ (
+ GPS_lat != lat ||
+ GPS_lon != lon ||
+ GPS_alt != alt ||
+ GPS_speed != speed
)
- {
- GPS_lat = lat;
- GPS_lon = lon;
- GPS_alt = alt;
- GPS_speed = speed;
- GPS_ts = parseInt(position.timestamp/1000);
- $('#cc_timestamp').text('just now');
-
- // update look angles once we get position
- if(follow_vehicle !== null && vehicles[follow_vehicle] !== undefined) {
- update_lookangles(follow_vehicle);
- }
+ )
+ {
+ GPS_lat = lat;
+ GPS_lon = lon;
+ GPS_alt = alt;
+ GPS_speed = speed;
+ GPS_ts = parseInt(position.timestamp/1000);
+ $('#cc_timestamp').text('just now');
+
+ // update look angles once we get position
+ if(follow_vehicle !== null && vehicles[follow_vehicle] !== undefined) {
+ update_lookangles(follow_vehicle);
+ }
- if(CHASE_enabled) {
- ChaseCar.updatePosition(callsign, position);
- CHASE_timer = (new Date()).getTime() + 15000;
- }
+ if(CHASE_enabled) {
+ ChaseCar.updatePosition(callsign, position);
+ CHASE_timer = (new Date()).getTime() + 15000;
}
- else { return; }
-
- // add/update marker on the map (tracker.js)
- updateCurrentPosition(lat, lon);
-
- // round the coordinates
- lat = parseInt(lat * 10000)/10000; // 4 decimal places (11m accuracy at equator)
- lon = parseInt(lon * 10000)/10000; // 4 decimal places
- speed = parseInt(speed * 10)/10; // 1 decimal place
- accuracy = parseInt(accuracy);
- alt = parseInt(alt);
-
- // dispaly them in the top right corner
- $('#app_name b').html(lat + ' ' + lon);
-
- // update chase car interface
- $('#cc_lat').text(lat);
- $('#cc_lon').text(lon);
- $('#cc_alt').text(alt + " m");
- $('#cc_accuracy').text(accuracy + " m");
- $('#cc_speed').text(speed + " m/s");
- /*
- },
- function() {
- // when there is no location
- $('#app_name b').html('mobile tracker');
- });
- */
+ }
+
+
+ // add/update marker on the map (sondehub.js)
+ updateCurrentPosition(lat, lon);
+
+ // round the coordinates
+ lat = parseInt(lat * 10000)/10000; // 4 decimal places (11m accuracy at equator)
+ lon = parseInt(lon * 10000)/10000; // 4 decimal places
+ speed = parseInt(speed * 10)/10; // 1 decimal place
+ accuracy = parseInt(accuracy);
+ alt = parseInt(alt);
+
+ // dispaly them in the top right corner
+ $('#app_name b').html(lat + ' ' + lon);
+
+ // update chase car interface
+ $('#cc_lat').text(lat);
+ $('#cc_lon').text(lon);
+ $('#cc_alt').text(alt + " m");
+ $('#cc_accuracy').text(accuracy + " m");
+ $('#cc_speed').text(speed + " m/s");
+
+
};
var twoZeroPad = function(n) {
@@ -435,6 +478,27 @@ var format_time_friendly = function(start, end) {
}
};
+var format_coordinates = function(lat, lon, name) {
+ var coords_text;
+ var ua = navigator.userAgent.toLowerCase();
+ var span = document.createElement('span')
+ var a = document.createElement("a")
+ span.appendChild(a)
+ // determine how to link the coordinates to a native app, if on a mobile device
+ if(ua.indexOf('iphone') > -1) {
+ a.href = 'maps://?q='+lat+','+lon
+ } else if(ua.indexOf('android') > -1) {
+ a.href = 'geo:'+lat+','+lon+'?q='+lat+','+lon+'('+name+')'
+ } else {
+ a.href = 'https://www.google.com/maps/search/?api=1&query='+lat+','+lon
+ a.target="_blank"
+ a.rel="noopener noreferrer"
+ }
+ a.innerText = roundNumber(lat, 5) + ', ' + roundNumber(lon, 5)
+
+ return span.innerHTML;
+};
+
// runs every second
var updateTime = function(date) {
// update timebox
@@ -456,7 +520,6 @@ var updateTime = function(date) {
}
};
-
$(window).ready(function() {
// refresh timebox
setInterval(function() {
@@ -538,12 +601,6 @@ $(window).ready(function() {
$("#main").removeClass("drag");
});
- // confirm dialog when launchnig a native map app with coordinates
- //$('#main').on('click', '#launch_mapapp', function() {
- // var answer = confirm("Launch your maps app?");
- // return answer;
- //});
-
// follow vehicle by clicking on data
$('#main').on('click', '.row .data', function() {
var e = $(this).parent();
@@ -618,6 +675,14 @@ $(window).ready(function() {
default: pretty_name = name[0].toUpperCase() + name.slice(1);
}
}
+ var visible_box = $(".flatpage:visible");
+ if (visible_box.length > 0){
+ wvar.box = visible_box[0].id
+ } else {
+ wvar.box = null
+ }
+
+ lhash_update(true);
checkSize();
});
@@ -631,7 +696,6 @@ $(window).ready(function() {
field.removeAttr('disabled');
e.removeClass('on').addClass('off');
- if(navigator.geolocation) navigator.geolocation.clearWatch(CHASE_enabled);
CHASE_enabled = null;
//CHASE_enabled = false;
@@ -639,7 +703,7 @@ $(window).ready(function() {
if(currentPosition && currentPosition.marker) map.addLayer(currentPosition.marker);
// turning the switch on
} else {
- if(callsign.length == null || callsign.length < 3) { alert('Please enter a valid callsign, at least 3 characters'); return; }
+ if(callsign == null || callsign.length < 3) { alert('Please enter a valid callsign, at least 3 characters'); return; }
if(!callsign.match(/^[a-zA-Z0-9\_\-]+$/)) { alert('Invalid characters in callsign (use only a-z,0-9,-,_)'); return; }
field.attr('disabled','disabled');
@@ -659,8 +723,7 @@ $(window).ready(function() {
ChaseCar.updatePosition(callsign, { coords: { latitude: GPS_lat, longitude: GPS_lon, altitude: GPS_alt, speed: GPS_speed }});
}
- if(navigator.geolocation) CHASE_enabled = navigator.geolocation.watchPosition(positionUpdateHandle, positionUpdateError);
- //CHASE_enabled = true;
+ CHASE_enabled = true;
// hide the blue man
if(currentPosition && currentPosition.marker) map.removeLayer(currentPosition.marker);
@@ -678,6 +741,23 @@ $(window).ready(function() {
// turning the switch on
} else {
e.removeClass('off').addClass('on');
+ // Remove any planned recovery check.
+ $("#sw_recovery_planned").removeClass('on').addClass('off');
+ }
+ });
+ // Logic to switch the recovery Planned button
+ $("#sw_recovery_planned").click(function() {
+ var e = $(this);
+
+ // turning the switch off
+ if(e.hasClass('on')) {
+ e.removeClass('on').addClass('off');
+
+ // turning the switch on
+ } else {
+ e.removeClass('off').addClass('on');
+ // Set recovery OK to false.
+ $("#sw_recovery_ok").removeClass('on').addClass('off');
}
});
// Logic to switch the use car position button
@@ -698,11 +778,21 @@ $(window).ready(function() {
callsign = $(this).val().trim();
offline.set('callsign', callsign); // put in localStorage
CHASE_listenerSent = false;
+ $('#recovery_callsign').val(callsign);
+ });
+
+ $("#recovery_callsign").on('change keyup', function() {
+ callsign = $(this).val().trim();
+ offline.set('callsign', callsign); // put in localStorage
+ CHASE_listenerSent = false;
+ $('#cc_callsign').val(callsign);
});
+
// load value from localStorage
callsign = offline.get('callsign');
$('#cc_callsign').val(callsign);
+ $('#recovery_callsign').val(callsign);
// settings page
@@ -751,6 +841,18 @@ $(window).ready(function() {
else focusVehicle(null, true);
break;
case "opt_imperial":
+ if (map_scale){
+ map_scale.remove()
+ }
+ // we need to remove and add the zoom controls so they end up in the same position
+ zoom_controls.remove()
+ if (on) {
+ map_scale = L.control.scale({position:'bottomright', imperial:true, metric:false}).addTo(map);
+ } else {
+ map_scale = L.control.scale({position:'bottomright', imperial:false}).addTo(map);
+ }
+ zoom_controls.addTo(map);
+
case "opt_haxis_hours":
refreshUI();
break;
@@ -767,10 +869,12 @@ $(window).ready(function() {
break;
case "opt_hide_receivers":
if(on) {
- updateReceivers([]);
- clearTimeout(periodical_listeners);
+ updateReceivers([],single=false);
+ //clearTimeout(periodical_listeners);
+ receiversHidden = true;
}
else {
+ receiversHidden = false;
refreshReceivers();
}
break;
@@ -785,9 +889,11 @@ $(window).ready(function() {
break;
case "opt_hide_chase":
if(on) {
- clearTimeout(periodical_listeners);
+ chaseCarsHidden = true;
+ //clearTimeout(periodical_listeners);
deleteChase();
} else {
+ chaseCarsHidden = false;
refreshNewReceivers(true);
}
break;
@@ -871,10 +977,7 @@ $(window).ready(function() {
});
navigator.geolocation.getCurrentPosition(positionUpdateHandle);
- // check for location update every 30sec
- //setInterval(positionUpdateHandle, 30000);
- // immediatelly check for position
- //positionUpdateHandle();
+ if(navigator.geolocation) navigator.geolocation.watchPosition(positionUpdateHandle, positionUpdateError);
}
// weather feature
@@ -973,7 +1076,8 @@ $(window).ready(function() {
$("header .search form").on('submit', function(e) {
e.preventDefault();
- var text = $("header .search input[type='text']").val();
+ var text = $("header .search input[type='text']").val().toUpperCase();
+ $("header .search input[type='text']")[0].value = text; // update field in case it wasn't already uppercase
if(text === wvar.query) return;
@@ -988,6 +1092,64 @@ $(window).ready(function() {
wvar.zoom = true;
}
+ // Insert the serial number into the recovery reporting serial number textbox
+ $("#pr_serial").val(text);
+
clean_refresh(wvar.mode, true, true);
});
});
+
+
+function check_version(){
+ const updateRequest = new Request("/js/version.json");
+ fetch(updateRequest)
+ .then(function(response){ return response.json()})
+ .then(function(response){
+ if (response['version'] != document.body.dataset.version) {
+
+ caches.keys().then(function(names) { // wipe cache for fresh reload
+ for (let name of names)
+ caches.delete(name);
+ });
+
+ window.clearInterval(update_check)
+ reload_timer = window.setTimeout(update_site, response['refresh']*1000)
+ reload_end_time = new Date().getTime() +response['refresh']*1000
+ update_countdown();
+ countdown_interval = setInterval(update_countdown, 100);
+ document.getElementById("reload_warning").style.display = "block";
+ }
+ })
+}
+function update_site(){
+
+ window.location.reload(true)
+}
+
+function check_banner(){
+ const bannerRequest = new Request("https://api.v2.sondehub.org/banner");
+ fetch(bannerRequest)
+ .then(function(response){ return response.json()})
+ .then(function(response){
+ if (response['banner']) {
+ document.getElementsByTagName("header")[0].style.backgroundColor = "#ff6259"
+ document.getElementsByTagName("header")[0].style.borderColor = "#eb3d34"
+ document.getElementById("banner").innerText = response['banner']
+ }
+ })
+}
+
+function update_countdown(){
+ var date = new Date(0);
+ time_remaining = (reload_end_time - new Date().getTime())/1000
+ date.setSeconds(time_remaining);
+ var timeString = date.toISOString().substring(11, 19); // hacky
+ document.getElementById("reload_timer").innerText = timeString;
+}
+
+check_version()
+check_banner()
+update_check = setInterval(check_version, 15 * 60 * 1000)
+load_hash();
+startAjax();
+load();
\ No newline at end of file
diff --git a/js/chasecar.lib.js b/js/chasecar.lib.js
index bca130f..1c470e2 100644
--- a/js/chasecar.lib.js
+++ b/js/chasecar.lib.js
@@ -24,7 +24,7 @@ ChaseCar.updatePosition = function(callsign, position) {
var _doc = {
"software_name": "SondeHub Tracker",
- "software_version": "{VER}",
+ "software_version": document.body.dataset.version,
"uploader_callsign": callsign,
"uploader_position": [position.coords.latitude, position.coords.longitude, _position_alt],
"uploader_antenna": "Mobile Station",
@@ -45,9 +45,9 @@ ChaseCar.updatePosition = function(callsign, position) {
ChaseCar.markRecovered = function(){
- // Distance limits reinstated 2021-12-04
- _run_checks = true;
- _range_limit = 200000; // 200 km
+ // Remove range checks - 2025-01-24
+ _range_check = false;
+ _range_limit = 500000; // 200 km
// Get the serial number to be marked recovered
_serial = $("#pr_serial").val().trim();
@@ -55,15 +55,15 @@ ChaseCar.markRecovered = function(){
_notes = $("#pr_notes").val().trim();
// Check it exists.
- if(_serial.includes("chase") && _run_checks){
+ if(_serial.includes("chase")){
$('#pr_last_report').text("Invalid sonde callsign.");
return;
}
- _callsign = $("#cc_callsign").val().trim();
+ _callsign = $("#recovery_callsign").val().trim();
if (_callsign == "" || _callsign == undefined || _callsign.length == 0)
{
- $('#pr_last_report').text("Enter a callsign in the chase-car section above!");
+ $('#pr_last_report').text("Enter a callsign/name in the 'Recovered by' field!");
return;
}
@@ -109,8 +109,8 @@ ChaseCar.markRecovered = function(){
// Calculate the distance from the sonde
_lookangles = calculate_lookangles(_chaser, _sonde);
- if( (_lookangles.range > _range_limit ) && _run_checks){
- $('#pr_last_report').text("Outside distance limit.");
+ if( (_lookangles.range > _range_limit ) && _range_check){
+ $('#pr_last_report').text("Outside distance limit (500km).");
return;
}
@@ -120,28 +120,26 @@ ChaseCar.markRecovered = function(){
}
}
+ // Logic to make recovery & planned mutually exclusive is in app.js
+ _recovered = $("#sw_recovery_ok").hasClass('on');
+ _planned = $("#sw_recovery_planned").hasClass('on');
+
var _doc = {
"serial": _serial,
"lat": _recov_lat,
"lon": _recov_lon,
"alt": 0.0,
- "recovered": $("#sw_recovery_ok").hasClass('on'),
+ "recovered": _recovered,
+ "planned": _planned,
"recovered_by": _callsign,
"description": _notes
};
- // Yes this is not the right way to do this...
- // .. but it adds an extra bit of check.
- var res = grecaptcha.getResponse();
- if (res == "" || res == undefined || res.length == 0)
- {
- $('#pr_last_report').text("Do Recaptcha first!");
- return;
- }
$('#pr_last_report').text("Submitting report...");
+
$.ajax({
type: "PUT",
url: ChaseCar.recovery_uri,
diff --git a/js/format.js b/js/format.js
index a1ee090..9552181 100644
--- a/js/format.js
+++ b/js/format.js
@@ -49,6 +49,12 @@ function formatData(data, live) {
dataTempEntry.gps_alt = data[entry].alt;
dataTempEntry.gps_lat = data[entry].lat;
dataTempEntry.gps_lon = data[entry].lon;
+
+ // Discard positions with null values.
+ if (dataTempEntry.gps_lat == 0 && dataTempEntry.gps_lon == 0) {
+ continue;
+ }
+
if (data[entry].heading) {
dataTempEntry.gps_heading = data[entry].heading;
}
@@ -72,18 +78,26 @@ function formatData(data, live) {
if (data[entry].hasOwnProperty("humidity")) {
dataTempEntry.data.humidity = data[entry].humidity;
}
- if (data[entry].manufacturer) {
- dataTempEntry.data.manufacturer = data[entry].manufacturer;
- }
if (data[entry].hasOwnProperty("pressure")) {
dataTempEntry.data.pressure = data[entry].pressure;
}
if (data[entry].sats) {
dataTempEntry.data.sats = data[entry].sats;
+
+ // Drop frames where sats = 0! We do not want to be handling invalid positions.
+ if (dataTempEntry.data.sats == 0){
+ continue;
+ }
}
if (data[entry].hasOwnProperty("temp")) {
dataTempEntry.data.temperature_external = data[entry].temp;
}
+ // RS41 specific stuff
+ if (data[entry].hasOwnProperty("rs41_mainboard")) {
+ dataTempEntry.data.rs41_mainboard = data[entry].rs41_mainboard;
+ }
+ // Removed showing mainboard firmware, not really valuable
+
if (data[entry].type) {
dataTempEntry.data.type = data[entry].type;
dataTempEntry.type = data[entry].type;
@@ -92,6 +106,14 @@ function formatData(data, live) {
dataTempEntry.data.type = data[entry].subtype;
dataTempEntry.type = data[entry].subtype;
}
+
+ if (data[entry].manufacturer) {
+ // Instead of adding a separate manufacturer field, prefix the type with it.
+ if (dataTempEntry.data.type) {
+ dataTempEntry.data.type = data[entry].manufacturer + " " + dataTempEntry.data.type;
+ }
+ }
+
if (data[entry].xdata) {
dataTempEntry.data.xdata = data[entry].xdata;
@@ -137,6 +159,12 @@ function formatData(data, live) {
dataTempEntry.gps_alt = data[key][i].alt;
dataTempEntry.gps_lat = data[key][i].lat;
dataTempEntry.gps_lon = data[key][i].lon;
+
+ // Discard positions with null values.
+ if (dataTempEntry.gps_lat == 0 && dataTempEntry.gps_lon == 0) {
+ continue;
+ }
+
if (data[key][i].heading) {
dataTempEntry.gps_heading = data[key][i].heading;
}
@@ -160,14 +188,17 @@ function formatData(data, live) {
if (data[key][i].hasOwnProperty("humidity")) {
dataTempEntry.data.humidity = data[key][i].humidity;
}
- if (data[key][i].manufacturer) {
- dataTempEntry.data.manufacturer = data[key][i].manufacturer;
- }
+
if (data[key][i].hasOwnProperty("pressure")) {
dataTempEntry.data.pressure = data[key][i].pressure;
}
if (data[key][i].sats) {
dataTempEntry.data.sats = data[key][i].sats;
+
+ // Drop frames where sats = 0! We do not want to be handling invalid positions.
+ if (dataTempEntry.data.sats == 0){
+ continue;
+ }
}
if (data[key][i].hasOwnProperty("temp")) {
dataTempEntry.data.temperature_external = data[key][i].temp;
@@ -180,6 +211,21 @@ function formatData(data, live) {
dataTempEntry.data.type = data[key][i].subtype;
dataTempEntry.type = data[key][i].subtype;
}
+
+ if (data[key][i].manufacturer) {
+ // Instead of adding a separate manufacturer field, prefix the type with it.
+ if (dataTempEntry.data.type) {
+ dataTempEntry.data.type = data[key][i].manufacturer + " " + dataTempEntry.data.type;
+ }
+ }
+
+ // RS41 specific stuff
+ if (data[key][i].hasOwnProperty("rs41_mainboard")) {
+ dataTempEntry.data.rs41_mainboard = data[key][i].rs41_mainboard;
+ }
+ // Removed showing mainboard firmware, not really valuable
+
+ // XDATA Handling
if (data[key][i].xdata) {
dataTempEntry.data.xdata = data[key][i].xdata;
if (data[key][i].hasOwnProperty("pressure")) {
@@ -244,6 +290,12 @@ function formatData(data, live) {
dataTempEntry.gps_alt = data[i].alt;
dataTempEntry.gps_lat = data[i].lat;
dataTempEntry.gps_lon = data[i].lon;
+
+ // Discard positions with null values.
+ if (dataTempEntry.gps_lat == 0 && dataTempEntry.gps_lon == 0) {
+ continue;
+ }
+
if (data[i].heading) {
dataTempEntry.gps_heading = data[i].heading;
}
@@ -275,6 +327,11 @@ function formatData(data, live) {
}
if (data[i].sats) {
dataTempEntry.data.sats = data[i].sats;
+
+ // Drop frames where sats = 0! We do not want to be handling invalid positions.
+ if (dataTempEntry.data.sats == 0){
+ continue;
+ }
}
if (data[i].hasOwnProperty("temp")) {
dataTempEntry.data.temperature_external = data[i].temp;
@@ -285,7 +342,8 @@ function formatData(data, live) {
dataTempEntry.data.type = v1types[comment[0]];
dataTempEntry.type = v1types[comment[0]];
if (v1manufacturers.hasOwnProperty(dataTempEntry.type)) {
- dataTempEntry.data.manufacturer = v1manufacturers[dataTempEntry.type];
+ // dataTempEntry.data.manufacturer = v1manufacturers[dataTempEntry.type];
+ dataTempEntry.data.type = v1manufacturers[dataTempEntry.type] + " " + dataTempEntry.data.type;
}
}
dataTempEntry.data.frequency = comment[2];
@@ -297,6 +355,21 @@ function formatData(data, live) {
dataTempEntry.data.type = data[i].subtype;
dataTempEntry.type = data[i].subtype;
}
+
+ if (data[i].manufacturer) {
+ // Instead of adding a separate manufacturer field, prefix the type with it.
+ if (dataTempEntry.data.type) {
+ dataTempEntry.data.type = data[i].manufacturer + " " + dataTempEntry.data.type;
+ }
+ }
+
+ // RS41 specific stuff
+ if (data[i].hasOwnProperty("rs41_mainboard")) {
+ dataTempEntry.data.rs41_mainboard = data[i].rs41_mainboard;
+ }
+ // Removed showing mainboard firmware, not really valuable
+
+ // XDATA Handling
if (data[i].xdata) {
dataTempEntry.data.xdata = data[i].xdata;
if (data[i].hasOwnProperty("pressure")) {
diff --git a/js/plot_config.js b/js/plot_config.js
index f40315a..e66bc6d 100644
--- a/js/plot_config.js
+++ b/js/plot_config.js
@@ -77,9 +77,9 @@ function updateLegend(pos) {
if(outside && pij !== undefined) {
if(!polyMarker) {
- try {polyMarker = new L.Marker(vehicles[follow_vehicle].prediction_polyline.getLatLngs()[pij]).addTo(map);} catch (e) {};
+ try {polyMarker = new L.Marker(vehicles[follow_vehicle].prediction_polyline[0].getLatLngs()[pij]).addTo(map);} catch (e) {};
} else {
- try {polyMarker.setLatLng(vehicles[follow_vehicle].prediction_polyline.getLatLngs()[pij]);} catch (e) {};
+ try {polyMarker.setLatLng(vehicles[follow_vehicle].prediction_polyline[0].getLatLngs()[pij]);} catch (e) {};
}
}
diff --git a/js/skewt.js b/js/skewt.js
index 1838649..9fb6995 100644
--- a/js/skewt.js
+++ b/js/skewt.js
@@ -1479,7 +1479,7 @@ function (div, { isTouchDevice, gradient = 45, topp = 50, maxtopp=50, parctempSh
const ranges = {
parctemp: { value: 10, step: 0.1, min: -50, max: 50 },
- topp: { min: 50, max: 900, step: 25, value: topp },
+ topp: { min: 10, max: 900, step: 10, value: 50},
parctempShift: { min: -5, step: 0.1, max: 10, value: parctempShift },
gradient: { min: 0, max: 85, step: 1, value: gradient },
// midtemp:{value:0, step:2, min:-50, max:50},
diff --git a/js/tracker.js b/js/sondehub.js
similarity index 70%
rename from js/tracker.js
rename to js/sondehub.js
index 4b34c19..1296cc4 100644
--- a/js/tracker.js
+++ b/js/sondehub.js
@@ -7,15 +7,22 @@ var launch_predictions_url = "https://api.v2.sondehub.org/predictions/reverse";
var recovered_sondes_url = "https://api.v2.sondehub.org/recovered";
var recovered_sondes_stats_url = "https://api.v2.sondehub.org/recovered/stats";
+// Grafana dashboard for Radiosondes
+var grafana_url = "https://grafana.v2.sondehub.org/d/bbaa7894-e5f4-4c0d-be96-897b4ffde43b/radiosonde-telemetry-dashboard?";
+
var livedata = "wss://ws-reader.v2.sondehub.org/";
var clientID = "SondeHub-Tracker-" + Math.floor(Math.random() * 10000000000);
var client = new Paho.Client(livedata, clientID);
var clientConnected = false;
var clientActive = false;
-var clientTopic;
+var clientTopic = [];
+var alwaysSub = [];
var messageRate = 0;
var messageRateAverage = 10;
+var receiversHidden = false;
+var chaseCarsHidden = false;
+
var pledges = {};
var pledges_loaded = false
@@ -45,10 +52,10 @@ var focusID = 0;
var receiverCanvas = null;
-var sondePrefix = ["RS92", "RS92-SGP", "RS92-NGP", "RS41", "RS41-SG", "RS41-SGP", "RS41-SGM", "DFM", "DFM06", "DFM09", "DFM17", "M10", "M20", "iMet-1", "iMet-4", "iMet-54", "LMS6", "LMS6-400", "LMS6-1680", "iMS-100", "MRZ", "chase"];
+var sondePrefix = ["RS92", "RS92-SGP", "RS92-NGP", "RS41", "RS41-SG", "RS41-SGP", "RS41-SGM", "DFM", "DFM06", "DFM09", "DFM17", "M10", "M20", "PS20", "iMet-1", "iMet-4", "iMet-54", "LMS6", "LMS6-400", "LMS6-1680", "iMS-100", "MRZ", "MTS01", "WxR-301D", "chase"];
var sondeCodes = {
- "07":"iMet-1", "11":"LMS6-403", "13":"RS92", "14":"RS92", "17":"DFM-09", "18":"DFM-06", "19":"MRZ-N1", "22":"RS-11G", "23":"RS41", "24":"RS41", "34":"iMet-4", "35":"iMS-100", "41":"RS41", "42":"RS41", "52":"RS92-NGP",
- "54":"DFM-17", "62":"MRZ-3MK", "63":"M20", "77":"M10", "82":"LMS6-1680", "84":"iMet-54"
+ "07":"iMet-1", "11":"LMS6-403", "13":"RS92", "14":"RS92", "17":"DFM-09", "18":"DFM-06", "19":"MRZ-N1", "22":"RS-11G", "23":"RS41", "24":"RS41", "34":"iMet-4", "35":"iMS-100", "38":"WxR-301D", "41":"RS41", "42":"RS41", "52":"RS92-NGP",
+ "54":"DFM-17", "62":"MRZ-3MK", "63":"M20", "64":"PS20", "65":"MTS01", "77":"M10", "82":"LMS6-1680", "84":"iMet-54"
};
var unsupportedSondeCodes = {
"15":"PAZA-12M", "16":"PAZA-22", "20":"MK3", "21":"1524LA LORAN-C/GL5000", "26":"SRS-C34", "27":"AVK-MRZ", "28":"AVK–AK2-02", "29":"MARZ2-2", "30":"RS2-80", "33":"GTS1-2/GFE(L)", "45":"CF-06", "58":"AVK-BAR",
@@ -62,11 +69,12 @@ var follow_vehicle = null;
var graph_vehicle = null;
var manual_pan = false;
+// NOTE - 'yellow' (was #FDFC30, darker version is "#caca02") has been removed from the rotation
+// due to complaints it was not visible enough. - 2023-06-03
+
var car_index = 0;
-var car_colors = ["blue", "red", "green", "yellow", "teal", "purple"];
-var balloon_index = 0;
-var balloon_colors_name = ["red", "blue", "green", "yellow", "purple", "orange", "cyan"];
-var balloon_colors = ["#f00", "blue", "green", "#FDFC30", "#c700e6", "#ff8a0f", "#0fffca"];
+var car_colors = ["#a6cee3", "#1f78b4", "#fb9a99", "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6"];
+var balloon_colors = ["#d95f02", "#7570b3", "#e7298a", "#e6ab02", "#a6761d", "#666666", "blue", "magenta", "#ffb300", "rebeccapurple"];
var nyan_color_index = 0;
var nyan_colors = ['nyan', 'nyan-coin', 'nyan-mon', 'nyan-pirate', 'nyan-cool', 'nyan-tothemax', 'nyan-pumpkin', 'nyan-afro', 'nyan-coin', 'nyan-mummy'];
@@ -160,7 +168,8 @@ var v1manufacturers = {
"LMS6-400": "Lockheed Martin",
"LMS6-1680": "Lockheed Martin",
"M10": "Meteomodem",
- "M20": "Meteomodem"
+ "M20": "Meteomodem",
+ "PS20": "Meteomodem"
}
var globalKeys = {
@@ -250,7 +259,12 @@ var globalKeys = {
"pcfh_controller_fw_date": "PCFH Controller Firmware Date",
"pcfh_fpga_fw_date": "PCFH FPGA Firmware Date",
"pcfh_temperature_pcb_date": "PCFH Temperature PCB Manufacture Date",
- "pcfh_main_pcb_date": "PCFH Main PCB Manufacture Date"
+ "pcfh_main_pcb_date": "PCFH Main PCB Manufacture Date",
+ "tacho_uptime": "KNMI Tachometer Uptime",
+ "tacho_delta": "KNMI Tachometer Delta",
+ "tacho_rpm": "KNMI Tachometer RPM",
+ "rs41_mainboard": "RS41 PCB Version",
+ "rs41_mainboard_fw": "RS41 PCB FW"
};
var globalSuffixes = {
@@ -309,6 +323,9 @@ var globalSuffixes = {
"pcfh_peltier_current_02": " A",
"pcfh_reserved_temperature": "°C",
"pcfh_thermocouple_reference_temperature": "°C",
+ "tacho_uptime": " S",
+ "tacho_delta": " s/400rev",
+ "tacho_rpm": " RPM"
};
// localStorage vars
@@ -553,7 +570,7 @@ function makeQuad(x, y, zoom) {
// map type list
-var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
});
@@ -573,12 +590,12 @@ var worldimagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/serv
});
worldimagery.id="WorldImagery";
-var stamen_terrain = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}{r}.png', {
- attribution: 'Map tiles by Stamen Design , CC BY 3.0 — Map data © OpenStreetMap contributors',
- subdomains: 'abcd',
- minZoom: 0,
- maxZoom: 18,
+var stamen_terrain = L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png', {
+ minZoom: 0,
+ maxZoom: 20,
+ attribution: '© Stadia Maps , © OpenMapTiles © OpenStreetMap contributors',
});
+
stamen_terrain.id="Terrain";
var cartodb_voyager = L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
@@ -602,6 +619,16 @@ var getlost = L.tileLayer('https://live.getlost.com.au/{z}/{x}/{y}.jpg', {
});
getlost.id = "GetLost";
+var highSight = L.tileLayer('https://api.highsight.dev/v1/tiles/{z}/{x}/{y}?key=ARX3jYxzWotJVz7ZgdDiMQI18tZJ5WCk', {
+ attribution: '© HighSight ',
+ maxZoom: 9,
+ minZoom: 3,
+ crossOrigin: true
+ });
+
+highSight.id = "HighSight";
+
+
var baseMaps = {
"Mapnik": osm,
"DarkMatter": dark_matter,
@@ -609,10 +636,12 @@ var baseMaps = {
"Terrain": stamen_terrain,
"Voyager": cartodb_voyager,
"OpenTopoMap": opentopomap,
+ "HighSight": highSight
}
var selectedLayer = "Mapnik";
+
// set map if in memory
var maplayer = offline.get("map")
if (maplayer !== null) {
@@ -650,6 +679,63 @@ function throttle_events(event) {
}
}
+function sub_to_nearby_sondes(){
+ let bounds = map.getBounds().pad(1); // expand by one viewport
+ let zoomed_out = map.getZoom() <= 8;
+ const sub_logging = false;
+ if (zoomed_out){
+ // If we are fairly zooomed out - only give the slow feed
+ var newClientTopic=[clientTopic[0]]
+ for(let i = 1; i -1) {
+ clientTopic.splice(topic_index, 1);
+ }
+ }
+ }
+ }
+ }
+ }
+}
function clean_refresh(text, force, history_step) {
force = !!force;
@@ -670,14 +756,18 @@ function clean_refresh(text, force, history_step) {
}
try {
- client.unsubscribe(clientTopic);
+ for (let topic in clientTopic){
+ client.unsubscribe(topic);
+ }
if (wvar.query && sondePrefix.indexOf(wvar.query) == -1) {
var topic = "sondes/" + wvar.query;
client.subscribe(topic);
- clientTopic = topic;
+ client.subscribe("prediction/"+wvar.query);
+ client.subscribe("reverse-prediction/"+wvar.query);
+ clientTopic = [topic];
} else {
- client.subscribe("batch");
- clientTopic = "batch";
+ client.subscribe("sondes-new/#");
+ clientTopic =["sondes-new/#"];
}
} catch (err) {}
@@ -686,7 +776,6 @@ function clean_refresh(text, force, history_step) {
wvar.mode = text;
document.getElementById("timeperiod").value = text;
- document.getElementById("timeperiod").disabled = true;
position_id = 0;
@@ -699,14 +788,13 @@ function clean_refresh(text, force, history_step) {
}
car_index = 0;
- balloon_index = 0;
nyan_color_index = 0;
stopFollow(force);
// add loading spinner in the vehicle list
$('#main .empty').parent().remove();
- $("#main .portrait,#main .landscape").append(
- '