oscam-2.26.01-11942-802-wit.../webif/include/jscript.js
2026-02-17 10:06:53 +00:00

3032 lines
96 KiB
JavaScript
Executable File

var oReloadTimer = null;
var oCounterTimer = null;
function reloadDocument() {
if(!withquery) history.pushState('', document.title, window.location.pathname);
else if (window.location.href.match(/(&|&)action=\w+/)) history.pushState('', document.title, window.location.href.replace(/(&|&)action=\w+/,''));
window.location.reload();
};
function cdpause() {
clearTimeout(oReloadTimer);
};
function runReloadCounter() {
var oReloadContent = document.getElementById("ReloadContent");
if (oReloadContent) {
if (counter < 0) {
counter = counterfull;
}
counter--;
}
};
function initDoc() {
if (oReloadTimer) window.clearInterval(oReloadTimer);
oReloadTimer = window.setInterval("reloadDocument();", counterfull * 1000);
if (oCounterTimer) window.clearInterval(oCounterTimer);
oCounterTimer = window.setInterval("runReloadCounter();", 1000);
};
/* Function for add new reader/user in readers.html/userconfig.html */
function addinsert() {
cdpause();
$("#searchTable").fadeOut('slow', function() {
$("#newinsert").fadeIn('slow');
});
}
/* Function for add new reader/user in readers.html/userconfig.html */
function chkinsert(chkvalue) {
if(existing_inserts.indexOf(encodeURIComponent(chkvalue))!=-1){
alert('Entry "' + chkvalue + '" already exists!');
return false;
}
}
/* Function for del entry in readers.html/userconfig.html */
function cleaninsert(deleteinsert) {
var tmp_array = existing_inserts.slice();
existing_inserts.length = 0;
var i2 = 0;
for (i = 0; i < tmp_array.length; i++) {
if (tmp_array[i] != deleteinsert){
existing_inserts[i2] = tmp_array[i];
i2++;
}
}
}
var beep = (function () {
var contextClass = (window.AudioContext ||
window.webkitAudioContext ||
window.mozAudioContext ||
window.oAudioContext ||
window.msAudioContext);
if (contextClass) {
var ctx = new contextClass();
return function (duration, type, freq, vol, finishedCallback) {
duration = +duration;
// Only 0-4 are valid types.
type = (type % 5) || 0;
if (typeof finishedCallback != "function") {
finishedCallback = function () {};
}
var osc = ctx.createOscillator();
var gainNode = ctx.createGain();
osc.type = type;
osc.connect(gainNode);
gainNode.connect(ctx.destination);
gainNode.gain.value = vol;
osc.type = type;
osc.frequency.value = freq; // value in hertz
osc.detune.value = 100; // value in cents
osc.start(0);
setTimeout(function () {
osc.stop(0);
finishedCallback();
}, duration);
};
} else {
return function (duration, type, freq, vol, finishedCallback) {return;};
}
})();
String.prototype.toHHMMSS = function () {
if (this.length < 1) {
return ''
}
var sec_num = parseInt(this, 10); // don't forget the second param
var years = Math.floor(sec_num / (86400*365));
var days = Math.floor(sec_num / 86400);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
hours = hours - (24 * days);
days = days - (365 * years);
if (years < 1) {
years = "";
} else {
years = years + "y ";
}
if (days < 1) {
days = "";
} else {
days = days + "d ";
}
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
var time = days + hours + ':' + minutes + ':' + seconds;
return time;
}
/*
* General: Eventhandler
*/
$(function () {
// Pollinterval UP
$("#inc").click(function () {
if (pollintervall > 98000 || polling) return;
$(":text[name='pintervall']").val(Number($(":text[name='pintervall']").val()) + 1);
pollintervall = $(":text[name='pintervall']").val() * 1000;
if (!nostorage) {
sessionStorage.pollintervall = pollintervall;
}
});
// Pollinterval PAUSE
$("#polling").click(function () {
if (polling < 1) {
polling = 1;
$(":text[name='pintervall']").val('--');
$('#polling').attr('class','pollingdisabled');
$('#inc, #dec').attr('disabled','disabled');
} else {
polling = 0;
$(":text[name='pintervall']").val(pollintervall/1000);
$('#polling').attr('class','pollingenabled');
$('#inc, #dec').removeAttr('disabled');
clearTimeout(timer_ID);
timer_ID = setTimeout("waitForMsg()", pollintervall);
}
if (!nostorage) {
sessionStorage.polling = polling;
}
});
// Pollinterval DOWN
$("#dec").click(function () {
if (pollintervall < 2000 || polling) return;
$(":text[name='pintervall']").val(Number($(":text[name='pintervall']").val()) - 1);
pollintervall = $(":text[name='pintervall']").val() * 1000;
if (!nostorage) {
sessionStorage.pollintervall = pollintervall;
}
});
// Hover for showing Chart on Statuspage
$('table.status').on('mouseover', 'tr > td.statuscol14', function (e) {
var uid = '#' + $(this).parent().attr('id');
if ('pcr'.indexOf($(uid).attr('class')) >= 0) {
if ($(uid).data('ecmhistory')) {
var head = $(uid + ' > td:nth-child(3)').attr('title').indexOf('(') > -1 ? $(uid + ' > td:nth-child(3)').attr('title').substring(0, $(uid + ' > td:nth-child(3)').attr('title').indexOf('(')-1) : $(uid + ' > td:nth-child(3)').attr('title');
$('#charthead').text(head + ' History');
$("#graph").html('');
var arry = $(uid).data('ecmhistory').split(",");
$.each(arry, function (index, value) {
$("#graph").append(generateBar(value));
});
$("#chart").show();
}
$("#chart").offset({
left: e.pageX + 20,
top: e.pageY - 20
});
}
});
// Mousout for hiding Chart on Statuspage
$('table.status').on('mouseout', 'tr > td.statuscol14', function () {
$("#chart").hide();
});
$("#add1regex").click(function () {
if (MAX_SEARCH_PATTERN > 98) return;
MAX_SEARCH_PATTERN++;
localStorage.MAX_SEARCH_PATTERN = MAX_SEARCH_PATTERN;
var i = MAX_SEARCH_PATTERN;
var beep_disabled = ' disabled="disabled" title="Not supported by your browser"';
var contextClass = (window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext);
if (contextClass) { beep_disabled = ''; }
var prefix = "0";
if ( i > 9 ) { prefix = ""; }
$('<LI class="regex" id="regexrow' + i + '">Search' + prefix + i + ': <input type="text" name="regex' + i + '" class="regexinput" ID="regex' + i + '" value=""> Found only: <input type="checkbox" id="whitelisted' + i + '"><label></label> Hide: <input type="checkbox" id="hidden' + i + '"><label></label> Back Color: <input size="7" maxlength="7" type="text" name="color' + i + '" class="colorinput" ID="color' + i + '" value=""> Color: <input size="7" maxlength="7" type="text" name="fcolor' + i + '" class="colorinput" ID="fcolor' + i + '" value=""> Beep: <input type="checkbox" id="beep' + i + '"' + beep_disabled +'><label></label></LI>').insertBefore(".regexdata_save");
$('#color' + i).val($('.colorPicker_def_color').css('color'));
$('#fcolor' + i).val($('.colorPicker_def_fcolor').css('color'));
$('#color' + i).colorPicker();
$('#fcolor' + i).colorPicker();
});
$("#del1regex").click(function () {
var i = MAX_SEARCH_PATTERN;
if (i < 2) return;
if ($('#regex' + i).val() != '') if (!confirm('Search' + i + ' is not empty! Delete?')) return;
$("#regexrow" + i).remove();
localStorage.removeItem('regex' + i);
localStorage.removeItem('color' + i);
localStorage.removeItem('fcolor' + i);
localStorage.removeItem('whitelisted' + i);
localStorage.removeItem('hidden' + i);
localStorage.removeItem('beep' + i);
MAX_SEARCH_PATTERN--;
localStorage.MAX_SEARCH_PATTERN = MAX_SEARCH_PATTERN;
});
$("#regexok").click(function () {
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
var pattern = $('#regex' + i).val();
if (pattern) {
var color = $('#color' + i).val();
var fcolor = $('#fcolor' + i).val();
} else {
var color = '';
var fcolor = '';
}
localStorage['regex' + i] = pattern ? pattern : '';
localStorage['color' + i] = color ? color : '';
localStorage['fcolor' + i] = fcolor ? fcolor : '';
localStorage['whitelisted' + i] = $('#whitelisted' + i).prop('checked') ? '1' : '0';
localStorage['hidden' + i] = $('#hidden' + i).prop('checked') ? '1' : '0';
localStorage['beep' + i] = $('#beep' + i).prop('checked') ? '1' : '0';
}
});
$("#regexreset").click(function () {
if (confirm('Delete all Filters and Colors?')) {
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
$('#regex' + i).val('');
$('#whitelisted' + i).prop('checked', false);
$('#hidden' + i).prop('checked', false);
$('#color' + i).val($('.colorPicker_def_color').css('color'));
$('#color' + i).change();
$('#fcolor' + i).val($('.colorPicker_def_fcolor').css('color'));
$('#fcolor' + i).change();
$('#beep' + i).prop('checked', false);
localStorage['regex' + i] = '';
localStorage['color' + i] = '';
localStorage['fcolor' + i] = '';
localStorage['whitelisted' + i] = '0';
localStorage['hidden' + i] = '0';
localStorage['beep' + i] = '0';
}
}
});
$(".sizemls a, .sizeml a").click(function () {
maxloglines = parseInt($(this).attr('sendval'));
$("#sizemfrom").text(' Switch displayed log lines from ' + maxloglines + ' to ');
for (var i = 32; i <= 512; i *= 2) {
$("#sizem" + i).attr('class', (maxloglines == i) ? 'sizemls' : 'sizeml');
}
return false;
});
$(".debugls a, .debugl a").click(function () {
parameters = parameters + "&debug=" + $(this).attr('sendval');
return false;
});
$("#savelog").on('click', function (event) {
var txt = '';
$("#livelogdata li").each(function (i) {
txt += $(this).text() + '\n';
});
// Data URI
txtData = 'data:application/txt;charset=utf-8,' + encodeURIComponent(txt);
$(this).attr({
'href': txtData,
'target': '_blank'
});
});
$("#showhidesettings").click(function () {
if ($("#showhidesettings").val() == 'Show Settings') {
$("#showhidesettings").val('Hide Settings');
$("#regexdata").fadeIn('slow');
} else {
$("#showhidesettings").val('Show Settings');
$("#regexdata").fadeOut('slow');
}
});
$("#stoplog").click(function () {
if ($("#stoplog").val() == 'Stop Log') {
$("#stoplog").val('Start Log');
stoppoll = 1;
} else {
$("#stoplog").val('Stop Log');
stoppoll = 0;
waitForMsg();
}
});
$("#onlineidle").click(function () {
if ($("#onlineidle").text() == 'Login*') {
$("#onlineidle")
.text('Online & Idle*')
.attr('title', 'Login info (click to switch)');
} else {
$("#onlineidle")
.text('Login*')
.attr('title', 'Online & Idle info (click to switch)');
}
if (!nostorage) localStorage.loi = $("#onlineidle").text();
waitForMsg();
});
// switch reader ON/OFF
$("a.switchreader").click(function (e) {
e.preventDefault();
var parameters_old = parameters;
parameters += '&label=' + $(this).data('reader-name') + '&action=' + $(this).data('next-action');
var rowid = '#' + $(this).data('md5');
var img = $(this).children("img");
waitForMsg();
if ($(this).data('next-action') == 'enable') {
$(this).data('next-action', 'disable').attr('title', 'Disable Reader: ' + $(this).data('reader-name') + $(this).data('desc'));
$(rowid).attr('class', 'enabledreader');
img.attr('src', 'image?i=ICDIS').attr('alt', 'Disable');
} else {
$(this).data('next-action', 'enable').attr('title', 'Enable Reader: ' + $(this).data('reader-name') + $(this).data('desc'));
$(rowid).attr('class', 'disabledreader');
img.attr('src', 'image?i=ICENA').attr('alt', 'Enable');
}
parameters = parameters_old;
});
// delete reader
$("a.deletereader").click(function (e) {
e.preventDefault();
if (confirm("Delete Reader " + $(this).data('reader-name') + "?")) {
var parameters_old = parameters;
parameters += '&label=' + $(this).data('reader-name') + '&action=' + $(this).data('next-action');
cleaninsert($(this).data('reader-name'));
waitForMsg();
parameters = parameters_old;
$('#' + $(this).data('md5')).fadeOut('slow');
}
});
// switch user ON/OFF
$("a.switchuser").click(function (e) {
e.preventDefault();
var parameters_old = parameters;
parameters += '&user=' + $(this).data('user-name') + '&action=' + $(this).data('next-action');
var rowid = '#' + $(this).data('md5');
var img = $(this).children("img");
waitForMsg();
if ($(this).data('next-action') == 'enable') {
$(this).data('next-action', 'disable').attr('title', 'Disable User: ' + $(this).data('user-name') + $(this).data('desc'));
$(rowid).attr('class', 'offline');
$(rowid + ' > td.usercol2').text('offline');
img.attr('src', 'image?i=ICDIS').attr('alt', 'Disable');
} else {
$(this).data('next-action', 'enable').attr('title', 'Enable User: ' + $(this).data('user-name') + $(this).data('desc'));
$(rowid).attr('class', 'disabled');
$(rowid + ' > td.usercol2').text('offline (disabled)');
img.attr('src', 'image?i=ICENA').attr('alt', 'Enable');
}
parameters = parameters_old;
});
// reset user stats
$("a.resetuser").click(function (e) {
e.preventDefault();
if (confirm("Reset Stats for " + $(this).data('user-name') + "?")) {
var parameters_old = parameters;
parameters += '&user=' + $(this).data('user-name') + '&action=' + $(this).data('next-action');
waitForMsg();
parameters = parameters_old;
}
});
// delete user
$("a.deleteuser").click(function (e) {
e.preventDefault();
if (confirm("Delete User " + $(this).data('user-name') + "?")) {
var parameters_old = parameters;
parameters += '&user=' + $(this).data('user-name') + '&action=' + $(this).data('next-action');
cleaninsert($(this).data('user-name'));
waitForMsg();
parameters = parameters_old;
$('#' + $(this).data('md5')).fadeOut('slow');
}
});
// search related events
$("#searchTerm").keyup(function () {
var value = $("#searchTerm").val().toLowerCase().trim();
$("#dataTable tr").each(function (index) {
if (!index) return;
$(this).find("td").each(function () {
var id = (($(this).data('sort-value') == undefined || $(this).hasClass("usercol2")) ? $(this).text() : $(this).data('sort-value').toString()).toLowerCase().trim();
var not_found = (id.indexOf(value) == -1);
$(this).closest('tr').toggle(!not_found);
return not_found;
});
});
});
$("#searchTerm").click(function () {
cdpause();
});
$("#searchTerm").blur(function () {
initDoc();
});
var table = $('#dataTable').stupidtable();
table.bind('beforetablesort', function (event, data) {
lockpoll = 1;
table.addClass("disabledtable");
});
table.bind('aftertablesort', function (event, data) {
// data.column - the index of the column sorted after a click
// data.direction - the sorting direction (either asc or desc)
lockpoll = 0;
table.removeClass("disabledtable");
});
// copy emm to single write emm
$("a.tosingleemm").click(function (e) {
var ins_emm = (/\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)\s+/).exec($(this).text());
$('#singleemm').val(ins_emm[1]);
$('#singleemm').change();
});
});
/*
* General: Update page footer and failbannotifier
*/
function updateFooter(data) {
$("#curtime").text(' ' + data.oscam.curdate + ' | ' + data.oscam.curtime + ' ');
$("#runtime").text(' ' + data.oscam.runtime);
$("#uptime") .text(' ' + data.oscam.uptime);
if ($("#fbnotifier > span.span_notifier").length) {
if (data.oscam.failbannotifier > 0) {
$("#fbnotifier > span.span_notifier")
.text(data.oscam.failbannotifier);
}
else {
$("#fbnotifier > span.span_notifier").remove();
}
}
else if (data.oscam.failbannotifier > 0) {
$("#fbnotifier")
.append('<SPAN CLASS="span_notifier">'+ data.oscam.failbannotifier + '</SPAN>');
}
}
/*
* identfy an element within string of elements
*/
var poll_excluded;
function is_nopoll(value) {
return (poll_excluded.indexOf(value) > (-1)) ? true : false;
}
/*
* Userpage Functions: Update Page
*/
function updateUserpage(data) {
// update user lines
$.each(data.oscam.users, function (i, item) {
var uid = "#" + item.user.usermd5;
poll_excluded = ($(uid).attr('nopoll') != undefined) ? $(uid).attr('nopoll') : '';
switch (item.user.classname) {
case 'online':
$(uid).attr('class', item.user.classname);
if (!is_nopoll('usercol1')) {
if ($(uid + " td.usercol1 > span.span_notifier").length) {
if(item.user.unotify){
$(uid + " td.usercol1 > span.span_notifier")
.text(item.user.unotify);
}
else {
$(uid + " td.usercol1 > span.span_notifier").remove();
}
}
else if(item.user.unotify) {
$(uid + " td.usercol1")
.append('<SPAN CLASS="span_notifier">'+ item.user.unotify + '</SPAN>');
}
}
if (!is_nopoll('usercol2')) {
$(uid + " td.usercol2")
.attr('title', item.user.stats.expectsleep != 'undefined' ? (item.user.stats.expectsleep > 0 ? 'Sleeping in ' + item.user.stats.expectsleep + ' minutes' : 'Sleeping') : '')
.data('sort-value', item.user.ip)
.html("<B>" + item.user.status + "</B><br>" + item.user.ip);
}
if (!is_nopoll('usercol3')) {
$(uid + " td.usercol3").html(item.user.stats.idle + "<br>" + item.user.stats.timeonchannel.toHHMMSS());
}
if (!is_nopoll('usercol4')) {
if (item.user.protoicon.length > 0) {
if (!$(uid + " td.usercol4 > img").length || $(uid + " td.usercol4 > img").attr('src')!='image?i=IC_' + item.user.protoicon) {
var protoimage = $('<img class="protoicon" src="image?i=IC_' + item.user.protoicon + '" />');
protoimage.hide();
$(uid + " td.usercol4").html(protoimage);
protoimage.fadeIn('slow');
}
} else {
$(uid + " td.usercol4").text(item.user.protocol);
}
$(uid + " td.usercol4")
.attr('title', item.user.prototitle)
.data('sort-value', item.user.protosort);
}
// channel icon
if (!is_nopoll('usercol6')) {
$(uid + " td.usercol6")
.attr('title', item.user.lastchanneltitle)
.data('sort-value', item.user.lastchannelsort);
if (item.user.lca.length > 0) {
// if we already have a picon within link
if ($(uid + " > td.usercol6 > img.usericon").length) {
// we compare the picon name and switch if different
var image = $(uid + " > td.usercol6 > img.usericon");
if (image.attr('src') != 'image?i=IC_' + item.user.lca) {
// set title of link as tooltip
image.hide();
image.attr('src', 'image?i=IC_' + item.user.lca);
image.fadeIn('slow');
image.attr('alt', item.user.lastchanneltitle);
image.attr('title', item.user.lastchanneltitle);
}
} else {
// we have no image so we have to create one
// if we have picon clear text
$(uid + " > td.usercol6").text('');
// just to be sure that class of image is set
if ($(uid + " > td.usercol6 > img").length) {
$(uid + " > td.usercol6 > img").attr('class', 'usericon');
}
newimage = $('<img class="usericon" src="image?i=IC_' + item.user.lca + '">');
newimage.hide();
$(uid + " > td.usercol6").append(newimage);
newimage.fadeIn('slow');
newimage.attr('alt', item.user.lastchanneltitle);
newimage.attr('title', item.user.lastchanneltitle);
}
} else {
$(uid + " td.usercol6").html(item.user.lastchannel);
}
}
if (!is_nopoll('usercol7')) {
$(uid + " td.usercol7")
.text(item.user.stats.cwlastresptimems);
}
//usercol8 ???
if (!is_nopoll('usercol9')) {
$(uid + " td.usercol9").text(item.user.stats.cwok);
}
if (!is_nopoll('usercol10')) {
$(uid + " td.usercol10").text(item.user.stats.cwnok);
}
if (!is_nopoll('usercol11')) {
$(uid + " td.usercol11").text(item.user.stats.cwignore);
}
if (!is_nopoll('usercol12')) {
$(uid + " td.usercol12").text(item.user.stats.cwtimeout);
}
if (!is_nopoll('usercol13')) {
$(uid + " td.usercol13").text(item.user.stats.cwccyclechecked + ' / ' + item.user.stats.cwcycleok + ' / ' + item.user.stats.cwcyclenok + ' / ' + item.user.stats.cwcycleign);
}
if (!is_nopoll('usercol14')) {
$(uid + " td.usercol14").text(item.user.stats.cwcache);
}
if (!is_nopoll('usercol15')) {
$(uid + " td.usercol15").text(item.user.stats.cwtun);
}
if (!is_nopoll('usercol16')) {
$(uid + " td.usercol16").text(item.user.stats.cwcache);
}
if (!is_nopoll('usercol17')) {
$(uid + " td.usercol17").text(item.user.stats.emmok);
}
if (!is_nopoll('usercol18')) {
$(uid + " td.usercol18").text(item.user.stats.emmnok);
}
if (!is_nopoll('usercol19')) {
$(uid + " td.usercol19").text(item.user.stats.cwrate + item.user.stats.cwrate2);
}
if (!is_nopoll('usercol22')) {
$(uid + " td.usercol22").text(item.user.stats.cascusercomb);
}
if (!is_nopoll('usercol21')) {
$(uid + " td.usercol21").text(item.user.stats.n_requ_m);
}
if (!is_nopoll('usercol20')) {
$(uid + " td.usercol20")
.attr('title', item.user.expview)
.text(item.user.stats.expdate);
}
break;
case 'connected':
$(uid).attr('class', item.user.classname);
if (!is_nopoll('usercol1')) {
if ($(uid + " td.usercol1 > span.span_notifier").length) {
if(item.user.unotify){
$(uid + " td.usercol1 > span.span_notifier")
.text(item.user.unotify);
}
else {
$(uid + " td.usercol1 > span.span_notifier").remove();
}
}
else if(item.user.unotify) {
$(uid + " td.usercol1")
.append('<SPAN CLASS="span_notifier">'+ item.user.unotify + '</SPAN>');
}
}
if (!is_nopoll('usercol2')) {
$(uid + " td.usercol2")
.attr('title', '')
.data('sort-value', item.user.ip)
.html("<B>" + item.user.status + "</B><br>" + item.user.ip);
}
if (!is_nopoll('usercol3')) {
$(uid + " td.usercol3").html(item.user.stats.idle + "<br>" + item.user.stats.timeonchannel.toHHMMSS());
}
if (!is_nopoll('usercol4')) {
if (item.user.protoicon.length > 0) {
if (!$(uid + " td.usercol4 > img").length || $(uid + " td.usercol4 > img").attr('src')!='image?i=IC_' + item.user.protoicon) {
var protoimage = $('<img class="protoicon" src="image?i=IC_' + item.user.protoicon + '" />');
protoimage.hide();
$(uid + " td.usercol4").html(protoimage);
protoimage.fadeIn('slow');
}
} else {
$(uid + " td.usercol4").text(item.user.protocol);
}
$(uid + " td.usercol4")
.attr('title', item.user.prototitle)
.data('sort-value', item.user.protosort);
}
if (!is_nopoll('usercol6')) {
// channel icon
$(uid + " td.usercol6")
.attr('title', item.user.lastchanneltitle)
.data('sort-value', item.user.lastchannelsort);
if (item.user.lca.length > 0) {
var image;
if ($(uid + " td.usercol6").html().length == 0) {
image = $('<img class="usericon" src="image?i=IC_' + item.user.lca + '" />');
image.hide();
$(uid + " td.usercol6").prepend(image);
image.fadeIn('slow');
} else {
image = $(uid + " td.usercol6 img.usericon");
if (image.attr('src') != ('image?i=IC_' + item.user.lca)) {
image.fadeOut('fast', function () {
image.attr('src', 'image?i=IC_' + item.user.lca);
image.fadeIn('slow');
});
image.attr('alt', item.user.lcb);
image.attr('title', item.user.lastchanneltitle);
}
}
} else {
$(uid + " td.usercol6").html(item.user.lastchannel);
}
}
if (!is_nopoll('usercol7')) {
$(uid + " td.usercol7")
.text(item.user.stats.cwlastresptimems);
}
if (!is_nopoll('usercol19')) {
$(uid + " td.usercol19").text(item.user.stats.cwrate);
}
break;
default:
//check the last status
if ('online,connected'.indexOf($(uid).attr('class')) > (-1)) {
// last status was online so cleanup offline
$(uid).attr('class', item.user.classname);
if (!is_nopoll('usercol1')) {
if ($(uid + " td.usercol1 > span.span_notifier").length) {
$(uid + " td.usercol1 > span.span_notifier").remove();
}
}
if (!is_nopoll('usercol2')) {
$(uid + " td.usercol2")
.attr('title', '')
.html(item.user.status);
}
if (!is_nopoll('usercol3')) {
$(uid + " td.usercol3").text('');
}
if (!is_nopoll('usercol4')) {
$(uid + " td.usercol4")
.text('')
.attr('title', '');
var protoimage = $(uid + " td.usercol4 img.protoicon");
if (image) {
protoimage.fadeOut('slow');
protoimage.remove();
}
}
//channelicon
if (!is_nopoll('usercol6')) {
$(uid + " td.usercol6")
.text('')
.data('sort-value', '');
var image = $(uid + " td.usercol6 img.usericon");
if (image) {
image.fadeOut('slow');
image.remove();
}
}
if (!is_nopoll('usercol7')) {
$(uid + " td.usercol7")
.text('');
}
}
break;
}
if (typeof custompoll == 'function') {
custompoll(item);
}
});
// update user totals + ECM
updateTotals(data);
// update footer
updateFooter(data);
}
/*
* Readerpage Functions: Update Page
*/
function updateReaderpage(data) {
// update reader lines
$.each(data.oscam.readers, function (i, item) {
var uid = "#" + item.labelmd5;
poll_excluded = ($(uid).attr('nopoll') != undefined) ? $(uid).attr('nopoll') : '';
$(uid).attr('class', item.classname);
if (!is_nopoll('readercol4')) {
$(uid + " td.readercol4").text(item.stats.ecmsok + item.stats.ecmsokrel)
.data('sort-value', item.stats.ecmsok);
}
if (!is_nopoll('readercol19')) {
$(uid + " td.readercol19").text(item.stats.ecmsoklg + item.stats.ecmsoklgrel)
.data('sort-value', item.stats.ecmsoklg);
}
if (!is_nopoll('readercol5')) {
$(uid + " td.readercol5").text(item.stats.ecmsnok + item.stats.ecmsnokrel)
.data('sort-value', item.stats.ecmsnok);
}
if (!is_nopoll('readercol6')) {
$(uid + " td.readercol6").text(item.stats.ecmstout + item.stats.ecmstoutrel)
.data('sort-value', item.stats.ecmstout);
}
if (!is_nopoll('readercol7')) {
$(uid + " td.readercol7").text(item.stats.ecmsfiltered);
}
if (!is_nopoll('readercol8')) {
$(uid + " td.readercol8").text(item.stats.emmerror);
}
if (!is_nopoll('readercol9')) {
$(uid + " td.readercol9").text(item.stats.emmwritten);
}
if (!is_nopoll('readercol20')) {
$(uid + " td.readercol20").html(item.status + "<BR>" + item.ip);
}
if (!is_nopoll('readercol10')) {
$(uid + " td.readercol10").text(item.stats.emmskipped);
}
if (!is_nopoll('readercol11')) {
$(uid + " td.readercol11").text(item.stats.emmblocked);
}
if (!is_nopoll('readercol12')) {
$(uid + " td.readercol12").text(item.stats.lbweight);
}
if (!is_nopoll('readercol2')) {
if (data.oscam.piconenabled == "1" && item.protoicon) {
$(uid + " td.readercol2").html('<img class="protoicon" title="Protocol ' + item.protocol + ' ' +
item.prototitle + '" alt="IC_' + item.protoicon + '" src="image?i=IC_' + item.protoicon + '">');
} else {
$(uid + " td.readercol2").text(item.protocol);
}
$(uid + " td.readercol2")
.data('sort-value', item.protosort);
}
if (typeof custompoll == 'function') {
custompoll(item);
}
});
// update user totals + ECM
updateTotals(data);
// update footer
updateFooter(data);
}
/*
* LiveLog Functions: format the debuglevel switcher
*/
function setDebuglevel(debug, maxdebug) {
var cs_dblevel = parseInt(debug);
var maxlevel = parseInt(maxdebug);
if (lastdebuglevel != cs_dblevel) {
var lvl = 0;
$("#debugfrom").text(' Switch Debug from ' + cs_dblevel + ' to ');
for (var i = 0; i < maxlevel; i++) {
lvl = 1 << i;
if (cs_dblevel & lvl) {
$("#debug" + lvl).attr('sendval', cs_dblevel - lvl);
} else {
$("#debug" + lvl).attr('sendval', cs_dblevel + lvl);
}
$("#debug" + lvl).attr('class', (cs_dblevel & lvl) ? 'debugls' : 'debugl');
}
lastdebuglevel = cs_dblevel;
}
}
/*
* Livelog Functions: get filter color
*/
function getLogColor(text) {
if (nostorage) {
return null;
}
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
var pattern = localStorage['regex' + i];
var color = localStorage['color' + i];
var fcolor = localStorage['fcolor' + i];
var hidden = localStorage['hidden' + i];
var beep = localStorage['beep' + i];
var regex = new RegExp(pattern);
if (pattern && (pattern != '') && (regex.exec(text))) {
return {
color: color,
fcolor: fcolor,
hidden: hidden,
beep: beep
}
}
}
return null;
}
/*
* Livelog Functions: get whitelist state
*/
function isWhitelisted(text) {
if (nostorage) {
return 1;
}
var numwhite = 0;
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
numwhite += parseInt(localStorage['whitelisted' + i]);
}
if (numwhite > 0) {
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
var whitelisted = localStorage['whitelisted' + i];
var pattern = localStorage['regex' + i];
var regex = new RegExp(pattern);
if (pattern && (pattern != '') && (whitelisted == '1') && (regex.exec(text))) {
return 1;
}
}
return 0;
} else {
return 1;
}
}
/*
* LiveLog Functions: manage the delivered data / loglines
*/
function updateLogpage(data) {
lockpoll = 1;
if (data.oscam.debug) {
setDebuglevel(data.oscam.debug, data.oscam.maxdebug);
}
if (data.oscam.logdisabled) {
stoppoll = 1;
$("#livelogdata").append('<li>Log is disabled</li>\n');
}
$.each(data.oscam.lines, function (i, item) {
if (isWhitelisted(Base64.decode(item.line))) {
var newcolor = getLogColor(Base64.decode(item.line));
var newline = $('<li class="' + decodeURIComponent(item.usr) + '">' + Base64.decode(item.line) + '</li>\n');
var hiddenline = 0;
if (newcolor) {
if (newcolor.hidden != '1') {
if (newcolor.color && newcolor.color != '') {
newline.css('background-color', newcolor.color);
}
if (newcolor.fcolor && newcolor.fcolor != '') {
newline.css('color', newcolor.fcolor);
}
$("#livelogdata").append(newline);
if (newcolor.beep == 1) {
beep(50, 4, 1000, 0.2);
}
} else {
hiddenline = 1;
}
} else {
$("#livelogdata").append(newline);
}
if (!hiddenline) {
if ($("#livelog:hover").length) {
$('#livelog').stop(true);
} else {
$("#livelog").scrollTop($("#livelog").prop("scrollHeight"));
}
}
}
parameters = "?lastid=" + item.id;
});
var len = $("#livelogdata li").length;
if (len > maxloglines) {
$("#livelogdata li").slice(0, len - maxloglines).remove();
}
// update footer
updateFooter(data);
lockpoll = 0;
}
/*
* Statuspage Functions: JQuery Extensions
*/
$.fn.toHtmlString = function () {
return $('<td></td>').html($(this).clone()).html();
};
/*
* Statuspage Functions: Generate a Bar for Barchart
*/
function generateBar(value) {
var bar = $('<div class="bar"/>');
var maxheight = 75; //$( "#graph" ).height() -15;
var numval = parseInt(value);
numval = Math.floor(numval / 30);
if (numval >= maxheight) {
bar.css('background-color', '#FF0000');
numval = maxheight;
}
bar.css('height', numval + 'px');
return bar;
}
/*
* Statuspage Functions: Add/Remove Subheadline
*/
function addremoveSubheadline(remove, data, container, subheadline, type) {
if (remove == 1 && $("#" + subheadline).length) {
$("#" + subheadline)
.fadeOut('slow')
.remove();
$(".status tbody:empty").hide();
}
if (remove == 0 && !$("#" + subheadline).length) {
$(container).removeAttr('style');
var strheadline = '<TR id="' + subheadline + '"><TD CLASS="subheadline" COLSPAN="12">';
if (type == 'c') {
if (data.oscam.status.ucac != '') { //hide idle clients
strheadline += '<P id="chead">Clients <span id="ucs">' + data.oscam.status.ucs + '</span>/<span id="uca">' + data.oscam.status.uca + '</span> (<span id="ucac">' + data.oscam.status.ucac + '</span> with ECM within last <span id="cfgh">' + data.oscam.status.cfgh + '</span> seconds)</P>'
} else {
strheadline += '<P id="chead">Clients <span id="ucs">' + data.oscam.status.ucs + '</span>/<span id="uca">' + data.oscam.status.uca + '</span></P>'
}
strheadline += '<DIV><input type="button" onclick="window.location.href = \'status.html?hideidle=5\';" value="Show Hidden" title="Show Hidden User">';
strheadline += '<input type="button" onclick="window.location.href = \'status.html?hideidle=0\';" value="Show Idle" title="Show Idle User">';
strheadline += '<input type="button" onclick="window.location.href = \'status.html?hideidle=1\';" value="Hide Idle" title="Hide Idle User">';
} else if (type == 'm') {
strheadline += '<P id="shead">Server <span id="scs">' + data.oscam.status.scs + '</span>/<span id="sca">' + data.oscam.status.sca + '</span> & Monitors <span id="mcs">' + data.oscam.status.mcs + '</span>/<span id="mca">' + data.oscam.status.mca + '</span></P>'
strheadline += '<DIV><input type="button" onclick="window.location.href = \'status.html?hideidle=2\';" value="Show Hidden" title="Show Hidden Server & Monitors">';
}
strheadline += '</DIV></TD></TR>';
var headline = $(strheadline);
headline.hide();
$(container).append(headline);
headline.fadeIn('slow');
}
}
function fillStatus(list, type, data) {
list.forEach(function(key) {
$("#" + key).text(data.oscam[type][key]);
});
}
/*
* Statuspage Functions: Update Totals cacheEx
*/
function updateCacheextotals(data) {
fillStatus(["total_cachexpush", "total_cachexgot", "rel_cachexhit", "total_cachesize"], "totals", data);
}
/*
* Statuspage Functions: Update Totals User + Totals Reader + ECM + EMM
*/
function updateTotals(data) {
fillStatus(["total_users", "total_active", "total_connected", "total_online", "total_disabled", "total_expired", "total_readers", "total_active_readers", "total_connected_readers", "total_disabled_readers", "total_cwok", "total_cwok_readers", "rel_cwok", "rel_cwok_readers", "total_cwcache", "rel_cwcache", "total_cwnok", "total_cwnok_readers", "rel_cwnok", "rel_cwnok_readers", "total_cwtout", "total_cwtout_readers", "rel_cwtout", "rel_cwtout_readers", "total_cwign", "total_ecm_min", "total_cw", "total_cwpos", "total_cwpos_readers", "rel_cwpos", "rel_cwpos_readers", "total_cwneg", "total_cwneg_readers", "rel_cwneg", "rel_cwneg_readers", "total_emok", "rel_emok", "total_emnok", "rel_emnok", "total_em", "total_elenr", "total_eheadr", "total_emmerroruk_readers", "total_emmerrorg_readers", "total_emmerrors_readers", "total_emmerroruq_readers", "total_emmwrittenuk_readers", "total_emmwritteng_readers", "total_emmwrittens_readers", "total_emmwrittenuq_readers", "total_emmskippeduk_readers", "total_emmskippedg_readers", "total_emmskippeds_readers", "total_emmskippeduq_readers", "total_emmblockeduk_readers", "total_emmblockedg_readers", "total_emmblockeds_readers", "total_emmblockeduq_readers", "total_sum_all_readers_ecm", "total_sum_all_readers_emm"], "totals", data);
}
/*
* Statuspage Functions: Update Totals Sysinfo
*/
var first_run = 1;
function updateSysinfo(data) {
fillStatus(["mem_cur_total", "mem_cur_free", "mem_cur_used", "mem_cur_buff", "mem_cur_cached", "mem_cur_totalsw", "mem_cur_freesw", "mem_cur_usedsw", "mem_cur_shared", "oscam_vmsize", "oscam_rsssize", "server_procs", "cpu_load_0", "cpu_load_1", "cpu_load_2"], "sysinfo", data);
$("#mem_cur_freem").attr('title', 'max Free: ' + data.oscam.sysinfo.mem_cur_freem + ' \n(incl. Buffer & Cached)');
if (!first_run) {
fillStatus(["oscam_refresh", "oscam_cpu_user", "oscam_cpu_sys", "oscam_cpu_sum"], "sysinfo", data);
}
first_run = 0;
}
/*
* Statuspage Functions: Update Page
*/
function updateStatuspage(data) {
var updatedclients = "";
// update status lines
$.each(data.oscam.status.client, function (i, item) {
var newrow;
//add ID's for type c and m to list of existing elements. We need this to delete all not longer existing
updatedclients += item.thid + ",";
var uid = "#" + item.thid;
poll_excluded = ($(uid).attr('nopoll') != undefined) ? $(uid).attr('nopoll') : '';
if (!$(uid).length && 'rpcxm'.indexOf(item.type) > (-1)) {
//build new row
var rowcontent = '<TR ID="' + item.thid + '"><TD CLASS="statuscol0"/><TD CLASS="statuscol1"/><TD CLASS="statuscol4"/>';
rowcontent += '<TD CLASS="statuscol5"/><TD CLASS="statuscol7"/><TD CLASS="statuscol8"/><TD CLASS="statuscol9"/>';
rowcontent += '<TD CLASS="statuscol12"/><TD CLASS="statuscol13"/><TD CLASS="statuscol14"/><TD CLASS="statuscol15"/>';
rowcontent += '<TD CLASS="statuscol16"/></TR>';
newrow = $(rowcontent);
newrow.hide();
// if we have no clients we have to add the headline first
// append new clientrow to table
var container = '';
if ('hms'.indexOf(item.type) > (-1)) {
container = '#tbodys';
if (item.type == 'm') {
if (!$("#Serverheadline").length) {
addremoveSubheadline(0, data, container, "Serverheadline", item.type);
} else if (!$("#mca").length) {
$("#shead").append(' & Monitors <span id="mcs">' + data.oscam.status.mcs + '</span>/<span id="mca">' + data.oscam.status.mca + '</span>');
}
}
} else if ('px'.indexOf(item.type) > (-1)) {
container = '#tbodyp';
} else {
container = '#tbody' + item.type;
if (!$("#Userheadline").length && item.type == 'c') {
addremoveSubheadline(0, data, container, "Userheadline", item.type);
}
}
$(container).append(newrow);
var name1, name2, name3, kill1, kill2, kill3, edit1;
switch (item.type) {
case 'c':
case 'm':
name1 = 'User';
name2 = item.name_enc;
kill1 = '" href="status.html?action=kill&threadid=' + item.thid.substring(3, item.thid.length);
kill2 = 'Kill'
kill3 = 'ICKIL';
edit1 = 'user_edit.html?user=';
break;
case 'r':
case 'p':
case 'x':
name1 = (item.type == 'r') ? 'Reader' : 'Proxy';
name2 = item.rname_enc;
kill1 = '" href="status.html?action=restart&label=' + name2;
kill2 = 'Restart';
kill3 = 'ICRES';
edit1 = 'readerconfig.html?label=';
break;
}
name3 = decodeURIComponent(name2);
if (!is_nopoll('statuscol0')) {
$(uid + " > td.statuscol0").append('<a title="Hide ' +
name1 + ': ' + name3 + (item.desc ? '\n' + item.desc.replace('&#13;', '') : '') +
'" href="status.html?hide=' +
item.thid.substring(3, item.thid.length) +
'"><img class="icon" alt="Hide"' +
'" src="image?i=ICHID">');
}
if (!is_nopoll('statuscol1')) {
$(uid + " > td.statuscol1").append('<a title="' + kill2 + ' ' +
name1 + ': ' + name3 + (item.desc ? '\n' + item.desc.replace('&#13;', '') : '') +
kill1 + '"><img class="icon" alt="' + kill2 +
'" src="image?i=' + kill3 + '">');
}
if (!is_nopoll('statuscol4')) {
if (data.oscam.piconenabled == "1" && !item.upicmissing) {
$(uid + " > td.statuscol4").append('<a href="' + edit1 + name2 + '"><img class="statususericon" title="Edit ' +
name1 + ': ' + name3 + (item.desc ? '\n' + item.desc.replace('&#13;', '') : '') + '" src="image?i=IC_' + name2 + '"></a>');
} else {
$(uid + " > td.statuscol4").append('<a href="' + edit1 + name2 + '" title="Edit ' + name1 + ': ' +
name3 + (item.desc ? '\n' + item.desc.replace('&#13;', '') : '') + '\n' + item.upicmissing + '">' + name3 + '</a>');
}
}
if (!is_nopoll('statuscol13')) {
$(uid + " > td.statuscol13").append('<A HREF="files.html?file=' + data.oscam.srvidfile + '" TITLE="' + item.request + '"/>');
}
if (!is_nopoll('statuscol9')) {
if (data.oscam.piconenabled == "1" && item.protoicon) {
$(uid + " > td.statuscol9").append('<img class="protoicon" title="Protocol ' + item.protocol + ' ' +
item.protocolext + '" alt="IC_' + item.protoicon + '" src="image?i=IC_' + item.protoicon + '">');
} else {
$(uid + " > td.statuscol9").attr('title', item.protocolext).text(item.protocol);
}
}
}
$(uid).attr('class', item.type).data('ecmhistory', item.request.ecmhistory).removeAttr('style');
// fix for anonymous newcamd-clients
if ($(uid + " > td.statuscol4").text().match('anonymous')) {
if (!is_nopoll('statuscol9')) {
if (data.oscam.piconenabled == "1" && item.protoicon) {
$(uid + " > td.statuscol9").html('<img class="protoicon" title="Protocol ' + item.protocol + ' ' +
item.protocolext + '" alt="IC_' + item.protoicon + '" src="image?i=IC_' + item.protoicon + '">');
} else {
$(uid + " > td.statuscol9").attr('title', item.protocolext).text(item.protocol);
}
}
if (!is_nopoll('statuscol4')) {
if (data.oscam.piconenabled == "1" && !item.upicmissing) {
$(uid + " > td.statuscol4").html('<a href="user_edit.html?user=' + item.name_enc +
'"><img class="statususericon" title="Edit User: ' + decodeURIComponent(item.name_enc) + item.desc +
'" src="image?i=IC_' + item.name_enc + '"></a>');
} else {
$(uid + " > td.statuscol4").html('<a href="user_edit.html?user=' + item.name_enc + '" title="Edit User: ' +
decodeURIComponent(item.name_enc) + item.desc + item.upicmissing + '">' + decodeURIComponent(item.name_enc) + '</a>');
}
}
}
if (!is_nopoll('statuscol5')) {
switch (item.au) {
case '0':
$(uid + " > td.statuscol5").text('OFF').attr('class', 'statuscol5 statuscol5OFF');
break;
case '-1':
$(uid + " > td.statuscol5").html('<a class="tooltip" href="#">ON<span>' + item.aufmt + '</span></a>').attr('class', 'statuscol5 statuscol5ON');
break;
default:
$(uid + " > td.statuscol5").html('<a class="tooltip" href="#">ACTIVE<span>' + item.aufmt + '</span></a>').attr('class', 'statuscol5 statuscol5ACTIVE');
break;
}
}
if (!is_nopoll('statuscol4')) {
$(uid + " > td.statuscol4").attr('title', decodeURIComponent(item.type == 'c' ? item.name_enc : item.rname_enc) + (item.desc ? '\n' + item.desc.replace('&#13;', '') : ''));
}
if (!is_nopoll('statuscol7')) {
$(uid + " > td.statuscol7").text(item.connection.ip);
}
if (!is_nopoll('statuscol8')) {
$(uid + " > td.statuscol8").text(item.connection.port);
}
if (!is_nopoll('statuscol9')) {
$(uid + " > td.statuscol9").attr('title', item.protocolext);
}
if (!is_nopoll('statuscol12')) {
$(uid + " > td.statuscol12").text(item.request.srvid + ':' + item.request.caid + '@' + item.request.provid);
}
if (!is_nopoll('statuscol13')) {
var newimage;
if (data.oscam.piconenabled == '1' && item.request.srvid != '0000' && item.request.picon) {
// if we already have a picon within link
if ($(uid + " > td.statuscol13 > a > img.statususericon").length) {
// we compare the picon name and switch if different
var image = $(uid + " > td.statuscol13 > a > img.statususericon");
if (image.attr('src') != 'image?i=IC_' + item.request.picon) {
// set title of link as tooltip
$(uid + " > td.statuscol13 > a").attr('title', item.request.chname + item.request.chprovider);
image.hide();
image.attr('src', 'image?i=IC_' + item.request.picon);
image.fadeIn('slow');
}
} else {
// we have no image so we have to create one
// if we have picon clear text
$(uid + " > td.statuscol13").text('');
// if we have no link we create one
if (!$(uid + " > td.statuscol13 > a").length) {
$(uid + " > td.statuscol13").append('<a href="files.html?file=' + data.oscam.srvidfile + '"/>');
}
// set title of link as tooltip
$(uid + " > td.statuscol13 > a").attr('title', item.request.chname + item.request.chprovider);
// just to be sure that class of image is set
if ($(uid + " > td.statuscol13 > a > img").length) {
$(uid + " > td.statuscol13 > a > img").attr('class', 'statususericon');
}
newimage = $('<img class="statususericon" src="image?i=IC_' + item.request.picon + '">');
newimage.hide();
$(uid + " > td.statuscol13 > a").append(newimage);
newimage.fadeIn('slow');
}
} else {
// picon is not delivered in JSON - we set the text of column
if (item.request.chname && item.request.srvid != '0000') {
$(uid + " > td.statuscol13").html('<a href="files.html?file=' + data.oscam.srvidfile + '"/>');
$(uid + " > td.statuscol13 > a").html(item.request.chname + item.request.chprovider);
$(uid + " > td.statuscol13 > a").attr('title', item.request.chname + item.request.chprovider);
} else {
$(uid + " > td.statuscol13").html('');
}
}
}
if (!is_nopoll('statuscol14')) {
if ('hms'.indexOf(item.type) > (-1)) {
$(uid + " > td.statuscol14").text('');
} else {
var value = item.type == 'c' ? (item.request.answered ? item.request.answered + ' (' + item.request.msvalue + ' ms)' : '') : item.request.lbvalue;
if (data.oscam.lbdefined) {
var label = item.rname_enc.replace('+%28cache%29', '');
var name = item.type == 'c' ? item.request.answered.replace(' (cache)', '') : decodeURIComponent(label);
if (!$(uid + " > td.statuscol14 > a").length) {
$(uid + " > td.statuscol14")
.text('')
.append('<a href="readerstats.html?label=' + label + '&amp;show=0" TITLE="Show statistics for: ' + name + '">');
} else {
$(uid + " > td.statuscol14 > a")
.attr('href','readerstats.html?label=' + label + '&show=0')
.attr('title','Show statistics for: ' + name);
}
$(uid + " > td.statuscol14 > a").text(value);
} else {
$(uid + " > td.statuscol14").text(value);
}
}
}
if (!is_nopoll('statuscol15')) {
if ($("#onlineidle").text() != 'Login*') {
$(uid + " > td.statuscol15")
.html(item.times.online.toHHMMSS() + '<br>' + item.times.idle.toHHMMSS())
.attr('title', 'Login: ' + item.times.loginfmt);
} else {
$(uid + " > td.statuscol15")
.html(item.times.loginfmt.substring(0, 8) + '<br>' + item.times.loginfmt.substring(10, 18))
.attr('title', 'Online: ' + item.times.online.toHHMMSS() + '\nIDLE: ' + item.times.idle.toHHMMSS());
}
}
if (!is_nopoll('statuscol16')) {
var entitlement = '';
switch (item.type) {
case 'r':
// entitlement for native cards
var activeentitlements = item.connection.entitlements.length;
if (activeentitlements > 0) {
entitlement += '<br><a href="entitlements.html?label=' + item.rname_enc + '&hideexpired=1" class="tooltip">';
entitlement += '(' + activeentitlements + ' entitlement' + ((activeentitlements != 1) ? 's)' : ')');
entitlement += '<span>';
$.each(item.connection.entitlements, function (i, obj) {
entitlement += obj.caid + ':' + obj.provid + '<br>' + obj.exp + '<br><br>';
});
entitlement = entitlement.substring(0, entitlement.length - 4);
entitlement += '</span></a>';
} else {
entitlement += '<br><a href="entitlements.html?label=';
entitlement += item.rname_enc + '&hideexpired=1" class="tooltip1">(no entitlements)<span>No active entitlements found</span></a>';
}
break;
case 'p':
if (item.connection.entitlements.length > 0 && item.protocol.indexOf('cccam') > -1) {
// cccam
var entobj = item.connection.entitlements[0];
entitlement += '<br><a href="entitlements.html?label=' + item.rname_enc + '" class="tooltip' + entobj.cccreshare + '">';
entitlement += '(' + entobj.locals + ' of ' + entobj.cccount + ' card' + (entobj.cccount > 1 ? "s" : "") + ')';
entitlement += '<span>card_count=' + entobj.cccount + '<br>';
entitlement += 'hop1=' + entobj.ccchop1 + '<br>';
entitlement += 'hop2=' + entobj.ccchop2 + '<br>';
entitlement += 'hopx=' + entobj.ccchopx + '<br>';
entitlement += 'currenthops=' + entobj.ccccurr + '<br><br>';
entitlement += 'reshare0=' + entobj.cccres0 + '<br>';
entitlement += 'reshare1=' + entobj.cccres1 + '<br>';
entitlement += 'reshare2=' + entobj.cccres2 + '<br>';
entitlement += 'resharex=' + entobj.cccresx + '</span></a>';
}
if (item.protocol.indexOf('gbox') > -1) {
// TO DO gbox
var $html = $(uid + " > td.statuscol16").toHtmlString();
if ($html != undefined) {
entitlement = $html.substring($html.indexOf('<br>'), $html.indexOf('</a>'));
if (entitlement) entitlement += '</a>';
}
}
break;
}
$(uid + " > td.statuscol16").empty().html(item.connection.status + entitlement).attr('class', 'statuscol16 statuscol16' + item.connection.status);
}
if (newrow) {
newrow.fadeIn("slow");
}
if (typeof custompoll == 'function') {
custompoll(item);
}
});
//remove non existing elements
$("tr.c, tr.m, tr.r, tr.p, tr.h").each(function () {
if (updatedclients.indexOf($(this).attr('id')) == -1) {
$(this).fadeOut('slow').remove();
}
});
// if we have no clients left we remove the headline
if (!$("tr.c").length && data.oscam.status.uca == '0') {
addremoveSubheadline(1, '', '', "Userheadline", 'c');
}
// if we have no servers/monitors left we remove the headline
if (!$("tr.m").length && data.oscam.status.mca == '0') {
if ($("#mca").length) {
$("#shead").replaceWith('<P id="shead">Server <span id="scs">' + data.oscam.status.scs + '</span>/<span id="sca">' + data.oscam.status.sca + '</span></P>');
}
if (!$("tr.s").length && !$("tr.h").length && data.oscam.status.sch == '0') {
addremoveSubheadline(1, '', '', "Serverheadline", 'm');
}
}
//update client-headline
if (data.oscam.status.uca != '0') {
if (!$("#Userheadline").length) {
addremoveSubheadline(0, data, "#tbodyc", "Userheadline", "c");
} else {
$("#ucs").text(data.oscam.status.ucs);
$("#uca").text(data.oscam.status.uca);
if (data.oscam.status.ucac != '0') $("#ucac").text(data.oscam.status.ucac);
}
}
//update server/monitor-headline
if (data.oscam.status.mca != '0' && $("#mcs")) {
$("#mcs").text(data.oscam.status.mcs);
$("#mca").text(data.oscam.status.mca);
}
//update reader-headline
if(data.oscam.status.rco != '0') {
var rcon = (data.oscam.status.rca - data.oscam.status.rco);
if($("#rco").length) {
$("#rcc").text(data.oscam.status.rcc);
$("#rca").text(data.oscam.status.rca);
$("#rco").text(rcon);
} else {
$("#rhead").html('Readers <span id="rcc">' + data.oscam.status.rcc + '</span>/' + data.oscam.status.rca + ' (<span id="rco">' + rcon + '</span> of ' + data.oscam.status.rca + ' CARDOK)');
}
} else if($("#rco").length) {
$("#rhead").html('Readers <span id="rcc">' + data.oscam.status.rcc + '</span>/' + data.oscam.status.rca);
} else {
$("#rcc").text(data.oscam.status.rcc);
$("#rca").text(data.oscam.status.rca);
}
//update proxy-headline
if(data.oscam.status.pco != '0') {
var pcon = (data.oscam.status.pca - data.oscam.status.pco);
if($("#pco").length) {
$("#pcc").text(data.oscam.status.pcc);
$("#pca").text(data.oscam.status.pca);
$("#pco").text(pcon);
} else {
$("#phead").html('Proxies <span id="pcc">' + data.oscam.status.pcc + '</span>/' + data.oscam.status.pca + ' (<span id="pco">' + pcon + '</span> of ' + data.oscam.status.pca + ' online)');
}
} else if($("#pco").length) {
$("#phead").html('Proxies <span id="pcc">' + data.oscam.status.pcc + '</span>/' + data.oscam.status.pca);
} else {
$("#pcc").text(data.oscam.status.pcc);
$("#pca").text(data.oscam.status.pca);
}
// update footer
updateFooter(data);
// sysinfos
if ($("#mem_cur_total").length) updateSysinfo(data);
// user + ecm totals
if ($("#total_users").length) updateTotals(data);
// cachex
if ($("#total_cachexpush").length) updateCacheextotals(data);
}
/*
* General fork into page refresh functions
*/
function updatePage(data) {
// show heartbeat
if ($("input.pintervall").length && $("input.pintervall").css("background-color") != $("#picolor").css("background-color")) {
var orgstyle = $("input.pintervall").css("background-color");
$("input.pintervall").css("background-color", $("#picolor").css("background-color"));
}
switch (page) {
case 'status':
updateStatuspage(data);
break;
case 'user':
updateUserpage(data);
break;
case 'reader':
updateReaderpage(data);
break;
case 'livelog':
updateLogpage(data);
break;
case 'cacheex':
updateCacheextotals(data);
break;
default:
break;
}
// hide heartbeat
if ($("input.pintervall").length && $("input.pintervall").css("background-color") == $("#picolor").css("background-color")) {
setTimeout(function () {
$("input.pintervall").css("background-color", orgstyle);
}, 300);
}
if (typeof afterpoll == 'function') {
afterpoll();
}
}
function setPollerr(error) {
if (error && !$("#pollerr").length) {
$("body").append('<div id="pollerr" style="top:5px;left:5px;background-color:red;color:yellow;">POLLERR</div>');
} else {
if ($("#pollerr").length) {
$("#pollerr").fadeOut('slow').remove();
}
}
}
/*
* General Polling
*/
var lockpoll = 0;
var timer_ID;
function waitForMsg() {
if (typeof pollrefresh == 'undefined') return;
if (lockpoll > 0) {
/* assumed that previous poll is not finnished yet we not
call new data and just set the next intervall */
clearTimeout(timer_ID);
timer_ID = setTimeout("waitForMsg()", pollintervall);
return;
}
$.ajax({
type: "GET",
url: jsonurl + parameters,
dataType: "JSON",
async: true,
cache: false,
success: function (data) {
setPollerr(0);
if ((!pollrefresh || polling ) && page != 'livelog') return;
updatePage(data);
if (!stoppoll) {
clearTimeout(timer_ID);
timer_ID = setTimeout("waitForMsg()", pollintervall);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
clearTimeout(timer_ID);
timer_ID = setTimeout("waitForMsg()", 15000);
setPollerr(1);
}
});
}
/*
* General: Set Poll Interval
*/
function setPollrefresh() {
// Set pollintervall, if pollrefresh set to 0 disable polling
if (pollrefresh) {
pollintervall = parseInt(pollrefresh) * 1000;
if (pollintervall > 99000) pollintervall = 99000;
if (!nostorage) {
if (sessionStorage.pollintervall) pollintervall = sessionStorage.pollintervall;
else sessionStorage.pollintervall = pollintervall;
if (sessionStorage.polling == 1) polling = 1;
}
}
}
// static for paranoid Browsers
var nostorage = 0;
/*
* General: Start Polling
*/
$(document).ready(function () {
try {
if (!localStorage) {
nostorage = 1;
// remove whole filter block - makes no sense
// without saving
$('#regex').remove();
}
} catch(err){
nostorage = 1;
$('#regex').remove();
}
// set default to nothing excluded
poll_excluded = '';
// help wiki links
if (typeof oscamconf != "undefined") {
var wikihref = "https://git.streamboard.tv/common/oscam/-/wikis/pages/configuration/oscam." + oscamconf + "#";
$("form table a").click(function () {
if (!$(this).attr("href") && !$(this).attr("name")) {
if ($(this).data('p')) {
var parm = $(this).data('p');
} else {
var parm = $(this).parent().next().find("input,select,textarea").attr('name');
}
window.open(wikihref + parm);
}
});
}
// Title
var pagename = (typeof page != 'undefined' ? page : $(location).attr('pathname').replace(/.*\/|\.[^.]*$/g, ''));
$(document).attr('title', $(document).attr('title') + ' (' + pagename[0].toUpperCase() + pagename.slice(1) + ')');
if (typeof page != 'undefined') {
switch (page) {
case 'livelog':
var saved_regex = localStorage.MAX_SEARCH_PATTERN;
MAX_SEARCH_PATTERN = parseInt(saved_regex ? saved_regex : MAX_SEARCH_PATTERN);
$('<LI style="display:none;"><span class="colorPicker_def_color"></span><span class="colorPicker_def_fcolor"></span></LI>').insertBefore(".regexdata_save");
var beep_disabled = ' disabled="disabled" title="Not supported by your browser"';
var contextClass = (window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext);
if (contextClass) { beep_disabled = ''; }
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
var prefix = "0";
if ( i > 9 ) { prefix = ""; }
$('<LI class="regex" id="regexrow' + i + '">Search' + prefix + i + ': <input type="text" name="regex' + i + '" class="regexinput" ID="regex' + i + '" value=""> Found only: <input type="checkbox" id="whitelisted' + i + '"><label></label> Hide: <input type="checkbox" id="hidden' + i + '"><label></label> Back Color: <input size="7" maxlength="7" type="text" name="color' + i + '" class="colorinput" ID="color' + i + '" value=""> Color: <input size="7" maxlength="7" type="text" name="fcolor' + i + '" class="colorinput" ID="fcolor' + i + '" value=""> Beep: <input type="checkbox" id="beep' + i + '"' + beep_disabled +'><label></label></LI>').insertBefore(".regexdata_save");
}
if (!nostorage) {
for (var i = 1; i < MAX_SEARCH_PATTERN + 1; i++) {
var pattern = localStorage['regex' + i];
var color = localStorage['color' + i];
var fcolor = localStorage['fcolor' + i];
$('#regex' + i).val(pattern ? pattern : '');
$('#color' + i).val(color ? color : $('.colorPicker_def_color').css('color'));
$('#fcolor' + i).val(fcolor ? fcolor : $('.colorPicker_def_fcolor').css('color'));
$('#color' + i).colorPicker();
$('#fcolor' + i).colorPicker();
$('#whitelisted' + i).prop('checked', localStorage['whitelisted' + i] == '1' ? true : false);
$('#hidden' + i).prop('checked', localStorage['hidden' + i] == '1' ? true : false);
$('#beep' + i).prop('checked', localStorage['beep' + i] == '1' ? true : false);
}
}
waitForMsg();
break;
case 'status':
$(".status tbody:empty").hide();
$("#chart").hide();
if (!nostorage) {
if (localStorage.loi == 'Login*') {
$("#onlineidle")
.text('Login*')
.css('cursor','pointer')
.attr('title', 'Online & Idle info (click to switch)');
} else {
$("#onlineidle")
.text('Online & Idle*')
.css('cursor','pointer')
.attr('title', 'Login info (click to switch)');
}
}
break;
default:
break;
}
// if pollrefresh set to 0 hide pollselector
setPollrefresh();
if (pollrefresh) {
if (polling) {
$(":text[name='pintervall']").val('--');
$('#polling').attr('class','pollingdisabled');
$('#inc, #dec').attr('disabled','disabled');
} else {
$(":text[name='pintervall']").val(pollintervall / 1000);
$('#polling').attr('class','pollingenabled');
$('#inc, #dec').removeAttr('disabled');
waitForMsg();
}
$("#poll").show();
}
}
});
function decodeVideoguardEMM(text, target, addHideButton) {
text = text.trim();
var bytes = text.replace(/[^A-Fa-f0-9]/g, "").toUpperCase().match(/.{1,2}/g) || [];
var html = '';
if (addHideButton) {
html += '<p><input type="button" value="Hide" title="Hide" onclick="$(\'' + target + '\').css(\'display\', \'none\');" /></p><br/>';
}
var AddTextType = {"data":"Data", "length":"Length", "type":"Type", "emmType":"EMM-Type", "encryptionType":"Encryption Type",
"keyIndex":"Key-Index", "keyIndex2":"Key-Index2", "fixedValue":"Fixed Value", "pairingDevice":"Pairing Device", "date":"Date",
"checksum":"Checksum", "emmStartMarker":"EMM Marker", "cardSerial":"Serial Number (Smartcard)",
"boxSerial":"Serial Number (Receiver)", "emmEndMarker":"Sub-EMM End", "rest":"rest ????",
"cardEmmLength":"Card EMM Length", "cardNanoLength":"Card Nano Length", "irdEmmLength":"IRD EMM Length",
"filterSectionLength":"Filter Section Length", "irdNanoLength":"IRD Nano Length", "cardNanoType":"Card Nano Type",
"irdNanoType":"IRD Nano Type", "filterNanoType":"Filter Nano Type", "cardGroupSerial":"Serial Number (Card Group)",
"mpegSectionLength":"EMM Length", "irdEmmChecksum":"IRD EMM Checksum", "pairingdeviceCount":"Pairing Device Count"};
function addText(count, color, text, parm) {
html += '<font style="color: ' + color + '"><b>';
var ret = '';
for (var i = 0; i < count; i++) {
var v = bytes.shift();
if (typeof v === 'undefined') {
v = 'XX';
}
html += v + ' ';
ret += v;
if (((i + 1) % 16) == 0) {
html += '<br/>';
}
}
switch (text) {
case AddTextType.emmStartMarker:
if(ret.substring(2) == '00') {
text += " (cccam)";
}
break;
case AddTextType.mpegSectionLength:
var len = ((parseInt(parm, 16) << 8) + parseInt(ret, 16)) & 0x0FFF;
text += ' - <b>' + len + '</b>';
if (bytes.length >= len) {
text += ' - <font style="color:#009900"><b>OK (' + bytes.length + ')</b></font>';
} else {
text += ' - <font style="color:#F00000"><b>FAIL (' + bytes.length + ')</b></font>';
}
ret = len;
break;
case AddTextType.length:
case AddTextType.cardEmmLength:
case AddTextType.cardNanoLength:
case AddTextType.irdEmmLength:
case AddTextType.filterSectionLength:
case AddTextType.irdNanoLength:
var len = parseInt(ret, 16);
text += ' - <b>' + len + '</b>';
if (bytes.length >= len) {
text += ' - <font style="color:#009900"><b>OK (' + bytes.length + ')</b></font>';
} else {
text += ' - <font style="color:#F00000"><b>FAIL (' + bytes.length + ')</b></font>';
}
ret = len;
break;
case AddTextType.type:
var type = parseInt(ret, 16) & 0xC0;
var subEmmCount = ((parseInt(ret, 16) & 0x30) >> 16) + 1;
if (type == 0x40) {
text += ' - <b>unique</b> EMM For Smartcard';
}
else if (type == 0xC0) {
text += ' - <b>unique</b> EMM For Receiver/CAM';
}
else if (type == 0x80) {
text += ' - <b>shared</b> EMM For Smartcard';
}
else {
text += ' - <b>global</b> EMM';
}
text += ' (' + subEmmCount + ' Sub EMMs)';
break;
case AddTextType.emmType:
switch (ret) {
case '02':
text += ' - <b>Default</b>';
break;
case '07':
text += ' - <b>With Filter Nanos</b>';
break;
default:
text += ' - <b>unknown</b>';
break;
}
break;
case AddTextType.encryptionType:
switch (ret) {
case '44':
text += ' - <b>User-Encryption</b>';
break;
case '60':
text += ' - <b>System-Encryption</b>';
break;
case '40':
text += ' - <b>System-Encryption</b>';
break;
default:
text += ' - <b>unknown</b>';
break;
}
break;
case AddTextType.cardNanoType:
switch (ret) {
case '01':
text += ' - <b>Set date</b>';
break;
case '90':
text += ' - <b>Encrypted Nano</b>';
break;
case '41':
text += ' - <b>Add a ChID</b>';
break;
case '42':
text += ' - <b>Delete a ChID</b>';
break;
default:
text += ' - <b>unknown</b>';
break;
}
break;
case AddTextType.irdNanoType:
switch (ret) {
case '02':
text += ' - <b>Set Date/Time</b>';
break;
case '07':
case '08':
text += ' - <b>Download Firmware</b>';
break;
case '2B':
text += ' - <b>Pairing Data</b>';
break;
default:
text += ' - <b>unknown</b>';
break;
}
break;
case AddTextType.filterNanoType:
switch (ret) {
case '30':
text += ' - <b>Always Valid</b>';
break;
case '31':
text += ' - <b>Card Address</b>';
break;
default:
text += ' - <b>unknown</b>';
break;
}
break;
case AddTextType.keyIndex:
if (!isV14V15) {
text += ' - <b>' + ret + '</b>';
}
switch (ret) {
case '01':
text += ' - <b>V14</b>';
break;
case '02':
text += ' - <b>V15</b>';
break;
default:
text += ' - <b>unknown</b>';
break;
}
break;
case AddTextType.keyIndex2:
text += ' - <b>unknown</b>';
break;
case AddTextType.fixedValue:
if (ret == parm) {
text += ' - <font style="color:#009900"><b>OK</b></font>';
} else {
text += ' - <font style="color:#F00000"><b>FAIL (' + parm + ')</b></font>';
}
break;
case AddTextType.pairingDevice:
switch (ret) {
default: text += ' - <b>Device ' + ret + '</b>';
break;
}
break;
case AddTextType.date:
var b = ret.replace(/[^A-Fa-f0-9]/g, "").match(/.{1,2}/g) || [];
var bin = parseInt(b[2] + b[3], 16);
var time = {};
time.s = ((bin & parseInt('11111', 2)) * 2);
bin = bin >>> 5;
time.m = (bin & parseInt('111111', 2));
bin = bin >>> 6;
time.h = (bin & parseInt('11111', 2));
bin = bin >>> 5;
bin = parseInt(b[0] + b[1], 16);
var date = {};
date.d = (bin & parseInt('11111111', 2));
bin = bin >>> 8;
date.m = (bin & parseInt('11111111', 2));
bin = bin >>> 8;
date.y = parseInt(date.m / 12) + 2004;
date.m -= (((date.y - 2004) * 12) - 1);
text += ' - <b>' + date.d + '.' + date.m + '.' + date.y + '</b>';
text += ' <b>' + time.h + ':' + time.m + ':' + time.s + ' UTC</b>';
break;
case AddTextType.checksum:
case AddTextType.irdEmmChecksum:
var checksumData = parseInt(ret, 16);
var checksum = 0x00;
for(var i = 0; i < parm.length; i++) {
checksum += parseInt(parm[i], 16);
checksum &= 0xFF;
}
if (checksumData == checksum) {
text += ' - <font style="color:#009900"><b>OK</b></font>';
} else {
text += ' - <font style="color:#F00000"><b>FAIL (' + checksum.toString(16).toUpperCase() + ')</b></font>';
}
break;
}
html += '</b></font> - ' + text + '<br/>';
return ret;
}
function ReadSingleCardEMM() {
var cardEmmLength = addText(1, '#00F', AddTextType.cardEmmLength);
var remainingDataLength = cardEmmLength;
while (remainingDataLength > 0 && bytes.length) {
var cardNanoType = addText(1, '#008000', AddTextType.cardNanoType);
var fixedSizeNanos = {
"01": 0x04,
"09": 0x03,
"10": 0x02,
"19": 0x01,
"1E": 0x08,
"24": 0x00,
"25": 0x00,
"27": 0x0D,
"2B": 0x02,//0x03
"2D": 0x04,
"30": 0x00,
"31": 0x04,//0x03
"32": 0x03,
"33": 0x23,
"3D": 0x02,
"3E": 0x00,
"41": 0x05,//0x04
"42": 0x02,
"44": 0x04,
"4E": 0x04,
"7A": 0x02,
"02": 0x01,
"03": 0x03,
"04": 0x00,
"48": 0x00,
"C0": 0x00,
};
if (fixedSizeNanos[cardNanoType] != undefined) {
if (cardNanoType == "01") {
addText(4, '#00A0A0', AddTextType.date);
}
else {
addText(fixedSizeNanos[cardNanoType], '#000', AddTextType.data);
}
remainingDataLength -= fixedSizeNanos[cardNanoType] + 1;
}
else {
var cardNanoLength = addText(1, '#00F', AddTextType.cardNanoLength);
if (cardNanoType == "90") {
var encryptionType = addText(1, '#b22222', AddTextType.encryptionType);
switch (encryptionType) {
case '40':
case '44':
case '60':
addText(1, '#b22222', AddTextType.keyIndex);
addText((cardNanoLength - 2), '#000', AddTextType.data);
break;
default:
addText(1, '#b22222', AddTextType.keyIndex2);
addText((cardNanoLength - 2), '#000', AddTextType.data);
break;
}
}
else {
addText(cardNanoLength, '#000', AddTextType.data);
}
remainingDataLength -= cardNanoLength + 2;
}
}
}
function ReadIrdNano() {
var irdNanoType = addText(1, '#008000', AddTextType.irdNanoType);
var fixedSizeNanos = {
"02": 0x04,
};
if (fixedSizeNanos[irdNanoType] != undefined) {
if (irdNanoType == "02") {
addText(4, '#00A0A0', AddTextType.date);
}
else {
addText(fixedSizeNanos[cardNanoType], '#000', AddTextType.data);
}
return fixedSizeNanos[irdNanoType] + 1;
}
else {
var irdNanoLength = addText(1, '#00F', AddTextType.irdNanoLength);
switch (irdNanoType) {
case '2B':
addText(1, '#000', AddTextType.pairingdeviceCount);
var remainingDataLengthNano = irdNanoLength - 1;
while (remainingDataLengthNano > 0 && bytes.length) {
var startLength = bytes.length;
addText(1, '#E000E0', AddTextType.pairingDevice);
addText(4, '#cc7000', AddTextType.boxSerial);
ReadSingleCardEMM();
remainingDataLengthNano -= startLength - bytes.length;
}
break;
default:
addText(irdNanoLength, '#000', AddTextType.data);
break;
}
return irdNanoLength + 2;
}
}
var partOfLength = bytes[1];
addText(2, '#000', AddTextType.emmStartMarker);
addText(1, '#00F', AddTextType.mpegSectionLength, partOfLength);
var filterByte = parseInt(addText(1, '#199a8d', AddTextType.type), 16);
var type = filterByte & 0xC0;
var subEmmCount = ((filterByte & 0x30) >> 16) + 1;
if(partOfLength != 0) { // partOfLength == 0 for emms by cccam clients, these do not have the serials part
for(var i = 0; i < subEmmCount; i++) {
if (type == 0x40) { // unique: card
addText(4, '#cc7000', AddTextType.cardSerial);
} else if (type == 0xC0) { // unique: receiver/cam
addText(4, '#cc7000', AddTextType.boxSerial);
} else if (type == 0x80) { // shared: card group
addText(3, '#cc7000', AddTextType.cardGroupSerial);
addText(1, '#000', AddTextType.fixedValue, '01');
}
}
}
while (bytes.length) {
var emmtype = addText(1, '#008000', AddTextType.emmType);
var irdEmmLength = addText(1, '#00F', AddTextType.irdEmmLength);
var checksumData = {};
if (irdEmmLength > 0) {
checksumData = bytes.slice(0, irdEmmLength - 1);
checksumData.unshift(irdEmmLength.toString(16));
checksumData.unshift(emmtype);
}
if (irdEmmLength > 0) {
switch (emmtype) {
case '02':
var remainingDataLength = irdEmmLength - 1;
while(remainingDataLength > 0 && bytes.length) {
remainingDataLength -= ReadIrdNano();
}
break;
case '07':
var filterSectionLength = addText(1, '#00F', AddTextType.filterSectionLength);
var remainingDataLength = filterSectionLength;
while (remainingDataLength > 0 && bytes.length) {
var filterNano = addText(1, '#008000', AddTextType.filterNanoType);
switch (filterNano) {
case '30':
remainingDataLength -= 1;
break;
case '31':
addText(4, '#cc7000', AddTextType.cardSerial);
remainingDataLength -= 5;
break;
default:
addText(remainingDataLength - 1, '#000', AddTextType.data);
remainingDataLength = 0;
break;
}
}
var remainingDataLength = irdEmmLength - 1 - filterSectionLength - 1;
while(remainingDataLength > 0 && bytes.length) {
remainingDataLength -= ReadIrdNano();
}
break;
default:
addText(irdEmmLength - 1, '#000', AddTextType.data);
break;
}
addText(1, '#800080', AddTextType.irdEmmChecksum, checksumData);
}
ReadSingleCardEMM();
}
$(target).html(html);
}
/**
* Really Simple Color Picker in jQuery
*
* Licensed under the MIT (MIT-LICENSE.txt) licenses.
*
* Copyright (c) 2008-2012
* Lakshan Perera (www.laktek.com) & Daniel Lacy (daniellacy.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
(function (e) {
var t, n, r = 0,
i = {
control: e('<div class="colorPicker-picker">&nbsp;</div>'),
palette: e('<div id="colorPicker_palette" class="colorPicker-palette" />'),
swatch: e('<div class="colorPicker-swatch">&nbsp;</div>'),
hexLabel: e('<label for="colorPicker_hex">Hex</label>'),
hexField: e('<input type="text" id="colorPicker_hex" />')
},
s = "transparent",
o;
e.fn.colorPicker = function (t) {
return this.each(function () {
var n = e(this),
o = e.extend({}, e.fn.colorPicker.defaults, t),
u = e.fn.colorPicker.toHex(n.val().length > 0 ? n.val() : o.pickerDefault),
a = i.control.clone(),
f = i.palette.clone().attr("id", "colorPicker_palette-" + r),
l = i.hexLabel.clone(),
c = i.hexField.clone(),
h = f[0].id,
p, d;
e.each(o.colors, function (t) {
p = i.swatch.clone();
if (o.colors[t] === s) {
p.addClass(s).text("X");
e.fn.colorPicker.bindPalette(c, p, s)
} else {
p.css("background-color", "#" + this);
e.fn.colorPicker.bindPalette(c, p)
}
p.appendTo(f)
});
l.attr("for", "colorPicker_hex-" + r);
c.attr({
id: "colorPicker_hex-" + r,
value: u
});
c.bind("keydown", function (t) {
if (t.keyCode === 13) {
var r = e.fn.colorPicker.toHex(e(this).val());
e.fn.colorPicker.changeColor(r ? r : n.val())
}
if (t.keyCode === 27) {
e.fn.colorPicker.hidePalette()
}
});
c.bind("keyup", function (t) {
var r = e.fn.colorPicker.toHex(e(t.target).val());
e.fn.colorPicker.previewColor(r ? r : n.val())
});
c.bind("blur", function (t) {
var r = e.fn.colorPicker.toHex(e(this).val());
e.fn.colorPicker.changeColor(r ? r : n.val())
});
e('<div class="colorPicker_hexWrap" />').append(l).appendTo(f);
f.find(".colorPicker_hexWrap").append(c);
if (o.showHexField === false) {
c.hide();
l.hide()
}
e("body").append(f);
f.hide();
a.css("background-color", u);
a.bind("click", function () {
if (n.is(":not(:disabled)")) {
e.fn.colorPicker.togglePalette(e("#" + h), e(this))
}
});
if (t && t.onColorChange) {
a.data("onColorChange", t.onColorChange)
} else {
a.data("onColorChange", function () {})
} if (d = n.data("text")) a.html(d);
n.after(a);
n.bind("change", function () {
n.next(".colorPicker-picker").css("background-color", e.fn.colorPicker.toHex(e(this).val()))
});
n.val(u);
if (n[0].tagName.toLowerCase() === "input") {
try {
n.attr("type", "hidden")
} catch (v) {
n.css("visibility", "hidden").css("position", "absolute")
}
} else {
n.hide()
}
r++
})
};
e.extend(true, e.fn.colorPicker, {
toHex: function (e) {
if (e.match(/[0-9A-F]{6}|[0-9A-F]{3}$/i)) {
return e.charAt(0) === "#" ? e : "#" + e
} else if (e.match(/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/)) {
var t = [parseInt(RegExp.$1, 10), parseInt(RegExp.$2, 10), parseInt(RegExp.$3, 10)],
n = function (e) {
if (e.length < 2) {
for (var t = 0, n = 2 - e.length; t < n; t++) {
e = "0" + e
}
}
return e
};
if (t.length === 3) {
var r = n(t[0].toString(16)),
i = n(t[1].toString(16)),
s = n(t[2].toString(16));
return "#" + r + i + s
}
} else {
return false
}
},
checkMouse: function (r, i) {
var s = n,
o = e(r.target).parents("#" + s.attr("id")).length;
if (r.target === e(s)[0] || r.target === t[0] || o > 0) {
return
}
e.fn.colorPicker.hidePalette()
},
hidePalette: function () {
e(document).unbind("mousedown", e.fn.colorPicker.checkMouse);
e(".colorPicker-palette").hide()
},
showPalette: function (n) {
var r = t.prev("input").val();
n.css({
top: t.offset().top + t.outerHeight(),
left: t.offset().left
});
e("#color_value").val(r);
n.show();
e(document).bind("mousedown", e.fn.colorPicker.checkMouse)
},
togglePalette: function (r, i) {
if (i) {
t = i
}
n = r;
if (n.is(":visible")) {
e.fn.colorPicker.hidePalette()
} else {
e.fn.colorPicker.showPalette(r)
}
},
changeColor: function (n) {
t.css("background-color", n);
t.prev("input").val(n).change();
e.fn.colorPicker.hidePalette();
t.data("onColorChange").call(t, e(t).prev("input").attr("id"), n)
},
previewColor: function (e) {
t.css("background-color", e)
},
bindPalette: function (n, r, i) {
i = i ? i : e.fn.colorPicker.toHex(r.css("background-color"));
r.bind({
click: function (t) {
o = i;
e.fn.colorPicker.changeColor(i)
},
mouseover: function (t) {
o = n.val();
e(this).css("border-color", "#598FEF");
n.val(i);
e.fn.colorPicker.previewColor(i)
},
mouseout: function (r) {
e(this).css("border-color", "#000");
n.val(t.css("background-color"));
n.val(o);
e.fn.colorPicker.previewColor(o)
}
})
}
});
e.fn.colorPicker.defaults = {
pickerDefault: "FFFFFF",
colors: ["000000", "993300", "333300", "000080", "333399", "333333", "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080", "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "999999", "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0", "FF99CC", "FFCC99", "FFFF99", "CCFFFF", "99CCFF", "FFFFFF"],
addColors: [],
showHexField: true
}
})(jQuery);
/**
* Stupid jQuery Table Sort
* Copyright (c) 2012 Joseph McCullough
* https://github.com/joequery/Stupid-Table-Plugin#readme
*/
(function (e) {
e.fn.stupidtable = function (t) {
return this.each(function () {
var n = e(this);
t = t || {};
t = e.extend({}, e.fn.stupidtable.default_sort_fns, t);
n.on("click.stupidtable", "th", function () {
var r = e(this);
var i = 0;
var s = e.fn.stupidtable.dir;
n.find("#headline > th").slice(0, r.index()).each(function () {
var t = e(this).attr("colspan") || 1;
i += parseInt(t, 10)
});
var o = r.data("sort-default") || s.ASC;
if (r.data("sort-dir")) o = r.data("sort-dir") === s.ASC ? s.DESC : s.ASC;
var u = r.data("sort") || null;
if (u === null) {
return
}
n.trigger("beforetablesort", {
column: i,
direction: o
});
n.css("display");
setTimeout(function () {
var a = [];
var f = t[u];
var l = n.children("tbody").children("tr");
l.each(function (t, n) {
var r = e(n).children().eq(i);
var s = r.data("sort-value");
var o = typeof s !== "undefined" ? s : r.text();
a.push([o, n])
});
a.sort(function (e, t, s) {
return f(e[0], t[0], o)
});
if (o != s.ASC) a.reverse();
l = e.map(a, function (e) {
return e[1]
});
n.children("tbody").append(l);
n.find("th.sorting-desc, th.sorting-asc").data("sort-dir", null).removeClass("sorting-desc sorting-asc").addClass("sortable");
r.data("sort-dir", o).removeClass("sortable").addClass("sorting-" + o);
$('tr').find('td.td-sorting').removeClass('td-sorting');
$('tr').find('td:eq(' + i + ')').addClass('td-sorting');
n.trigger("aftertablesort", {
column: i,
direction: o
});
n.css("display")
}, 10)
})
})
};
e.fn.stupidtable.dir = {
ASC: "asc",
DESC: "desc"
};
var convert_locale = function (c) {
if (c == "") return 0;
if(locale_decpoint == ",") {
c = c.toString().replace( /\./g,"" ).replace( /,/,"." );
}else if(locale_decpoint == "."){
c = c.toString().replace( /,/g,"" );
}
return(c);
}
var ip2int = function dot2num(dot, s) {
if (dot == "" && s == "asc") return 4300000000;
if (dot == "" && s == "desc") return 1;
var d = dot.split('.');
return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}
e.fn.stupidtable.default_sort_fns = {
"int": function (e, t, s) {
return parseInt(convert_locale(e), 10) - parseInt(convert_locale(t), 10)
},
"float": function (e, t, s) {
return parseFloat(convert_locale(e)) - parseFloat(convert_locale(t))
},
"ip": function (a, b, s) {
aIP = ip2int(a, s);
bIP = ip2int(b, s);
return aIP - bIP;
},
"string": function (e, t, s) {
if (e == "" && s == "asc") return +1;
if (t == "" && s == "asc") return -1;
if (e < t) return -1;
if (e > t) return +1;
return 0
},
"string-ins": function (e, t, s) {
e = e.toString().toLowerCase();
t = t.toString().toLowerCase();
if (e == "" && s == "asc") return +1;
if (t == "" && s == "asc") return -1;
if (e < t) return -1;
if (e > t) return +1;
return 0
}
}
})(jQuery)
// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
/*
* OSCam WebIf Wiki Help System
* If wikiInternal is true (set by server when WEBIF_WIKI is compiled in),
* show local wiki popup. Otherwise, open external wiki directly (old behavior).
*/
var wikiPopupHtml = '<div id="wikiPopup" class="wiki-popup">' +
'<div class="wiki-popup-header">' +
'<a class="wiki-popup-title" href="#" target="_blank"></a>' +
'<span class="wiki-popup-reset" title="Reset position and size">&#8634;</span>' +
'<span class="wiki-popup-close" title="Close">&times;</span>' +
'</div>' +
'<div class="wiki-popup-content"></div>' +
'</div>';
var wikiDragState = { isDragging: false, startX: 0, startY: 0, startLeft: 0, startTop: 0 };
var wikiSavedLeft = localStorage.getItem('wikiPopupLeft');
var wikiSavedWidth = localStorage.getItem('wikiPopupWidth');
var wikiSavedHeight = localStorage.getItem('wikiPopupHeight');
var wikiDefaultWidth = 400;
var wikiLastLinkOffset = 0;
var wikiUserResized = !!(wikiSavedWidth || wikiSavedHeight);
var wikiCurrentLink = null;
var wikiConnectorLine = null;
/* Draw connector line between link and popup */
function updateWikiConnector() {
if (!wikiCurrentLink || !$('#wikiPopup').is(':visible')) {
if (wikiConnectorLine) {
wikiConnectorLine.remove();
wikiConnectorLine = null;
}
return;
}
var $link = wikiCurrentLink;
var $popup = $('#wikiPopup');
/* Calculate positions */
var linkOffset = $link.offset();
var linkRight = linkOffset.left + $link.outerWidth();
var linkCenterY = linkOffset.top + $link.outerHeight() / 2;
var popupOffset = $popup.offset();
var popupLeft = popupOffset.left;
var popupCenterY = popupOffset.top + 20; /* Connect to header area */
/* Create or update SVG line */
if (!wikiConnectorLine) {
wikiConnectorLine = $('<svg class="wiki-connector"><line/></svg>');
$('body').append(wikiConnectorLine);
}
/* Position SVG to cover the area between link and popup */
var minX = Math.min(linkRight, popupLeft) - 5;
var maxX = Math.max(linkRight, popupLeft) + 5;
var minY = Math.min(linkCenterY, popupCenterY) - 5;
var maxY = Math.max(linkCenterY, popupCenterY) + 5;
wikiConnectorLine.css({
position: 'absolute',
left: minX,
top: minY,
width: maxX - minX,
height: maxY - minY,
pointerEvents: 'none',
zIndex: 1
});
wikiConnectorLine.find('line').attr({
x1: linkRight - minX,
y1: linkCenterY - minY,
x2: popupLeft - minX,
y2: popupCenterY - minY,
stroke: '#ffcc00',
'stroke-width': 2
});
}
function removeWikiConnector() {
if (wikiConnectorLine) {
wikiConnectorLine.remove();
wikiConnectorLine = null;
}
}
$(function() {
if (typeof oscamconf === 'undefined') return;
/* Check if internal wiki is enabled (WEBIF_WIKI compiled in) */
if (typeof wikiInternal === 'undefined' || wikiInternal !== true) {
/* No internal wiki - external wiki links are handled in document.ready above */
return;
}
/* Internal wiki enabled - setup popup and override click handler */
$('body').append(wikiPopupHtml);
$('.wiki-popup-close').click(function() {
$('#wikiPopup').fadeOut(200);
removeWikiConnector();
if (wikiCurrentLink) {
wikiCurrentLink.removeClass('wiki-active');
wikiCurrentLink = null;
}
});
$('.wiki-popup-reset').click(function() {
localStorage.removeItem('wikiPopupLeft');
localStorage.removeItem('wikiPopupWidth');
localStorage.removeItem('wikiPopupHeight');
wikiSavedLeft = null;
wikiSavedWidth = null;
wikiSavedHeight = null;
wikiUserResized = false;
var $popup = $('#wikiPopup');
/* Recalculate position based on current link */
if (wikiCurrentLink) {
var offset = wikiCurrentLink.offset();
wikiLastLinkOffset = offset.left + wikiCurrentLink.outerWidth();
var defaultLeft = wikiLastLinkOffset + 10;
if (defaultLeft + 420 > $(window).width()) {
defaultLeft = $(window).width() - 420;
}
$popup.css({ width: wikiDefaultWidth, height: 'auto', left: defaultLeft, top: offset.top - 10 });
} else {
var defaultLeft = wikiLastLinkOffset + 10;
if (defaultLeft + 420 > $(window).width()) {
defaultLeft = $(window).width() - 420;
}
$popup.css({ width: wikiDefaultWidth, height: 'auto', left: defaultLeft });
}
setTimeout(updateWikiConnector, 50);
});
$(document).click(function(e) {
if (!$(e.target).closest('#wikiPopup').length &&
!$(e.target).closest('form table a').length) {
$('#wikiPopup').fadeOut(200);
removeWikiConnector();
if (wikiCurrentLink) {
wikiCurrentLink.removeClass('wiki-active');
wikiCurrentLink = null;
}
}
});
$(document).keydown(function(e) {
if (e.keyCode === 27) {
$('#wikiPopup').fadeOut(200);
removeWikiConnector();
if (wikiCurrentLink) {
wikiCurrentLink.removeClass('wiki-active');
wikiCurrentLink = null;
}
}
/* Arrow keys to navigate between parameters when popup is open */
if ((e.keyCode === 38 || e.keyCode === 40) && $('#wikiPopup').is(':visible') && wikiCurrentLink) {
var $allLinks = $('form table a').filter(function() {
return !$(this).attr('href') && $(this).text().trim();
});
var currentIndex = $allLinks.index(wikiCurrentLink);
var newIndex;
if (e.keyCode === 38) {
/* Arrow up - previous parameter */
if (currentIndex > 0) {
e.preventDefault();
newIndex = currentIndex - 1;
var $newLink = $allLinks.eq(newIndex);
$newLink.click();
/* Scroll into view if needed */
var linkTop = $newLink.offset().top;
var scrollTop = $(window).scrollTop();
if (linkTop < scrollTop + 50) {
$('html, body').animate({ scrollTop: linkTop - 100 }, 150);
}
}
} else {
/* Arrow down - next parameter */
if (currentIndex < $allLinks.length - 1) {
e.preventDefault();
newIndex = currentIndex + 1;
var $newLink = $allLinks.eq(newIndex);
$newLink.click();
/* Scroll into view if needed */
var linkBottom = $newLink.offset().top + $newLink.outerHeight();
var windowBottom = $(window).scrollTop() + $(window).height();
if (linkBottom > windowBottom - 50) {
$('html, body').animate({ scrollTop: $newLink.offset().top - $(window).height() + 150 }, 150);
}
}
}
}
});
/* Drag functionality for popup */
$('.wiki-popup-header').css('cursor', 'move').on('mousedown', function(e) {
if ($(e.target).hasClass('wiki-popup-close') || $(e.target).hasClass('wiki-popup-reset') || $(e.target).hasClass('wiki-popup-title')) return;
wikiDragState.isDragging = true;
wikiDragState.startX = e.pageX;
wikiDragState.startY = e.pageY;
wikiDragState.startLeft = parseInt($('#wikiPopup').css('left')) || 0;
wikiDragState.startTop = parseInt($('#wikiPopup').css('top')) || 0;
e.preventDefault();
});
/* Touch support for drag */
$('.wiki-popup-header').on('touchstart', function(e) {
if ($(e.target).hasClass('wiki-popup-close') || $(e.target).hasClass('wiki-popup-reset') || $(e.target).hasClass('wiki-popup-title')) return;
var touch = e.originalEvent.touches[0];
wikiDragState.isDragging = true;
wikiDragState.startX = touch.pageX;
wikiDragState.startY = touch.pageY;
wikiDragState.startLeft = parseInt($('#wikiPopup').css('left')) || 0;
wikiDragState.startTop = parseInt($('#wikiPopup').css('top')) || 0;
});
$(document).on('touchmove', function(e) {
if (!wikiDragState.isDragging) return;
var touch = e.originalEvent.touches[0];
var newLeft = wikiDragState.startLeft + (touch.pageX - wikiDragState.startX);
var newTop = wikiDragState.startTop + (touch.pageY - wikiDragState.startY);
newLeft = Math.max(0, Math.min(newLeft, $(window).width() - 420));
newTop = Math.max(0, newTop);
$('#wikiPopup').css({ left: newLeft, top: newTop });
updateWikiConnector();
e.preventDefault();
});
$(document).on('touchend', function() {
if (wikiDragState.isDragging) {
wikiDragState.isDragging = false;
wikiSavedLeft = $('#wikiPopup').css('left');
localStorage.setItem('wikiPopupLeft', wikiSavedLeft);
}
});
$(document).on('mousemove', function(e) {
if (!wikiDragState.isDragging) return;
var newLeft = wikiDragState.startLeft + (e.pageX - wikiDragState.startX);
var newTop = wikiDragState.startTop + (e.pageY - wikiDragState.startY);
newLeft = Math.max(0, Math.min(newLeft, $(window).width() - 420));
newTop = Math.max(0, newTop);
$('#wikiPopup').css({ left: newLeft, top: newTop });
updateWikiConnector();
});
$(document).on('mouseup', function() {
if (wikiDragState.isDragging) {
wikiDragState.isDragging = false;
wikiSavedLeft = $('#wikiPopup').css('left');
localStorage.setItem('wikiPopupLeft', wikiSavedLeft);
}
});
/* Save size after user resize */
var wikiLastWidth = 0;
var wikiLastHeight = 0;
$('#wikiPopup').on('mouseup', function() {
var w = $(this).width();
var h = $(this).height();
if (wikiLastWidth && wikiLastHeight && (w !== wikiLastWidth || h !== wikiLastHeight)) {
wikiUserResized = true;
wikiSavedWidth = w;
wikiSavedHeight = h;
localStorage.setItem('wikiPopupWidth', wikiSavedWidth);
localStorage.setItem('wikiPopupHeight', wikiSavedHeight);
}
wikiLastWidth = w;
wikiLastHeight = h;
});
$('form table a').off('click').click(function(e) {
e.preventDefault();
e.stopPropagation();
/* Remove highlight from previous link */
if (wikiCurrentLink) {
wikiCurrentLink.removeClass('wiki-active');
}
/* Store current link for keyboard navigation and highlight it */
wikiCurrentLink = $(this);
wikiCurrentLink.addClass('wiki-active');
/* Get real input name for internal wiki lookup */
var $cell = $(this).parent();
var inputName = null;
/* Try 1: Input in next cell (standard layout) */
var $input = $cell.next().find('input,select,textarea').first();
/* Try 2: Input in same cell */
if (!$input.length) {
$input = $cell.find('input,select,textarea').first();
}
/* Try 3: For TH headers (like services), look in same column of next row */
if (!$input.length && $cell.is('th')) {
var cellIndex = $cell.index();
var $nextRow = $cell.closest('tr').next('tr');
if ($nextRow.length) {
var $correspondingCell = $nextRow.find('td, th').eq(cellIndex);
$input = $correspondingCell.find('input,select,textarea').first();
}
}
if ($input.length) {
inputName = $input.attr('name');
}
/* Get param for external wiki link (use data-p override if present) */
var externalParam = $(this).data('p') || inputName;
if (!inputName) return;
/* Extract section from form's hidden part input */
var section = $('input[name="part"]').val() || '';
var $link = $(this);
var $popup = $('#wikiPopup');
$('.wiki-popup-title').text(inputName).attr('href',
'https://git.streamboard.tv/common/oscam/-/wikis/pages/configuration/oscam.' + oscamconf + '#' + externalParam);
$('.wiki-popup-content').html('<div class="wiki-loading">Loading...</div>');
var offset = $link.offset();
wikiLastLinkOffset = offset.left + $link.outerWidth();
var leftPos;
if (wikiSavedLeft) {
leftPos = parseInt(wikiSavedLeft);
} else {
leftPos = offset.left + $link.outerWidth() + 10;
if (leftPos + 420 > $(window).width()) {
leftPos = $(window).width() - 420;
}
}
$popup.css({
top: offset.top - 10,
left: leftPos,
width: wikiUserResized && wikiSavedWidth ? parseInt(wikiSavedWidth) : wikiDefaultWidth,
height: wikiUserResized && wikiSavedHeight ? parseInt(wikiSavedHeight) : 'auto',
'max-width': $(window).width() - 20,
'max-height': $(window).height() - 20
}).fadeIn(200);
/* Draw connector line */
setTimeout(updateWikiConnector, 50);
/* Update last size for resize detection */
setTimeout(function() {
wikiLastWidth = $popup.width();
wikiLastHeight = $popup.height();
}, 250);
$.ajax({
url: 'wiki.json',
type: 'GET',
data: { config: oscamconf, section: section, param: inputName },
dataType: 'json',
success: function(data) {
if (data && data.text) {
var html = formatWikiText(data.text);
$('.wiki-popup-content').html(html);
} else {
$('.wiki-popup-content').html(
'<div class="wiki-nohelp">No help available for this parameter.<br><br>' +
'<a href="https://git.streamboard.tv/common/oscam/-/wikis/pages/configuration/oscam.' +
oscamconf + '#' + externalParam + '" target="_blank">View Wiki &rarr;</a></div>'
);
}
},
error: function() {
$('.wiki-popup-content').html(
'<div class="wiki-error">Failed to load help.<br><br>' +
'<a href="https://git.streamboard.tv/common/oscam/-/wikis/pages/configuration/oscam.' +
oscamconf + '#' + externalParam + '" target="_blank">View Wiki &rarr;</a></div>'
);
}
});
});
});
function formatWikiText(text) {
if (!text) return '';
/* Convert escaped newlines to real newlines first */
text = text.replace(/\\n/g, '\n');
text = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
text = text.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre class="wiki-code">$2</pre>');
text = text.replace(/```([\s\S]*?)```/g, '<pre class="wiki-code">$1</pre>');
text = text.replace(/`([^`]+)`/g, '<code>$1</code>');
text = text.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
text = text.replace(/^### (.+)$/gm, '<h4>$1</h4>');
text = text.replace(/^## (.+)$/gm, '<h3>$1</h3>');
text = text.replace(/\n/g, '<br>');
text = text.replace(/<\/pre><br>/g, '</pre>');
return '<div class="wiki-text">' + text + '</div>';
}
/* Wiki documentation status toggle - shows icons for missing/review/ok documentation */
$(document).ready(function() {
if (typeof oscamconf === 'undefined' || typeof wikiInternal === 'undefined' || wikiInternal !== true) {
return;
}
var wikiStatusLoaded = false;
var wikiStatusVisible = false;
/* Support different table classes: config, configreader, configuser, configservices, writeemm */
var $allTables = $('table.config, table.configreader, table.configuser, table.configservices, table.writeemm');
if (!$allTables.length) return;
/* Only make the FIRST table header clickable */
var $firstHeader = $allTables.find('th[colspan]').first();
if (!$firstHeader.length) return;
$firstHeader.css('cursor', 'pointer').attr('title', 'Click to toggle documentation status icons');
$firstHeader.click(function() {
if (!wikiStatusLoaded) {
/* Load status for all parameters */
$.ajax({
url: 'wiki_status.json',
type: 'GET',
data: { config: oscamconf },
dataType: 'json',
success: function(data) {
if (data) {
/* Method 1: Find all <A> tags that are parameter labels */
$allTables.find('a').each(function() {
var $a = $(this);
/* Skip if already has icon */
if ($a.find('.wiki-status-icon').length) return;
/* Skip links with href (real links, not labels) */
if ($a.attr('href')) return;
/* Skip if no text */
var labelText = $a.text().trim();
if (!labelText) return;
/* Find associated input name */
var paramName = null;
var $cell = $a.closest('td, th');
/* Try 1: Input in same cell */
var $input = $cell.find('input,select,textarea').first();
/* Try 2: Input in next cell */
if (!$input.length) {
$input = $cell.next('td, th').find('input,select,textarea').first();
}
/* Try 3: For TH headers, look in same column of next row */
if (!$input.length && $cell.is('th')) {
var cellIndex = $cell.index();
var $nextRow = $cell.closest('tr').next('tr');
if ($nextRow.length) {
var $correspondingCell = $nextRow.find('td, th').eq(cellIndex);
$input = $correspondingCell.find('input,select,textarea').first();
}
}
if ($input.length) {
paramName = $input.attr('name');
}
if (!paramName) return;
var status = data[paramName];
var icon = '';
var tooltip = '';
if (status === 'missing') { icon = '❗ '; tooltip = 'Documentation missing'; }
else if (status === 'review') { icon = '⚠️ '; tooltip = 'Documentation needs review'; }
else if (status === 'ok') { icon = '✅ '; tooltip = 'Documentation complete'; }
if (icon) {
$a.prepend('<span class="wiki-status-icon" title="' + tooltip + '">' + icon + '</span>');
}
});
wikiStatusLoaded = true;
wikiStatusVisible = true;
$('.wiki-status-icon').addClass('visible');
}
}
});
} else {
/* Toggle visibility for ALL icons */
wikiStatusVisible = !wikiStatusVisible;
if (wikiStatusVisible) {
$('.wiki-status-icon').addClass('visible');
} else {
$('.wiki-status-icon').removeClass('visible');
}
}
});
});