🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh /etc/rc.common
#
# (c) 2010-2024 Cezary Jackiewicz <cezary@eko.one.pl>
#
START=99
start() {
PORT=$(uci -q get 3ginfo.@3ginfo[0].http_port)
[ -z "$PORT" ] && PORT=81
uhttpd -E /index.html -x /cgi-bin -h /usr/share/3ginfo/html -p 0.0.0.0:$PORT -i .sh=/bin/sh > /dev/null 2>&1
}
@@ -0,0 +1,192 @@
label {
font-weight: 400;
text-align: right;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
border-radius: 5px;
}
.section {
border-bottom: 1px dashed #8c8b8b;
}
h3 {
margin-bottom: 20px;
}
#container {
transition: margin-left .5s;
padding: 20px;
}
.click,
.click:hover,
.click:visited,
.click:link {
text-decoration: none;
color: #31708f;
cursor: pointer;
}
.margintop {
margin-top: 10px;
}
@media (max-width: 768px) {
.margintop {
margin-top: -90px;
}
.center-xd {
text-align: center;
}
}
.sizing-box {
height: 110px;
width: 150px;
}
.signal-bars {
display: inline-block;
}
.signal-bars .bar {
width: 14%;
margin-left: 1%;
min-height: 20%;
display: inline-block;
}
.signal-bars .bar.first-bar { height: 20%; }
.signal-bars .bar.second-bar { height: 40%; }
.signal-bars .bar.third-bar { height: 60%; }
.signal-bars .bar.fourth-bar { height: 80%; }
.signal-bars .bar.fifth-bar { height: 99%; }
.lzero .bar {
background-color: #fafafa;
border: thin solid #ccc;
}
.lone .bar {
background-color: #ff0000;
border: thin solid #800000;
}
.ltwo .bar {
background-color: #ff6a00;
border: thin solid #803500;
}
.lthree .bar {
background-color: #ffd800;
border: thin solid #806a00;
}
.lfour .bar {
background-color: #b6ff00;
border: thin solid #558000;
}
.lfive .bar {
background-color: #4cff00;
border: thin solid #2a8000;
}
.four-bars .bar.fifth-bar,
.three-bars .bar.fifth-bar,
.three-bars .bar.fourth-bar,
.one-bar .bar:not(.first-bar),
.two-bars .bar:not(.first-bar):not(.second-bar) {
background-color: #fafafa;
border: thin solid #ccc;
}
.oneline {
clear: both;
}
@media (max-width: 527px) {
.hidden-vxs {
display: none;
}
}
@media (min-width: 578px) and (max-width: 821px) {
.modalmargintop {
margin-top: 5px;
}
}
.error {
color: red;
}
@media (max-width: 768px) {
.col-xs-12-text-left {
text-align: left;
}
}
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}
.tab button:hover {
background-color: #ddd;
}
.tab button.active {
background-color: #ccc;
}
.tabcontent {
display: none;
padding: 6px 12px;
b1order: 1px solid #ccc;
b1order-top: none;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.flex-content {
text-align: center;
}
@@ -0,0 +1,794 @@
function readdata(source, callback) {
var xmlhttp;
try {xmlhttp = new XMLHttpRequest();} catch (e) {
try {xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");} catch (e) {
try {xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");} catch (e) {
alert("Old browser?");
return false;
}
}
}
xmlhttp.open("GET", "/cgi-bin/" + source);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
callback(JSON.parse(xmlhttp.responseText));
}
}
}
xmlhttp.send(null);
}
function translate() {
var lang = navigator.languages ? navigator.languages[0] : navigator.language;
this._lang = lang.substr(0, 2);
// this._lang = 'en';
fetch(`/i18n/${this._lang}.json`)
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Something went wrong');
})
.then((translation) => {
this._translation = translation;
this._elements = document.querySelectorAll("[data-i18n]");
this._elements.forEach((element) => {
var keys = element.dataset.i18n.split(".");
var text = keys.reduce((obj, i) => obj[i], translation);
if (text) {
element.innerHTML = text;
}
});
})
.catch((error) => {
console.log(`Could not load ${this._lang}, en will be used`);
});
}
function _t(text, defaulttext) {
if (this._translation) {
var key = text.replaceAll(' ', '').toLowerCase();
if (key in this._translation) {
return this._translation[key];
}
}
return defaulttext ? defaulttext : text;
}
function info_onload() {
translate();
showmodeminfo();
}
function formatDateTime(s) {
if (s.length == 14) {
return s.replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/, "$1-$2-$3 $4:$5:$6");
} else if (s.length == 12) {
return s.replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/, "$1-$2-$3 $4:$5");
} else if (s.length == 8) {
return s.replace(/(\d{4})(\d{2})(\d{2})/, "$1-$2-$3");
} else if (s.length == 6) {
return s.replace(/(\d{4})(\d{2})/, "$1-$2");
}
return s;
}
function lz(n) {
return (n < 10 ? '0' : '' ) + n;
}
function formatDateTimeForUptime(uptime) {
var d = new Date(new Date().getTime() - uptime * 1000);
return '' +
d.getFullYear() + '-' +
lz(d.getMonth() + 1) + '-' +
lz(d.getDate()) + ' ' +
lz(d.getHours()) + ':' +
lz(d.getMinutes()) + ':' +
lz(d.getSeconds());
}
function createRowForModal(key, value) {
return '<div class="row"><div class="col-xs-5 col-sm-6 text-right">' + key + '</div><div class="col-xs-7 col-sm-6 text-left"><p>' + value + '</p></div></div>';
}
function createRow9ColForModal(arr) {
return '<div class="row">' +
'<div class="col-xs-1 text-right"><p>' + arr[0] + '</p></div>' +
'<div class="col-xs-3 text-left"><p>' + arr[1] + '</p></div>' +
'<div class="col-xs-2 text-left"><p>' + arr[2] + '</p></div>' +
'<div class="col-xs-1 text-left"><p>' + arr[3] + '</p></div>' +
'<div class="col-xs-1 text-left"><p>' + arr[4] + '</p></div>' +
'<div class="col-xs-1 text-left"><p>' + arr[5] + '</p></div>' +
'<div class="col-xs-1 text-left"><p>' + arr[6] + '</p></div>' +
'<div class="col-xs-1 text-left"><p>' + arr[7] + '</p></div>' +
'<div class="col-xs-1 text-left"><p>' + arr[8] + '</p></div>' +
'</div>';
}
/*****************************************************************************/
var modal;
function setValue(element, value) {
var e = document.getElementById(element);
if (e.tagName == "SELECT") {
for (var i = 0; i < e.options.length; i++) {
if (e.options[i].value == value) {
e.selectedIndex = i;
break;
}
}
} else if (e.tagName == "P") {
e.innerHTML = value;
} else if (e.tagName == "H3") {
e.innerHTML = value;
} else if (e.tagName == "SPAN") {
e.innerHTML = value;
} else if (e.tagName == "DIV") {
e.innerHTML = value;
} else if (e.type === 'checkbox') {
e.checked = value;
} else if (e.type === 'radio') {
e.checked = value;
} else {
e.value = value;
}
}
function setDisplay(element, show) {
document.getElementById(element).style.display = (show ? 'block' : 'none');
}
function addClasses(element, classes) {
for (var i = 0; i < classes.length; i++) {
if (!element.className.match(new RegExp('(?:^|\\s)' + classes[i] + '(?!\\S)', 'g')))
element.className += " " + classes[i];
}
}
function removeClasses(element, classes) {
for (var i = 0; i < classes.length; i++) {
element.className = element.className.replace(new RegExp('(?:^|\\s)' + classes[i] + '(?!\\S)', 'g'), '');
}
}
function showMsg(msg, error) {
closeMsg();
if (!msg || 0 === msg.length) { msg = _t('Please wait') + '...'; }
var e = document.getElementById('msgtxt');
e.innerHTML = msg;
if (error) {
e.style.color = 'red';
addClasses(e, ['has-error']);
} else {
e.style.color = null;
removeClasses(e, ['has-error']);
}
modal = document.getElementById('div_msg');
modal.style.display = 'block';
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = 'none';
}
}
}
function closeMsg() {
if (modal) { modal.style.display = 'none'; }
}
function sortJSON(data, key, way) {
return data.sort(function(a, b) {
var x = a[key]; var y = b[key];
if (way === 'asc' ) { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }
if (way === 'desc') { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); }
});
}
function formatDuration(s, showsec) {
if (s === '-') {return '-';}
if (s === '') {return '-';}
var d = Math.floor(s/86400),
h = Math.floor(s/3600) % 24,
m = Math.floor(s/60)%60,
s = s % 60;
var time = d > 0 ? d + 'd ' : '';
if (time != '') {time += h + _t('h') + ' '} else {time = h > 0 ? h + _t('h') + ' ' : ''}
if (time != '') {time += m + 'm '} else {time = m > 0 ? m + 'm ' : ''}
if (showsec) {
time += s + 's';
} else {
if (time == '') { time += m + 'm'; }
}
return time;
}
/*****************************************************************************/
function modem(evt, modem) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(modem).style.display = "block";
evt.currentTarget.className += " active";
}
function showmodeminfo() {
readdata('infoproducts.sh', function(data1) {
var html = '';
if (data1.res.length > 1) {
var htmltab = '<div class="tab">';
(data1.res).forEach(function callback(value, idx) {
var id = (idx == 0 ? 'id="defaultOpen"' : '');
htmltab += '<button class="tablinks" onclick="modem(event, \'modem' + idx + '\')"' + id + '><span id="tabtitle' + idx + '"></span></button>';
html += ('<div id="modem' + idx + '" class="tabcontent">' + document.getElementById('div_template').innerHTML + '</div>').replaceAll('_idx', idx);
});
htmltab += '</div>';
setValue('div_modems', '');
document.getElementById('div_modems').insertAdjacentHTML('beforeend', htmltab + html);
document.getElementById("defaultOpen").click();
} else {
setValue('div_modems', '');
html += ('<div id="modem0">' + document.getElementById('div_template').innerHTML + '</div>').replaceAll('_idx', 0);
document.getElementById('div_modems').insertAdjacentHTML('beforeend', html);
}
(data1.res).forEach(function callback(data, idx) {
setValue('vendor' + idx, data.vendor == '' ? '-' : data.vendor);
setValue('product' + idx, data.product == '' ? '-' : data.product);
if (data1.res.length > 1) {
setValue('tabtitle' + idx, data.product == '' ? 'modem #' + (idx + 1) : data.product);
}
setValue('revision' + idx, data.revision == '' ? '-' : data.revision);
setValue('imei' + idx, data.imei == '' ? '-' : data.imei);
setValue('iccid' + idx, data.iccid == '' ? '-' : data.iccid);
setValue('imsi' + idx, data.imsi == '' ? '-' : data.imsi);
});
showmodemparams();
setInterval(showmodemparams, 10000);
});
}
var arrmodemaddon = [];
function showmodemparams() {
readdata('info.sh', function(data1) {
(data1.res).forEach(function callback(data2, idx) {
var data = data2[0];
setValue('rx' + idx, data.rx == '' ? '-' : data.rx);
setValue('tx' + idx, data.tx == '' ? '-' : data.tx);
setValue('uptime' + idx, formatDuration(data.conn_time_sec, false));
setValue('uptime_since' + idx, ' (' + _t('since') + ' ' + formatDateTimeForUptime(data.conn_time_sec) + ')');
var data = data2[1];
if (data.error)
return;
arrmodemaddon[idx] = [];
switch(data.registration) {
case "0":
setValue('registration' + idx, _t('registered0', 'Not registered'));
break;
case "1":
setValue('registration' + idx, _t('registered1', 'Registered, home network'));
break;
case "2":
setValue('registration' + idx, _t('registered2', 'Not registered, searching'));
break;
case "3":
setValue('registration' + idx, _t('registered3', 'Registration denied'));
break;
case "5":
setValue('registration' + idx, _t('registered5', 'Registered, roaming'));
break;
case "6":
setValue('registration' + idx, _t('registered6', 'Registered for SMS only, home network'));
break;
case "7":
setValue('registration' + idx, _t('registered7', 'Registered for SMS only, roaming'));
break;
default:
setValue('registration' + idx, data.registration == '' ? '-' : data.registration);
}
if (data.registration == '1' || data.registration == '5' || data.registration == '6' || data.registration == '7') {
setValue('signal' + idx, data.signal == '' ? '-' : data.signal + '%');
if (data.signal) {
var e = document.getElementById('signal_bars' + idx);
removeClasses(e, ['lzero', 'lone', 'ltwo', 'lthree', 'lfour', 'lfive', 'one-bar', 'two-bars', 'three-bars', 'four-bars', 'five-bars']);
if (data.signal >= 80) {
addClasses(e, ['lfive', 'five-bars']);
}
if (data.signal < 80 && data.signal >= 60) {
addClasses(e, ['lfour', 'four-bars']);
}
if (data.signal < 60 && data.signal >= 40) {
addClasses(e, ['lthree', 'three-bars']);
}
if (data.signal < 40 && data.signal >= 20) {
addClasses(e, ['ltwo', 'two-bars']);
}
if (data.signal < 20 && data.signal > 0) {
addClasses(e, ['lone', 'one-bar']);
}
if (data.signal == 0) {
addClasses(e, ['lzero', 'one-bar']);
}
}
setValue('operator' + idx, data.operator_name == '' ? '-' : data.operator_name);
var mode = (data.mode == '' ? '-' : data.mode);
if (mode.toLowerCase().includes('lte') || mode.toLowerCase().includes('5g')) {
if (mode.toLowerCase().includes('lte')) {
mode = (data.mode).split(' ')[0];
}
if (mode.toLowerCase().includes('5g')) {
mode = (data.mode).split(' ')[0] + ' ' + (data.mode).split(' ')[1];
}
var count = ((data.mode).match(/\//g) || []).length;
if (count > 0) {
mode += ' (' + (count + 1) + 'CA)';
}
}
setValue('mode' + idx, mode);
arrmodemaddon[idx].push({'idx':1, 'key':'Mode', 'value':data.mode});
if (data.country) {
arrmodemaddon[idx].push({'idx':19, 'key':'Country', 'value':data.country});
}
if (data.operator_mcc && data.operator_mcc != '' && data.operator_mnc && data.operator_mnc != '') {
arrmodemaddon[idx].push({'idx':20, 'key':'MCC MNC', 'value':data.operator_mcc + ' ' + data.operator_mnc});
}
if (data.lac_dec && data.lac_dec > 0) {
arrmodemaddon[idx].push({'idx':22, 'key':'LAC', 'value':data.lac_dec + ' (' + data.lac_hex + ')'});
}
if (data.cid_dec && data.cid_dec > 0) {
arrmodemaddon[idx].push({'idx':21, 'key':'Cell ID', 'value':data.cid_dec + ' (' + data.cid_hex + ')'});
}
if (data.cid_dec && data.cid_dec > 0 && data.operator_mcc == 260) {
document.getElementById('btsearch' + idx).setAttribute("href", "http://www.btsearch.pl/szukaj.php?search=" + data.cid_dec + "&siec=-1&mode=std");
setDisplay('div_btsearch' + idx, true);
} else {
setDisplay('div_btsearch' + idx, false);
}
} else {
setValue('signal' + idx, '-');
var e = document.getElementById('signal_bars' + idx);
removeClasses(e, ['lzero', 'lone', 'ltwo', 'lthree', 'lfour', 'lfive', 'one-bar', 'two-bars', 'three-bars', 'four-bars', 'five-bars']);
addClasses(e, ['lzero', 'one-bar']);
setValue('operator' + idx, '-');
setValue('mode' + idx, '-');
setDisplay('div_btsearch' + idx, false);
}
if (data.addon) {
arrmodemaddon[idx] = arrmodemaddon[idx].concat(data.addon);
}
setDisplay('div_addon' + idx, (arrmodemaddon[idx]).length > 0);
});
});
}
function paramdesc(param, value) {
var pvalue = parseInt(value.split(' ')[0]);
var description = '';
var color = '';
var title = '';
switch(param) {
case 'rssi':
if (pvalue > -65) { color = '#2bdf5a'; description += _t('excellent'); }
if (pvalue > -75 && pvalue <= -65 ) { color = '#efff12'; description += _t('good'); }
if (pvalue > -85 && pvalue <= -75 ) { color = '#f8c200'; description += _t('fair'); }
if (pvalue > -95 && pvalue <= -85 ) { color = '#fa0000'; description += _t('poor'); }
if (pvalue <= -95) { color = '#fa0000'; description += _t('very poor'); }
title += '> -65 dBm ' + _t('excellent') + '\n';
title += '> -75 dBm i <= -65 dBm ' + _t('good') + '\n';
title += '> -85 dBm i <= -75 dBm ' + _t('fair') + '\n';
title += '> -95 dBm i <= -85 dBm ' + _t('poor') + '\n';
title += '<= -95 dBm ' + _t('very poor');
break;
case 'rsrp':
if (pvalue >= -80) { color = '#2bdf5a'; description += _t('excellent'); }
if (pvalue >= -90 && pvalue < -80 ) { color = '#efff12'; description += _t('good'); }
if (pvalue >= -100 && pvalue < -90 ) { color = '#f8c200'; description += _t('fair'); }
if (pvalue < -100) { color = '#fa0000'; description += _t('poor'); }
title += '> -80 dBm ' + _t('excellent') + '\n';
title += '>= -90 dBm i < -80 dBm ' + _t('good') + '\n';
title += '>= -100 dBm i < -90 dBm ' + _t('fair') + '\n';
title += '< -100 dBm ' + _t('poor');
break;
case 'rsrq':
if (pvalue >= -10) { color = '#2bdf5a'; description += _t('excellent'); }
if (pvalue >= -15 && pvalue < -10 ) { color = '#efff12'; description += _t('good'); }
if (pvalue >= -20 && pvalue < -15 ) { color = '#f8c200'; description += _t('fair'); }
if (pvalue < -20) { color = '#fa0000'; description += _t('poor'); }
title += '>= -10 dB ' + _t('excellent') + '\n';
title += '>= -15 dB i < -10 dB ' + _t('good') + '\n';
title += '>= -20 dB i < -15 dB ' + _t('fair') + '\n';
title += '< -20 dB ' + _t('poor');
break;
}
return ', <span style="color:' + color + '" title="' + title + '">' + description + '</span>';
}
function modemaddon(idx) {
var htmlco = '';
var htmlxs = '';
var html = '';
var pcc = [];
var scc1 = [];
var scc2 = [];
var scc3 = [];
var scc4 = [];
var ulscc = [];
var sorted = sortJSON(arrmodemaddon[idx], 'idx', 'asc');
sorted.forEach(function(e) {
var description = '';
switch (e.idx) {
// MODE
case 1:
if ((e.value).search(/^LTE B/) > -1 || (e.value).search(/^LTE-A B/) > -1) {
pcc[1] = (e.value).replace(/^LTE /, '').replace(/^LTE-A /, '');
}
if ((e.value).search(/^5G/) > -1) {
pcc[1] = (e.value).replace(/^5G NSA /, '').replace(/^5G SA /, '');
}
break;
// PCC
case 30:
if ((e.value).includes(' @')) {
pcc[1] = (e.value).split(' @')[0];
pcc[2] = (e.value).split(' @')[1];
} else {
pcc[1] = e.value;
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 31:
pcc[2] = e.value;
htmlxs += createRowForModal(e.key, e.value);
break;
case 32:
if (typeof pcc[2] === 'undefined') {
pcc[2] = e.value;
} else {
pcc[2] = e.value + ' DL<br>' + pcc[2] + ' UL'
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 33:
pcc[3] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 34:
if ((e.key).toLowerCase().includes('earfcn ul')) {
if (typeof pcc[4] === 'undefined') {
pcc[4] = e.value + ' UL';
} else {
pcc[4] = pcc[4] + ' DL<br>' + e.value + ' UL';
}
} else {
if (typeof pcc[4] === 'undefined') {
pcc[4] = e.value;
} else {
pcc[4] = e.value + ' DL<br>' + pcc[4];
}
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 35:
description = paramdesc('rssi', e.value);
pcc[5] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 36:
description = paramdesc('rsrp', e.value);
pcc[6] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 37:
description = paramdesc('rsrq', e.value);
pcc[7] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 38:
if ((e.key).toLowerCase().includes('sinr')) {
pcc[8] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
// SCC1
case 50:
if ((e.value).includes(' @')) {
scc1[1] = (e.value).split(' @')[0];
scc1[2] = (e.value).split(' @')[1];
} else {
scc1[1] = e.value;
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 52:
scc1[2] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 53:
scc1[3] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 54:
if (!(e.key).toLowerCase().includes('earfcn ul')) {
scc1[4] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 55:
description = paramdesc('rssi', e.value);
scc1[5] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 56:
description = paramdesc('rsrp', e.value);
scc1[6] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 57:
description = paramdesc('rsrq', e.value);
scc1[7] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 58:
if ((e.key).toLowerCase().includes('sinr')) {
scc1[8] = e.value;
} else {
html += createRowForModal(e.key, e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
// SCC2
case 60:
if ((e.value).includes(' @')) {
scc2[1] = (e.value).split(' @')[0];
scc2[2] = (e.value).split(' @')[1];
} else {
scc2[1] = e.value;
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 62:
scc2[2] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 63:
scc2[3] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 64:
if (!(e.key).toLowerCase().includes('earfcn ul')) {
scc2[4] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 65:
description = paramdesc('rssi', e.value);
scc2[5] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 66:
description = paramdesc('rsrp', e.value);
scc2[6] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 67:
description = paramdesc('rsrq', e.value);
scc2[7] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 68:
if ((e.key).toLowerCase().includes('sinr')) {
scc2[8] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
// SCC3
case 70:
if ((e.value).includes(' @')) {
scc3[1] = (e.value).split(' @')[0];
scc3[2] = (e.value).split(' @')[1];
} else {
scc3[1] = e.value;
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 72:
scc3[2] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 73:
scc3[3] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 74:
if (!(e.key).toLowerCase().includes('earfcn ul')) {
scc3[4] = e.value;
} else {
html += createRowForModal(e.key, e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 75:
description = paramdesc('rssi', e.value);
scc3[5] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 76:
description = paramdesc('rsrp', e.value);
scc3[6] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 77:
description = paramdesc('rsrq', e.value);
scc3[7] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 78:
if ((e.key).toLowerCase().includes('sinr')) {
scc3[8] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
// SCC4
case 80:
if ((e.value).includes(' @')) {
scc4[1] = (e.value).split(' @')[0];
scc4[2] = (e.value).split(' @')[1];
} else {
scc4[1] = e.value;
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 82:
scc4[2] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 83:
scc4[3] = e.value;
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 84:
if (!(e.key).toLowerCase().includes('earfcn ul')) {
scc4[4] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 85:
description = paramdesc('rssi', e.value);
scc4[5] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 86:
description = paramdesc('rsrp', e.value);
scc4[6] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 87:
description = paramdesc('rsrq', e.value);
scc4[7] = e.value + description.replace(', ', '<br>');
htmlxs += createRowForModal(_t(e.key), e.value + description);
break;
case 88:
if ((e.key).toLowerCase().includes('sinr')) {
scc4[8] = e.value;
} else {
html += createRowForModal(_t(e.key), e.value);
}
htmlxs += createRowForModal(_t(e.key), e.value);
break;
case 150:
ulscc[1] = e.value;
htmlxs += createRowForModal(e.key, e.value);
break;
case 152:
ulscc[2] = e.value;
htmlxs += createRowForModal(e.key, e.value);
break;
case 153:
ulscc[3] = e.value;
htmlxs += createRowForModal(e.key, e.value);
break;
case 154:
ulscc[4] = e.value;
htmlxs += createRowForModal(e.key, e.value);
break;
default:
if (e.idx < 30) {
htmlco += createRowForModal(_t(e.key), e.value);
} else {
html += createRowForModal(_t(e.key), e.value);
htmlxs += createRowForModal(_t(e.key), e.value);
}
}
});
htmlco += '<div class="visible-xs-block visible-sm-block">' + htmlxs + '</div>';
if (pcc.length + scc1.length + scc2.length + scc3.length + scc4.length > 0) {
htmlco += '<div class="margintop hidden-xs hidden-sm">' + html;
if (pcc.length > 0) {
pcc[0] = 'PCC';
for (var idx = 0; idx <= 9; idx++) {
if (typeof pcc[idx] === 'undefined') { pcc[idx] = '-'; }
}
htmlco += createRow9ColForModal(['', _t('Band'), _t('Bandwidth'), 'PCI', 'EARFCN', 'RSSI', 'RSRP', 'RSRQ', 'SINR']);
htmlco += createRow9ColForModal(pcc);
}
if (scc1.length > 0) {
scc1[0] = 'SCC1';
for (var idx = 0; idx <= 9; idx++) {
if (typeof scc1[idx] === 'undefined') { scc1[idx] = '-'; }
}
htmlco += createRow9ColForModal(scc1);
}
if (scc2.length > 0) {
scc2[0] = 'SCC2';
for (var idx = 0; idx <= 9; idx++) {
if (typeof scc2[idx] === 'undefined') { scc2[idx] = '-'; }
}
htmlco += createRow9ColForModal(scc2);
}
if (scc3.length > 0) {
scc3[0] = 'SCC3';
for (var idx = 0; idx <= 9; idx++) {
if (typeof scc3[idx] === 'undefined') { scc3[idx] = '-'; }
}
htmlco += createRow9ColForModal(scc3);
}
if (scc4.length > 0) {
scc4[0] = 'SCC4';
for (var idx = 0; idx <= 9; idx++) {
if (typeof scc4[idx] === 'undefined') { scc4[idx] = '-'; }
}
htmlco += createRow9ColForModal(scc4);
}
if (ulscc.length > 0) {
ulscc[0] = 'UL SCC';
for (var idx = 0; idx <= 9; idx++) {
if (typeof ulscc[idx] === 'undefined') { ulscc[idx] = '-'; }
}
htmlco += createRow9ColForModal(ulscc);
}
htmlco += '</div>';
}
showMsg(htmlco);
}
/*****************************************************************************/
window.onload = info_onload;
@@ -0,0 +1,7 @@
/*!
* Generated using the Bootstrap Customizer (https://getbootstrap.com/docs/3.4/customize/)
*//*!
* Bootstrap v3.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{color:#000 !important;text-shadow:none !important;background:transparent !important;-webkit-box-shadow:none !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.Line truncated
+53
View File
@@ -0,0 +1,53 @@
#!/bin/sh
#
# (c) 2024-2025 Cezary Jackiewicz <cezary@eko.one.pl>
#
. /lib/functions.sh
RES="/usr/share/modemdata"
ECM=""
SEPARATOR=""
parse_section() {
[ -n "$SEPARATOR" ] && echo "$SEPARATOR"
local section="$1"
config_get device "$section" device ""
config_get network "$section" network ""
config_get force_plmn "$section" force_plmn "0"
if echo "x$device" | grep -q "192.168."; then
ECM="$RES/addon/ecm/huawei.sh $device"
else
ECM=""
if [ ! -e /var/state/3ginfo-detected ]; then
[ -z "$device" ] && device=$(/usr/share/3ginfo/detectdevice.sh)
[ -z "$network" ] && network=$(/usr/share/3ginfo/detectsection.sh "$section")
fi
config_get pincode "$section" pincode ""
if [ -n "$pincode" ] && [ ! -e /var/state/3ginfo-pincode ]; then
[ -n "$device" ] && sms_tool -d "$device" at "at+cpin=\"$pincode\""
fi
fi
echo "["
$RES/network.sh "$network" | tr -d '\n'
echo ","
if [ -n "$ECM" ]; then
$ECM params
else
$RES/params.sh "$device" "$force_plmn" | tr -d '\n'
fi
echo "]"
SEPARATOR=","
}
config_load 3ginfo
echo -e "Content-type: application/json\n\n"
echo '{"res":['
config_foreach parse_section 3ginfo
echo ']}'
touch /var/state/3ginfo-detected
touch /var/state/3ginfo-pincode
exit 0
@@ -0,0 +1,42 @@
#!/bin/sh
#
# (c) 2024-2025 Cezary Jackiewicz <cezary@eko.one.pl>
#
. /lib/functions.sh
RES="/usr/share/modemdata"
SEPARATOR=""
parse_section() {
[ -n "$SEPARATOR" ] && echo "$SEPARATOR"
local section="$1"
local device
local network
config_get device "$section" device ""
if echo "x$device" | grep -q "192.168."; then
$RES/addon/ecm/huawei.sh $device product
else
if [ ! -e /var/state/3ginfo-detected ]; then
[ -z "$device" ] && device=$(/usr/share/3ginfo/detectdevice.sh)
fi
config_get pincode "$section" pincode ""
if [ -n "$pincode" ] && [ ! -e /var/state/3ginfo-pincode ]; then
[ -n "$device" ] && sms_tool -d "$device" at "at+cpin=\"$pincode\""
fi
$RES/product.sh "$device" | tr -d '\n'
fi
SEPARATOR=","
}
config_load 3ginfo
echo -e "Content-type: application/json\n\n"
echo '{"res":['
config_foreach parse_section 3ginfo
echo ']}'
touch /var/state/3ginfo-detected
touch /var/state/3ginfo-pincode
exit 0
@@ -0,0 +1,4 @@
/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?: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,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
@@ -0,0 +1,39 @@
{
"device": "Urządzenie",
"vendor": "Producent",
"product": "Model",
"revision": "Wersja",
"imei": "Identyfikator modemu (IMEI)",
"iccid": "Numer karty SIM (ICCID)",
"imsi": "Identyfikator abonenta (IMSI)",
"parameters": "Parametry",
"signal": "Sygnał",
"mode": "Technologia",
"simstatus": "Status karty SIM",
"more": "więcej parametrów",
"btslocation": "lokalizacja stacji bazowej",
"connection": "Połączenie z internetem",
"connectiontime": "Czas połączenia",
"tx": "Wysłano",
"rx": "Pobrano",
"registered0": "Brak sieci",
"registered1": "Zalogowana do sieci macierzystej",
"registered2": "Wyszukiwanie operatora",
"registered3": "Odmowa dostępu",
"registered5": "Zalogowana do sieci w roamingu",
"registered6": "Zalogowana do sieci macierzystej, tylko SMS",
"registered7": "Zalogowana do sieci w roamingu, tylko SMS",
"since": "od",
"h": "g",
"temperature": "Temperatura",
"band": "Pasmo",
"primaryband": "Pasmo podstawowe",
"bandwidth": "Szerokość",
"excellent": "doskonały",
"good": "dobry",
"fair": "słaby",
"poor": "zły",
"verypoor": "bardzo zły",
"pleasewait": "Proszę czekać",
"country": "Kraj"
}
@@ -0,0 +1,145 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="cezary@eko.one.pl">
<title>3G/4G/5G</title>
<link href="/bootstrap.min.css?v=1" rel="stylesheet">
<!--[if lt IE 9]>
<script src="/html5shiv.min.js?v=1"></script>
<script src="/respond.min.js?v=1"></script>
<![endif]-->
<link href="/3ginfo.css?v=1" rel="stylesheet">
<script src="/3ginfo.js?v=1"></script>
</head>
<body>
<div class="container">
<div id="div_content">
<div id="div_template" style="display:none">
<h3 class="section" data-i18n="device">Device</h3>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="vendor">Vendor</div>
<div class="col-xs-6">
<p id="vendor_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="product">Product</div>
<div class="col-xs-6">
<p id="product_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="revision">Revision</div>
<div class="col-xs-6">
<p id="revision_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="imei">International Mobile Equipment Identity (IMEI)</div>
<div class="col-xs-6">
<p id="imei_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="iccid">SIM number (ICCID)</div>
<div class="col-xs-6">
<p id="iccid_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="imsi">International Mobile Subscriber Identity (IMSI)</div>
<div class="col-xs-6">
<p id="imsi_idx">-</p>
</div>
</div>
<h3 class="section" data-i18n="parameters">Parameters</h3>
<div class="row">
<div class="col-sm-8">
<div class="row">
<div class="col-xs-6 text-right" data-i18n="operator">Operator</div>
<div class="col-xs-6">
<p id="operator_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="signal">Signal</div>
<div class="col-xs-6">
<p id="signal_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="mode">Mode</div>
<div class="col-xs-6">
<p id="mode_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="simstatus">SIM status</div>
<div class="col-xs-6">
<p id="registration_idx">-</p>
</div>
</div>
<div class="row" id="div_addon_idx" style="display:none;">
<div class="col-xs-6 col-xs-offset-6">
<p><a href="#" class="click" onclick="modemaddon(_idx);" data-i18n="more">more parameters</a></p>
</div>
</div>
<div class="row" id="div_btsearch_idx" style="display:none;">
<div class="col-xs-6 col-xs-offset-6">
<p><a href="#" id="btsearch_idx" class="click" target="_blank" data-i18n="btslocation">BTS location</a>&nbsp;&rarr;</p>
</div>
</div>
</div>
<div class="col-sm-4 center-xd">
<div class="signal-bars sizing-box lzero one-bar" id="signal_bars_idx">
<div class="first-bar bar"></div>
<div class="second-bar bar"></div>
<div class="third-bar bar"></div>
<div class="fourth-bar bar"></div>
<div class="fifth-bar bar"></div>
</div>
</div>
</div>
<h3 class="section" data-i18n="connection">Connection</h3>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="connectiontime">Connection time</div>
<div class="col-xs-6">
<p><span id="uptime_idx">-</span><span class="visible-xs oneline"></span><span id="uptime_since_idx"></span></p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="tx">Uploaded</div>
<div class="col-xs-6">
<p id="tx_idx">-</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right" data-i18n="rx">Downloaded</div>
<div class="col-xs-6">
<p id="rx_idx">-</p>
</div>
</div>
</div>
<div id="div_modems">
<div class="flex-center position-ref full-height">
<div class="flex-content">
<div data-i18n="pleasewait">Please wait</div>
</div>
</div>
</div>
</div>
<div id="div_msg" class="modal">
<div id="msgtxt" class="modal-content text-center" data-i18n="pleasewait">Please wait</div>
</div>
<div class="text-center">&nbsp;</div>
</body>
</html>
@@ -0,0 +1,5 @@
/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
* */
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();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))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);