Select Git revision
status-page.js
Forked from
firmware / FFS Gluon
Source project has a limited visibility.
status-page.js 7.98 KiB
"use strict";!function(){var t=JSON.parse(document.body.getAttribute("data-translations"));function e(e,n){return e.toFixed(n).replace(/\./,t["."])}function n(t,n){n--;for(var i=t;i>=10&&n>0;i/=10)n--;return e(t,n)}function i(t){return function(t,e,i){for(var r=0;i>e&&r<t.length-1;)i/=e,r++;return(i=n(i,3))+" "+t[r]}(["","K","M","G","T"],1024,t)}String.prototype.sprintf=function(){var t=0,e=arguments;return this.replace(/%s/g,function(){return e[t++]})};var r={id:function(t){return t},decimal:function(t){return e(t,2)},percent:function(e){return t["%s used"].sprintf(n(100*e,3)+"%")},memory:function(t){var e=1-(t.free+t.buffers+t.cached)/t.total;return r.percent(e)},time:function(e){var n=Math.round(e/60),i=Math.floor(n/1440),r=Math.floor(n%1440/60);n=Math.floor(n%60);var a="";return 1===i?a+=t["1 day"]+", ":i>1&&(a+=t["%s days"].sprintf(i)+", "),a+=r+":",n<10&&(a+="0"),a+=n},packetsDiff:function(n,i,r){if(r>0)return a=(n-i)/r,t["%s packets/s"].sprintf(e(a,0));var a},bytesDiff:function(t,e,n){if(n>0)return i(8*((t-e)/n))+"bps"},bytes:function(t){return i(t)+"B"}};function a(t,e){return e.split("/").forEach(function(e){t&&(t=t[e])}),t}function o(t,e){var n=new EventSource(t),i={};n.onmessage=function(t){var n=JSON.parse(t.data);e(n,i),i=n},n.onerror=function(){n.close(),window.setTimeout(function(){o(t,e)},3e3)}}var c,s=document.body.getAttribute("data-node-address");try{c=JSON.parse(document.body.getAttribute("data-node-location"))}catch(t){}var u=document.querySelectorAll("[data-statistics]");o("/cgi-bin/dyn/statistics",function(e,n){var i=e.uptime-n.uptime;u.forEach(function(t){var o=t.getAttribute("data-statistics"),c=t.getAttribute("data-format"),s=a(n,o),u=a(e,o);try{var l=r[c](u,s,i);void 0!==l&&(t.textContent=l)}catch(t){console.error(t)}});try{!function(e){var n=document.getElementById("mesh-vpn");if(e){n.style.display="";for(var i=document.getElementById("mesh-vpn-peers");i.lastChild;)i.removeChild(i.lastChild);var a=function t(e,n){return Object.keys(n.peers||{}).forEach(function(t){e.push([t,n.peers[t]])}),Object.keys(n.groups||{}).forEach(function(i){t(e,n.groups[i])}),e}([],e);a.sort(),a.forEach(function(e){var n=document.createElement("tr"),a=document.createElement("th");a.textContent=e[0],n.appendChild(a);var o=document.createElement("td");e[1]?o.textContent=t.connected+" ("+r.time(e[1].established)+")":o.textContent=t["not connected"],n.appendChild(o),i.appendChild(n)})}else n.style.display="none"}(e.mesh_vpn)}catch(t){console.error(t)}});var l={};function h(t){var e=document.createElement("canvas"),n=e.getContext("2d"),i=null,r=1.2;return{canvas:e,highlight:!1,resize:function(t,i){try{n.getImageData(0,0,t,i)}catch(t){}e.width=t,e.height=i},draw:function(a,o){var c,s,u=o(i);n.clearRect(a,0,5,e.height),u&&(c=a,s=u,n.beginPath(),n.fillStyle=t,n.arc(c,s,r,0,2*Math.PI,!1),n.closePath(),n.fill())},set:function(t){i=t}}}function f(){var t=-100,e=0,n=0,i=[],r=document.createElement("canvas");r.className="signalgraph",r.height=200;var a=r.getContext("2d");function o(){r.width=r.clientWidth,i.forEach(function(t){t.resize(r.width,r.height)})}function c(){if(0!==r.clientWidth){r.width!==r.clientWidth&&o(),a.clearRect(0,0,r.width,r.height);var c=!1;i.forEach(function(t){t.highlight&&(c=!0)}),a.save(),i.forEach(function(i){c&&(a.globalAlpha=.2),i.highlight&&(a.globalAlpha=1),i.draw(n,function(n){return i=n,a=t,o=e,c=r.height,(1-(i-a)/(o-a))*c;var i,a,o,c}),a.drawImage(i.canvas,0,0)}),a.restore(),a.save(),a.beginPath(),a.strokeStyle="rgba(255, 180, 0, 0.15)",a.lineWidth=5,a.moveTo(n+2.5,0),a.lineTo(n+2.5,r.height),a.stroke(),function(){var n,i,o,c,s=Math.floor(r.height/40);a.save(),a.lineWidth=.5,a.strokeStyle="rgba(0, 0, 0, 0.25)",a.fillStyle="rgba(0, 0, 0, 0.5)",a.textAlign="end",a.textBaseline="bottom",a.beginPath();for(var u=0;u<s;u++){var l=r.height-40*u;a.moveTo(0,l-.5),a.lineTo(r.width,l-.5);var h=Math.round((n=l,i=t,o=e,c=r.height,(i*n+o*(c-n))/c))+" dBm";a.save(),a.strokeStyle="rgba(255, 255, 255, 0.9)",a.lineWidth=4,a.miterLimit=2,a.strokeText(h,r.width-5,l-2.5),a.fillText(h,r.width-5,l-2.5),a.restore()}a.stroke(),a.strokeStyle="rgba(0, 0, 0, 0.83)",a.lineWidth=1.5,a.strokeRect(.5,.5,r.width-1,r.height-1),a.restore()}()}}o(),window.addEventListener("resize",c);var s=0;return window.requestAnimationFrame(function t(e){e-s>40&&(c(),n=(n+1)%r.width,s=e),window.requestAnimationFrame(t)}),{el:r,addSignal:function(t){i.push(t),t.resize(r.width,r.height)},removeSignal:function(t){i.splice(i.indexOf(t),1)}}}function d(t,e,n,i){var r=t.table.insertRow(),a=r.insertCell();if(t.wireless){var o=document.createElement("span");o.textContent="⬤ ",o.style.color=n,a.appendChild(o)}var u=document.createElement("span");u.textContent=e,a.appendChild(u);var l,f,d,g,v,m=r.insertCell();function p(){v&&window.clearTimeout(v),v=window.setTimeout(function(){g&&t.signalgraph.removeSignal(g),r.parentNode.removeChild(r),i()},6e4)}function b(t){var e=function(t){"::"==t.slice(0,2)&&(t="0"+t),"::"==t.slice(-2)&&(t+="0");var e=t.split(":"),n=e.length,i=[];return e.forEach(function(t,e){if(""===t)for(;n++<=8;)i.push(0);else{if(!/^[a-f0-9]{1,4}$/i.test(t))return;i.push(parseInt(t,16))}}),i}(t);if(e){var n="";return e.forEach(function(t){n+=("0000000000000000"+t.toString(2)).slice(-16)}),n}}return m.textContent="-",t.wireless&&((l=r.insertCell()).textContent="-",(f=r.insertCell()).textContent="-",(d=r.insertCell()).textContent="-",g=h(n),t.signalgraph.addSignal(g)),r.onmouseenter=function(){r.classList.add("highlight"),g&&(g.highlight=!0)},r.onmouseleave=function(){r.classList.remove("highlight"),g&&(g.highlight=!1)},p(),{update_nodeinfo:function(t){var e,n,i,r,a,o,l,h,d=function(t){var e=b(s);if(t&&t[0]){(t=t.map(function(t){var n=b(t);if(!n)return[-1];var i=0;return e&&(i=function(t,e){var n;for(n=0;n<t.length&&n<e.length&&t[n]===e[n];n++);return n}(e,n)),[i,n,t]})).sort(function(t,e){return t[0]<e[0]?1:t[0]>e[0]?-1:t[1]<e[1]?-1:t[1]>e[1]?1:0});var n=t[0][2];return n&&!/^fe80:/i.test(n)?n:void 0}}(t.network.addresses);if(d){if("span"===u.nodeName.toLowerCase()){var g=u;u=document.createElement("a"),g.parentNode.replaceChild(u,g)}u.href="http://["+d+"]/"}if(u.textContent=t.hostname,c&&t.location){var v=(e=c.latitude,n=c.longitude,i=t.location.latitude,r=t.location.longitude,a=Math.PI/180,o=(i*=a)-(e*=a),l=(r*=a)-(n*=a),h=Math.sin(o/2)*Math.sin(o/2)+Math.sin(l/2)*Math.sin(l/2)*Math.cos(e)*Math.cos(i),2*Math.asin(Math.sqrt(h))*6372.8);f.textContent=Math.round(1e3*v)+" m"}p()},update_mesh:function(t){m.textContent=Math.round(t.tq/2.55)+" %",p()},update_wifi:function(t){l.textContent=t.signal,d.textContent=Math.round(t.inactive/1e3)+" s",r.classList.toggle("inactive",t.inactive>200),g.set(t.inactive>200?null:t.signal),p()}}}function g(t,e,n){var i,r={};n&&(i=f(),t.appendChild(i.el));var a={table:t.firstElementChild,signalgraph:i,ifname:e,wireless:n},c=!1,s={},u=[];function l(){if(!c){c=!0;var t=new EventSource("/cgi-bin/dyn/neighbours-nodeinfo?"+encodeURIComponent(e));t.addEventListener("neighbour",function(t){try{var e=JSON.parse(t.data);(n=e,i=[],a=n.network.mesh,Object.keys(a).forEach(function(t){var e=a[t].interfaces;Object.keys(e).forEach(function(t){e[t].forEach(function(t){i.push(t)})})}),i).forEach(function(t){var n=r[t];if(n){delete s[t];try{n.update_nodeinfo(e)}catch(t){console.error(t)}}})}catch(t){console.error(t)}var n,i,a},!1),t.onerror=function(){t.close(),c=!1,Object.keys(s).forEach(function(t){s[t]>0&&(s[t]--,l())})}}}function h(t){var e=r[t];return e||(s[t]=3,e=r[t]=d(a,t,(u[0]||(u=["#396AB1","#DA7C30","#3E9651","#CC2529","#535154","#6B4C9A","#922428","#948B3D"]),u.shift()),function(){delete s[t],delete r[t]}),l()),e}return n&&o("/cgi-bin/dyn/stations?"+encodeURIComponent(e),function(t){Object.keys(t).forEach(function(e){var n=t[e];h(e).update_wifi(n)})}),{get_neigh:h}}document.querySelectorAll("[data-interface]").forEach(function(t){var e=t.getAttribute("data-interface"),n=(t.getAttribute("data-interface-address"),!!t.getAttribute("data-interface-wireless"));l[e]=g(t,e,n)}),o("/cgi-bin/dyn/neighbours-batadv",function(t){Object.keys(t).forEach(function(e){var n=t[e],i=l[n.ifname];i&&i.get_neigh(e).update_mesh(n)})})}();