
function $(id) {return document.getElementById(id);}
// ############### Mobile Device ################

if (window.screen.width < 769) {
  $('nav').style.display = 'none';
}

$('menu-icon').onclick = function(){
  $('nav').style.display = $('nav').style.display == 'none' ? 'block' : 'none';
};

//########## Main Page Alert Handler ############

// fadeIn animation special for alerts
function fadeIns(el){
  el.style.opacity = 0;
  (function fade() {
    var val = parseFloat(el.style.opacity);
    if (((val += 0.03) > 1) !== true) {
      el.style.opacity = val;
      var request = window.requestFrame('request');
      request(fade);
    }
  })();
}

var ac          = $('AC'),
  dc            = $('DC'),
  in_freq       = $('in_freq'),
  out_freq      = $('out_freq'),
  pwr           = $('pwr'),
  bat_cap       = $('bat_cap'),
  inner_temp    = $('inner_temp'),
  battimeleft   = $('bat_time_left'),
  // alarm         = $('alarm'),
  sPower        = $('sPower'),
  sBattery      = $('sBattery');
var battempCtrlChecked;

function dataFadeIn(){
  var x = [
    ac,
    dc,
    in_freq,
    out_freq,
    pwr,
    bat_cap,
    inner_temp,
    battimeleft,
    sPower,
    sBattery
  ];
  for (var i = 0; i < x.length; i++){
    fadeIns(x[i]);
  }
}

// Alarm colors
var ALARM_RED    = '#ff5050',
  ALARM_YELLOW = '#f0ad4e',
  ALARM_GREEN  = '#33cc00';

//########## Settings Inform Boxes ############

function HTMLcreate(htmlStr) {
  var frag = document.createDocumentFragment(),
    temp = document.createElement('div');
  temp.innerHTML = htmlStr;
  while (temp.firstChild) {
    frag.appendChild(temp.firstChild);
  }
  return frag;
}

// fade in animation
function fadeIn(el, display){
  el.style.opacity = 0;
  el.style.display = display || 'block';

  (function fade() {
    var val = parseFloat(el.style.opacity);
    if (((val += 0.05) > 1) !== true) {
      el.style.opacity = val;
      var request = window.requestFrame('request');
      request(fade);
    }
  })();
}

//########## Settings Form ############

function formValidation(){
  var read_community,write_community,managerIP,managerIP2,managerIP3,managerIP4,managerIP5,
    ipaddr, gw, mask,
    rs_server, rs_port, rs_key/*, ntpservip*/;

  read_community  = $('read_community'),
  write_community = $('write_community'),
  managerIP       = $('managerIP'),
  managerIP2      = $('managerIP2'),
  managerIP3      = $('managerIP3'),
  managerIP4      = $('managerIP4'),
  managerIP5      = $('managerIP5'),
  ipaddr          = $('ipaddr'),
  gw              = $('gw'),
  mask            = $('mask'),
  rs_server       = $('rs_server'),
  rs_port         = $('rs_port'),
  rs_key          = $('rs_key');
  // ntpservip          = $('ntpservip');

  var flag = true;
  if (!$('dhcp').checked) {
    if(!ValidateIPaddress(ipaddr, ' IP-адрес устройства')) flag = false;
    if(!ValidateIPaddress(gw,     ' IP-адрес шлюза')) flag = false;
    if(!ValidateIPaddress(mask,   'а Маска подсети')) flag = false;
  }
  if ($('rs_enabled').checked) {
    if(!ValidateIPaddress(rs_server, ' IP-адрес RADIUS сервера')) flag = false;
    if(!ValidateNumber(rs_port, ' Порт RADIUS сервера')) flag = false;
    if(!ValidateAlphanumeric(rs_key, ' Код атрибута access RADIUS сервера')) flag = false;
  }
  if(!ValidateIPaddress(managerIP, ' Сервер SNMP 1')) flag = false;
  if(!ValidateAlphanumeric(read_community, 'Read Community')) flag = false;
  if(!ValidateAlphanumeric(write_community, 'Write Community')) flag = false;
  if(!ValidateIPaddress(managerIP2, ' Сервер SNMP 2')) flag = false;
  if(!ValidateIPaddress(managerIP3, ' Сервер SNMP 3')) flag = false;
  if(!ValidateIPaddress(managerIP4, ' Сервер SNMP 4')) flag = false;
  if(!ValidateIPaddress(managerIP5, ' Сервер SNMP 5')) flag = false;

  return flag;
}

function ValidateIPaddress(ipaddress, z) {
  var warn = document.createElement('li');
  warn.innerHTML = 'Неправильно задан' + z + '!';
  if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress.value)) {
    return true;
  }
  $('validation-box').appendChild(warn);
  return false;
}

function ValidateNumber(n, z) {
  var warn = document.createElement('li');
  warn.innerHTML = 'Неправильно задан' + z + '!';
  if(/^-?[\d.]+(?:e-?\d+)?$/.test(n.value)) {
    return true;
  }
  $('validation-box').appendChild(warn);
  return false;
}

function ValidateAlphanumeric(uadd, z) {
  var warn = document.createElement('li');
  var letter = /^[0-9a-zA-Z]+$/;
  warn.innerHTML = 'Поле ' + z + ' может содержать только латинские буквы и цифры';
  if (letter.test(uadd.value)) {return true;}
  $('validation-box').appendChild(warn);
  return false;
}


function submitForms() {
  if (confirm('Вы уверены что хотите применить настройки?')) {
    if ($('ntp-inp')) {
      $('ntpservip').options[3].value = $('ntp-inp').value;
    }
    if (formValidation()) {
      $('form1').submit();
    }
    else{
      $('validation-box').style.display = 'block';
    }
  }
}

function checkPWD(){
  // $('checkUpdatePass').style.display = 'none';
  $('count-wrap').style.display = 'block';
  $('countdown').style.display = 'block';
  countdown();
}

function checkChangePWD(){
  var user = $('changePasswordUser').value;
  var oldpass = $('oldpwd').value;
  var newpass = $('newpwd').value;
  var newpassrepeat = $('newpwdrepeat').value;
  var letter = /^[0-9a-zA-Z]+$/;
  if (oldpass.length === 0 || newpass.length === 0 || newpassrepeat.length === 0){
    alert('Поля не заполнены!');
  } else if (newpass !== newpassrepeat){
    alert('Поля с новым паролем не совпадают!');
    $('oldpwd').value = '';
    $('newpwd').value = '';
    $('newpwdrepeat').value = '';
  } else if (user === ''){
    alert('Не выбран пользователь для которого необходимо сменить пароль!');
  } else {
    if (letter.test(oldpass) && letter.test(newpass) && letter.test(newpassrepeat)) {
      loadXMLDoc('changepwd.cgi?username=' + user + '&oldpass=' + oldpass + '&newpass=' + newpass, 'POST', function(){
        alert(this.responseText);
        window.location.reload();
      });
    } else {
      alert('Пароль задан неправильно');
      $('oldpwd').value = '';
      $('newpwd').value = '';
      $('newpwdrepeat').value = '';
    }
  }
}
function timesetType(el) {
  if (el.selectedIndex === 0) {
    $('ntpservip_l').className += ' hidden';
    $('ntpservip').className += ' hidden';
    $('ntpservip').setAttribute('disabled', 'disabled');
    if ($('ntp-inp')) {
      $('ntp-inp').className += ' hidden';
      $('ntp-inp').setAttribute('disabled', 'disabled');
    }
    $('lastsynctime_l').className += ' hidden';
    $('lastsynctime').className += ' hidden';
    // -----------------
    $('date_l').className = 'col span_1_of_2';
    $('date').className = 'form-control';
    $('time_l').className = 'col span_1_of_2';
    $('time').className = 'form-control';
    $('date').removeAttribute('disabled');
    $('time').removeAttribute('disabled');
  } else {
    $('ntpservip_l').className = 'col span_1_of_2';
    $('ntpservip').className = 'form-control';
    $('ntpservip').removeAttribute('disabled');
    if ($('ntp-inp')) {
      $('ntp-inp').className = 'form-control';
      $('ntp-inp').removeAttribute('disabled');
    }
    $('lastsynctime_l').className = 'col span_1_of_2';
    $('lastsynctime').className = 'form-control';
    // -------------
    $('date_l').className += ' hidden';
    $('date').className += ' hidden';
    $('time_l').className += ' hidden';
    $('time').className += ' hidden';
    $('date').setAttribute('disabled', 'disabled');
    $('time').setAttribute('disabled', 'disabled');
  }
}

function countdown(rel) {
  var countDown = 5;
  setInterval(function () {
    if (countDown == 1 && rel === true) {
      location.reload(true);
    }
    else if (countDown == 1 && rel !== true){
      window.location.href = '/';
    }
    if (countDown > 0){countDown--;}
    $('count-number').innerHTML = countDown;
    return countDown;
  }, 1000);
}

function dhcpState() {
  if ($('dhcp').checked) {
    $('ipaddr').setAttribute('disabled', 'disabled');
    $('gw').setAttribute('disabled', 'disabled');
    $('mask').setAttribute('disabled', 'disabled');
  } else {
    $('ipaddr').removeAttribute('disabled');
    $('gw').removeAttribute('disabled');
    $('mask').removeAttribute('disabled');
  }
}
function radiusState() {
  if (!$('rs_enabled').checked) {
    $('rs_server').setAttribute('disabled', 'disabled');
    $('rs_port').setAttribute('disabled', 'disabled');
    $('rs_pwd').setAttribute('disabled', 'disabled');
    $('rs_key').setAttribute('disabled', 'disabled');
  } else {
    $('rs_server').removeAttribute('disabled');
    $('rs_port').removeAttribute('disabled');
    $('rs_pwd').removeAttribute('disabled');
    $('rs_key').removeAttribute('disabled');
  }
}
function authState() {
  if (!$('auth').checked) {
    $('rs_enabled').setAttribute('disabled', 'disabled');
    $('rs_enabled').checked = false;
  } else {
    $('rs_enabled').removeAttribute('disabled');
    $('rs_enabled').checked = true;
  }
  radiusState();
}
//########## Info Form Validation ############

function infoValidation(){
  var owner, location,comment;
  owner    = $('owner').value,
  location = $('location').value,
  comment  = $('comment').value;

  var flag = true;
  if(!ValidateAlphanumeric2(owner, 'Владелец')){flag = false;}
  if(!ValidateAlphanumeric2(location, 'Местоположение')){flag = false;}
  if(!ValidateAlphanumeric2(comment, 'Комментарии')){flag = false;}

  return flag;
}

function ValidateAlphanumeric2(uadd, z) {
  var warn = document.createElement('li');
  // var letter = /^[0-9a-zA-Z]+[^\u0430-\u044f\u0410-\u042f\u0451\u0401\?]+$/m;
  var letter = /^[0-9a-zA-Z\ ]+$/m;
  warn.innerHTML = 'Поле ' + z + ' может содержать только латинские буквы и цифры';
  if (letter.test(uadd) || !uadd) {
    return true;
  }
  $('validation-box').appendChild(warn);
  return false;
}

function submitInfo() {
  if (confirm('Вы уверены что хотите применить изменения?')) {
    if (infoValidation()) {
      $('SNMPinfo').submit();
      // loadXMLDoc('info.cgi?owner='+ $('owner').value + '&sysLocation='+ $('location').value + '&comment='+ decodeURIComponent($('comment').value), 'GET', function(){
      //   console.log('Сохранено');
      // });
    }
    else {
      $('validation-box').style.display = 'block';
    }
  }
}

function getJSON(url, successHandler, errorHandler) {
  var xhr;
  xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');
  xhr.open('GET', url, true);
  xhr.onreadystatechange = function () {
    var status;
    var data;
    if (xhr.readyState == 4) {
      status = xhr.status;
      if (status == 200) {
        data = JSON.parse(xhr.responseText);
        successHandler(data);
      } else {
        errorHandler(status);
      }
    }
  };
  xhr.send();
}

function updatepage(){
  var loc = location.pathname.slice(1, -5);
  switch(loc){
  case 'settings':
    setTimeout(settingsGET, 1000);
    break;
  case 'history':
    getPage($('currentpage').value);
    break;
  }
}

function getCGI(url) {
  var xmlhttp;
  var q;
  if (url == 'reset.cgi') {
    q = confirm('Вы уверены что хотите сбросить на заводские настройки?');
  }
  if (url == 'reboot.cgi') {
    q = confirm('Вы уверены что хотите перезагрузить устройство?');
  }
  if (url == 'update.cgi') {
    q = confirm('Вы уверены что хотите обновить прошивку устройства?');
  }
  if (q) {
    if (window.XMLHttpRequest) {
      xmlhttp = new XMLHttpRequest();
    } else {
      xmlhttp = new window.ActiveXObject('Microsoft.XMLHTTP');
    }
    // xmlhttp.onreadystatechange = true;
    xmlhttp.open('GET', url, true);
    xmlhttp.send();
    return true;
  }
  // else {alert(a);}
}

function Alarm(bitmask, num) {
  // Bit mask format DEC <NUMBER>
  var answ = (bitmask & (1 << num)) >> num;
  return answ;
}

function setIcons(containerID, icnName) {
  $(containerID).innerHTML ='';

  var icons = typeof icnName === 'string' ? [icnName] : icnName;

  for (var i = 0; i < icons.length; i++) {
    var icnContainer = document.createElement('i');
    icnContainer.innerHTML = Icons[icons[i]]['icn'];
    icnContainer.style.paddingLeft = '10px';
    icnContainer.title = Icons[icons[i]]['title'];
    $(containerID).appendChild(icnContainer);
  }
}

function paramsRefresh() {
  getJSON('getJson.cgi'+'?'+Math.random(), function (data) {
    var alrm   = +data.u_alarm;
    var ma     = +data.m_alarm;
    var pstate = [];
    var bstate = [];
    var ups_bypass = Alarm(alrm, 5),
      ups_alarm    = Alarm(alrm, 4) || Alarm(alrm, 7),
      ups_standby  = Alarm(alrm, 3),
      ups_shutdown = Alarm(alrm, 1),
      bat_low      = Alarm(alrm, 6),
      bat_test     = Alarm(alrm, 2);
    // PPS
    $('AC').innerHTML         = parseFloat(data.AC) + ' В';
    $('AC').style.color       = Alarm(alrm, 7) ? ALARM_RED : ALARM_GREEN;

    $('DC').innerHTML         = parseFloat(data.DC) + ' В';
    $('DC').style.color       = Alarm(alrm, 7) ? ALARM_RED : ALARM_GREEN;

    $('in_freq').innerHTML    = parseFloat(data.in_freq) + ' Гц';
    $('in_freq').style.color  = Alarm(alrm, 7) ? ALARM_RED : ALARM_GREEN;

    $('out_freq').innerHTML   = parseFloat(data.out_freq) + ' Гц';
    $('out_freq').style.color = Alarm(alrm, 7) ? ALARM_RED : ALARM_GREEN;

    $('pwr').innerHTML        = parseFloat(data.pwr) + ' %';
    $('pwr').style.color      = Alarm(ma, 0) ? ALARM_RED : ALARM_GREEN;

    $('pmode').innerHTML      = ups_bypass ? 'Bypass' : 'Boost or Buck';

    // State
    ups_alarm ? pstate.push('exclamination') : pstate.push('normal');
    ups_standby ? pstate.push('clock') : null;
    ups_shutdown ? pstate.push('shutdown') : null;

    !Alarm(ma, 3) && !bat_low ? bstate.push('normal') : null;
    Alarm(ma, 3) ? bstate.push('exclamination') : null;
    bat_low ? bstate.push('batteryLow') : null;
    bat_test ? bstate.push('batTest') : null;

    setIcons('pstate_icons', pstate);
    setIcons('bstate_icons', bstate);

    // ACB
    $('bat_cap').innerHTML      = parseFloat(data.bat_cap) + ' %';
    $('bat_cap').style.color    = bat_low ? ALARM_RED : ALARM_GREEN;

    $('inner_temp').innerHTML   = parseFloat(data.inner_temp) + ' °C';
    $('inner_temp').style.color = Alarm(ma, 1) ? ALARM_RED : ALARM_GREEN;

    $('bat_time_left').innerHTML = parseFloat(data.bat_time_left) + ' мин';
    $('bat_time_left').style.color    = bat_low ? ALARM_RED : ALARM_GREEN;

    // Inputs
    $('di1').innerHTML   = +data.di1 ? 'Разомкнут' : 'Замкнут';
    $('di1').style.color = +data.di1 ? ALARM_GREEN : ALARM_RED;

    $('ro1').innerHTML   = +data.ro1 ? 'Замкнут' : 'Разомкнут';
    $('ro1').style.color = +data.ro1 ? ALARM_RED : ALARM_GREEN;

    $('ro2').innerHTML   = +data.ro2 ? 'Замкнут' : 'Разомкнут';
    $('ro2').style.color = +data.ro2 ? ALARM_RED : ALARM_GREEN;
    // checkState();
    window.setCookie('netsettings_changed', data.netsettings_changed);
    window.setCookie('device-error', Alarm(ma, 2));
    checkNotify();
    setTimeout(paramsRefresh, 1000);
  }, function (status) {
    if (status !== 0){
      alert('Не удалось получить данные.');
      setTimeout(paramsRefresh, 15000);
    }
  });
}
var mint;
//########## History ############
var H_PARAM    = 0,
  H_EVENT    = 1,
  H_DATETIME = 2;
function getPage(pn){
  getJSON('history.cgi?page=' + pn, function(data){
    $('history_data').textContent = '';
    var n = data.page;
    $('currentpage').value = pn;
    $('pagelimit').innerHTML = data.pages;
    for (var i in n){
      var tr = document.createElement('tr');
      var td = [
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td')
      ];
      td[0].innerHTML = n[i].split(';')[H_PARAM];
      td[0].id = 'h_param_'+ i;
      tr.appendChild(td[0]);
      td[1].id = 'h_event_'+ i;
      td[1].innerHTML = n[i].split(';')[H_EVENT];
      tr.appendChild(td[1]);
      td[2].id = 'h_datetime_'+ i;
      td[2].innerHTML = n[i].split(';')[H_DATETIME];
      tr.appendChild(td[2]);
      $('history_data').appendChild(tr);
    }
    // utcParam = data.utc;
    window.setCookie('netsettings_changed', data.netsettings_changed);
    checkNotify();
    clearTimeout(mint);
    mint = setTimeout(history_dataref, 5000);
  }, function(){
    $('table').display = 'none';
    $('content').innerHTML =
      '<h1>Журнал событий</h1>'+
      '<div class="panel panel-default">'+
        '<div class="panel-heading">Ошибка</div>'+
        '<p style="text-align: center;">Данные отсутствуют.</p>'+
      '</div>';
  });
}
function history_dataref() {
  var pn = parseInt($('currentpage').value);
  getJSON('history.cgi?page=' + pn, function(data) {
    var p = data.page;
    for (var j in p) {
      var param_col = $('h_param_'+ j);
      var event_col = $('h_event_'+ j);
      var datetime_col = $('h_datetime_'+ j);
      param_col.innerHTML = p[j].split(';')[H_PARAM];
      event_col.innerHTML = p[j].split(';')[H_EVENT];
      datetime_col.innerHTML = p[j].split(';')[H_DATETIME];
      $('pagelimit').innerHTML = data.pages;
    }
    clearTimeout(mint);
    mint = setTimeout(history_dataref, 5000);
  });
}
function nextPage(){
  var next = parseInt($('currentpage').value);
  if (next < parseInt($('pagelimit').textContent)) {
    next = next + 1;
    getPage(next);
  }
}
function prevPage(){
  var prev = parseInt($('currentpage').value);
  if (prev != 1) {
    prev = prev - 1;
    getPage(prev);
  }
}
//########## UPS History ############
var INPUT_V  = 0,
  INPUT_FV   = 1,
  OUTPUT_V   = 2,
  OUTPUT_C   = 3,
  INPUT_F    = 4,
  BAT_V      = 5,
  TEMP       = 6,
  STATUS     = 7,
  TIME       = 8;
function getUPSPage(pn){
  getJSON('ups_history.cgi?page=' + pn, function(data){
    $('history_data').textContent = '';
    var n = data.page;
    $('currentpage').value = pn;
    $('pagelimit').innerHTML = data.pages;
    // var inputs = [
    //   {id: 'h_inputv_', val: INPUT_V}
    // ];
    for (var i in n){
      var tr = document.createElement('tr');
      var td = [
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td'),
        document.createElement('td')
      ];
      td[0].innerHTML = parseFloat(n[i].split(';')[INPUT_V]) + ' В';
      td[0].id = 'h_inputv_'+ i;
      tr.appendChild(td[0]);
      td[1].id = 'h_inputfv_'+ i;
      td[1].innerHTML = parseFloat(n[i].split(';')[INPUT_FV]) + ' В';
      tr.appendChild(td[1]);
      td[2].id = 'h_outputv_'+ i;
      td[2].innerHTML = parseFloat(n[i].split(';')[OUTPUT_V]) + ' В';
      tr.appendChild(td[2]);
      td[3].id = 'h_outputc_'+ i;
      td[3].innerHTML = parseFloat(n[i].split(';')[OUTPUT_C]) + '%';
      tr.appendChild(td[3]);
      td[4].id = 'h_inputf_'+ i;
      td[4].innerHTML = parseFloat(n[i].split(';')[INPUT_F]) + ' Гц';
      tr.appendChild(td[4]);
      td[5].id = 'h_batv_'+ i;
      td[5].innerHTML = parseFloat(n[i].split(';')[BAT_V]) + ' В';
      tr.appendChild(td[5]);
      td[6].id = 'h_temp_'+ i;
      td[6].innerHTML = parseFloat(n[i].split(';')[TEMP]) + ' °C';
      tr.appendChild(td[6]);
      td[7].id = 'h_status_'+ i;
      td[7].innerHTML = n[i].split(';')[STATUS];
      tr.appendChild(td[7]);
      td[8].id = 'h_time_'+ i;
      td[8].innerHTML = n[i].split(';')[TIME];
      tr.appendChild(td[8]);
      $('history_data').appendChild(tr);
    }
    // utcParam = data.utc;
    window.setCookie('netsettings_changed', data.netsettings_changed);
    checkNotify();
    clearTimeout(mint);
    mint = setTimeout(ups_history_dataref, 5000);
  }, function(){
    $('table').display = 'none';
    $('content').innerHTML =
      '<h1>Журнал событий</h1>'+
      '<div class="panel panel-default">'+
        '<div class="panel-heading">Ошибка</div>'+
        '<p style="text-align: center;">Данные отсутствуют.</p>'+
      '</div>';
  });
}
function ups_history_dataref() {
  var pn = parseInt($('currentpage').value);
  getJSON('ups_history.cgi?page=' + pn, function(data) {
    var p = data.page;
    for (var j in p) {
      var inputv_col  = $('h_inputv_' + j);
      var inputfv_col = $('h_inputfv_' + j);
      var outputv_col = $('h_outputv_' + j);
      var outputc_col = $('h_outputc_' + j);
      var inputf_col  = $('h_inputf_' + j);
      var batv_col    = $('h_batv_' + j);
      var trmp_col    = $('h_temp_' + j);
      var status_col  = $('h_status_' + j);
      var time_col    = $('h_time_' + j);

      inputv_col.innerHTML  =  parseFloat(p[j].split(';')[INPUT_V]) + ' В';
      inputfv_col.innerHTML =  parseFloat(p[j].split(';')[INPUT_FV]) + ' В';
      outputv_col.innerHTML =  parseFloat(p[j].split(';')[OUTPUT_V]) + ' В';
      outputc_col.innerHTML =  parseFloat(p[j].split(';')[OUTPUT_C]) + '%';
      inputf_col.innerHTML  =  parseFloat(p[j].split(';')[INPUT_F]) + ' Гц';
      batv_col.innerHTML    =  parseFloat(p[j].split(';')[BAT_V]) + ' В';
      trmp_col.innerHTML    =  parseFloat(p[j].split(';')[TEMP]) + ' °C';
      status_col.innerHTML  =  p[j].split(';')[STATUS];
      time_col.innerHTML    =  p[j].split(';')[TIME];

      $('pagelimit').innerHTML = data.pages;
    }
    clearTimeout(mint);
    mint = setTimeout(ups_history_dataref, 5000);
  });
}
function nextUPSPage(){
  var next = parseInt($('currentpage').value);
  if (next < parseInt($('pagelimit').textContent)) {
    next = next + 1;
    getUPSPage(next);
  }
}
function prevUPSPage(){
  var prev = parseInt($('currentpage').value);
  if (prev != 1) {
    prev = prev - 1;
    getUPSPage(prev);
  }
}

function utf8_decode (s) {
  var bb = '', c = 0;
  for (var i = 0; i < s.length; i++) {
    c = s.charCodeAt(i);
    if (c > 127) {
      if (c > 1024) {
        if (c == 1025) {
          c = 1016;
        } else if (c == 1105) {
          c = 1032;
        }
        bb += String.fromCharCode(c - 848);
      }
    } else {
      bb += s.charAt(i);
    }
  }
  return bb;
}

function msieversion() {
  var ua = window.navigator.userAgent;
  var msie = ua.indexOf('MSIE ');
  if (msie != -1 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) /*If IE, return version number*/ return true;

  return false;
}

function blobLoad(requestUrl, fileName, buttonID){
  if(isMobile.iOS()){
    alert('На данном устройстве сохранение не доступно.');
  }

  var old = $(buttonID).children[0].textContent;

  var pgFlag = 'Обработка';
  var pgFlagLen = pgFlag.length;
  var d = new Date();
  var fName;
  if (fileName === 'settings.dat') {
    fName = fileName;
  } else {
    fName = d.getDate()+'_'+d.getMonth()+'_'+d.getHours()+d.getMinutes() + '_' + fileName;
  }
  var xhr = new XMLHttpRequest();
  var fURL = requestUrl.split('.').pop() == 'cgi' ? requestUrl+'?' : requestUrl+'&';
  xhr.open('GET', fURL+'_='+ new Date().getTime());
  xhr.responseType = 'blob';
  $(buttonID).setAttribute('disabled', 'disabled');
  xhr.addEventListener('load', function(){
    $(buttonID).children[1].style.width = 0;
    $(buttonID).children[0].textContent = old;
    $(buttonID).removeAttribute('disabled');
  });
  xhr.onload = function(){
    if (this.status === 200) {
      var blob = this.response;
      if(msieversion()){
        if (window.navigator.msSaveOrOpenBlob) {
          window.navigator.msSaveOrOpenBlob(blob, fName);
        } else {
          var IEwindow = window.open(requestUrl);
        }
      } else {
        var objectUrl = URL.createObjectURL(blob);
        var uri = objectUrl;
        var link = document.createElement('a');
        link.href = uri;
        link.style = 'visibility:hidden';
        link.download = fName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    }
  };
  xhr.onprogress = function(event) {
    $(buttonID).children[0].textContent = parseInt((event.loaded / event.total) * 100) + '%';
    $(buttonID).children[1].style.width = parseInt((event.loaded / event.total) * 100) + '%';
  };
  xhr.send();
}

var isMobile = {
  Android: function() {
    return navigator.userAgent.match(/Android/i);
  },
  BlackBerry: function() {
    return navigator.userAgent.match(/BlackBerry/i);
  },
  iOS: function() {
    return navigator.userAgent.match(/iPhone|iPad|iPod/i);
  },
  Opera: function() {
    return navigator.userAgent.match(/Opera Mini/i);
  },
  Windows: function() {
    return navigator.userAgent.match(/IEMobile/i);
  },
  any: function() {
    return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
  }
};

function checkOther(ele) {
  if (ele.selectedIndex == 3) {
    var newInput = document.createElement('input');
    newInput.type = 'text';
    newInput.className = 'form-control';
    newInput.id = 'ntp-inp';
    newInput.value = ntpservipValue;
    newInput.style.marginTop = '10px';
    ele.parentNode.insertBefore(newInput, ele.nextSibling);
  }
  else if ($('ntp-inp')) {
    var d = $('ntp-inp');
    ele.parentNode.removeChild(d);
  }
}

// ################################################################################

function settingsGET(){
  getJSON('settings.cgi', function(data) {
    //SNMP params
    $('managerIP').value = data.managerIP;
    $('read_community').value = data.read_community;
    $('write_community').value = data.write_community;
    $('managerIP2').value = data.managerIP2;
    $('managerIP3').value = data.managerIP3;
    $('managerIP4').value = data.managerIP4;
    $('managerIP5').value = data.managerIP5;
    $('di1').value = +data.di1;
    $('ro1').value = +data.ro1;
    $('ro2').value = +data.ro2;
    // Network params
    $('ipaddr').value   = data.ipaddr;
    $('gw').value       = data.gw;
    $('mask').value     = data.mask;
    $('dhcp').checked   = data.dhcp;
    // RADIUS params
    $('rs_server').value    = data.rs_server;
    $('rs_port').value      = data.rs_port;
    $('rs_pwd').value       = data.rs_pwd;
    $('rs_key').value       = data.rs_key;
    $('rs_enabled').checked = data.rs_enabled;
    $('auth').checked       = data.auth;
    // DateTime
    if (data.ntpservip != $('ntpservip').options[0].value &&
        data.ntpservip != $('ntpservip').options[1].value &&
        data.ntpservip != $('ntpservip').options[2].value )
    {
      var newInput                       = document.createElement('input');
      newInput.type                      = 'text';
      newInput.className                 = 'form-control';
      newInput.id                        = 'ntp-inp';
      newInput.style.marginTop           = '10px';
      $('ntpservip').options[3].selected = 'selected';
      $('ntpservip').options[3].value    = data.ntpservip;
      $('ntpservip').parentNode.insertBefore(newInput, $('ntpservip').nextSibling);

      window.ntpservipValue        = data.ntpservip;
      newInput.value        = window.ntpservipValue;
    } else {
      window.ntpservipValue        = data.ntpservip;
      $('ntpservip').value  = window.ntpservipValue;
    }
    $('utc').value          = data.utc;
    $('date').value         = data.date;
    $('time').value         = data.time;
    $('lastsynctime').value = data.lastsynctime;
    $('ntp').value          = data.ntp;
    dhcpState();
    radiusState();
    authState();
    timesetType($('ntp'));

    window.setCookie('netsettings_changed', data.netsettings_changed);
    checkNotify();
  }, function() {
    alert('Не удалось получить данные.');
  });
}

function batTest(options) {
  this.options = (options ? options : {});
  if (this.options.time) {
    if (typeof this.options.time !== 'number' && this.options.time > 99) {
      return alert('Ошибка заданного времени');
    }
  }
  var url = 'bat_test.cgi';
  loadXMLDoc(url, 'POST', function(){
    this.responseText ? alert(this.responseText) : null;
  }, JSON.stringify(options));
}
function UPSPowerOff(options) {
  this.options = (options ? options : {});
  if (typeof this.options.after !== 'number' && this.options.after > 9999) {
    return alert('Ошибка заданного времени включения');
  }
  if (typeof this.options.to !== 'number' && this.options.to > 9999) {
    return alert('Ошибка заданного времени выключения');
  }
  var url = 'ups_power.cgi';
  loadXMLDoc(url, 'POST', function(){
    this.responseText ? alert(this.responseText) : null;
  }, JSON.stringify(options));
}

var apply_settings = new NotificationBox('apply-settings',
  {
    'message': 'Внимание, для применения сетевых настроек необходимо их подтвердить. Иначе они будут сброшены в течении 10 минут.',
    'bgcolor':'#ffcc00',
    'textcolor': '#333',
    'url': 'confirm.cgi',
    'show': window.getCookie('role') < 2
  });
var device_error = new NotificationBox('device-error',
  {
    'message': 'Внимание, связь с UPS не установлена!',
    'bgcolor':'#ec0035',
    'textcolor': '#fff'
  });

// ################################################################################

function infoGet() {
  getJSON('info.cgi', function(data) {
    // Cotroller Info
    $('uptime').innerHTML    = data.uptime;
    $('model').innerHTML     = data.model;
    $('prodate').innerHTML   = data.prodate;
    $('fwversion').innerHTML = data.fwversion;
    $('macaddr').innerHTML   = data.macaddr;
    $('serno').innerHTML     = data.serno;
    $('owner').value         = data.owner;
    $('location').value      = data.sysLocation;
    $('comment').value       = data.comment;
    $('ups_fwversion').innerHTML       = data.ups_fwversion;
    $('ups_model').innerHTML       = data.ups_model;
    // utcParam                 = data.utc;
    window.setCookie('netsettings_changed', data.netsettings_changed);
    checkNotify();
  }, function() {
    alert('Не удалось получить данные.');
  });
}

// ################################################################################


/*
  This code is from Dynamic Web Coding at dyn-web.com
  Copyright 2009-12 by Sharon Paine
  See Terms of Use at www.dyn-web.com/business/terms.php
  regarding conditions under which you may use this code.
  This notice must be retained in the code as is!
*/

// DYN_WEB is namespace used for code from dyn-web.com
// replacing previous use of dw_ prefix for object names
var DYN_WEB = DYN_WEB || {};

DYN_WEB.Event = {
  add: document.addEventListener ? function (obj, etype, fp, cap) {
    cap = cap || false;
    obj.addEventListener(etype, fp, cap);
  } : function (obj, etype, fp) {
    obj.attachEvent('on' + etype, fp);
  },
  remove: document.removeEventListener ? function (obj, etype, fp, cap) {
    cap = cap || false;
    obj.removeEventListener(etype, fp, cap);
  } : function (obj, etype, fp) {
    obj.detachEvent('on' + etype, fp);
  },
  DOMit: function (e) {
    e = e ? e : window.event;
    if (!e.target) e.target = e.srcElement;
    if (!e.preventDefault) e.preventDefault = function () {
      e.returnValue = false;
      return false;
    };
    if (!e.stopPropagation) e.stopPropagation = function () {
      e.cancelBubble = true;
    };
    return e;
  },
  getTarget: function (e) {
    e = dw_Event.DOMit(e);
    var tgt = e.target;
    if (tgt.nodeType != 1) tgt = tgt.parentNode;
    return tgt;
  }
};

DYN_WEB.Cookie = {
  set: function (name, value, days, path, domain, secure) {
    var date, expires;
    if (typeof days == 'number') {
      date = new Date();
      date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
      expires = date.toGMTString();
    }
    document.cookie = name + '=' + encodeURIComponent(value) + (
      (expires) ? '; expires=' + expires : ''
      ) + (
      (path) ? '; path=' + path : ''
      ) + (
      (domain) ? '; domain=' + domain : ''
      ) + (
      (secure) ? '; secure' : '');
  },
  get: function (name) {
    var c, cookies = document.cookie.split(/;\s/g);
    for (var i = 0; cookies[i]; i++) {
      c = cookies[i];
      if (c.indexOf(name + '=') === 0) {
        return decodeURIComponent(c.slice(name.length + 1, c.length));
      }
    }
    return null;
  },
  del: function (name, path, domain) {
    if (dw_Cookie.get(name)) {
      document.cookie = name + '=' + (
        (path) ? '; path=' + path : ''
        ) + (
        (domain) ? '; domain=' + domain : ''
        ) + '; expires=Thu, 01-Jan-70 00:00:01 GMT';
    }
  }
};

if (!DYN_WEB.Util) {
  DYN_WEB.Util = {
    // add props of Obj2 to Obj1
    augment: function (Obj1, Obj2) {
      var prop;
      for (prop in Obj2) {
        if (Obj2.hasOwnProperty(prop) && !Obj1[prop]) {
          Obj1[prop] = Obj2[prop];
        }
      }
    },
    $: function (id) {
      return document.getElementById(id);
    }
  };
}

DYN_WEB.Tabs = (function () {

  // obj holds props: id, useCookies, etc.
  function Constr(obj) {
    this.useCookies = obj.useCookies;
    this.before_hide = obj.before_hide || function () {};
    this.on_activate = obj.on_activate || function () {};
    this.on_init = obj.on_init || function () {};
    Constr.col[obj.id] = this;
    Constr.init(obj.id);
  }

  Constr.col = {};

  Constr.prototype = {
    current: null // id of currently active pane
  };

  return Constr;
})();

(function () {
  var Ut = DYN_WEB.Util,
    Ev = DYN_WEB.Event,
    Cookie = DYN_WEB.Cookie,
    Tabs = DYN_WEB.Tabs;

  Ut.augment(Tabs, {
    // static props/methods for DYN_WEB.Tabs
    setup: function () {
      var obj, settings = [];
      if (Tabs.hasBrowserSupport()) {
        for (var i = 0; obj = arguments[i]; i++) {
          if (obj.css) {
            Ut.writeStyleSheet(obj.css);
          }
          settings[i] = obj; // save to pass to constructor onload
        }
        Ev.add(window, 'load', function () {
          for (var i = 0; settings[i]; i++) {
            new Tabs(settings[i]);
          }
        });
      }
    },
    hasBrowserSupport: function () {
      if (document.getElementById && document.getElementsByTagName && typeof decodeURI !== 'undefined' && (document.addEventListener || document.attachEvent)) {
        return true;
      }
      return false;
    },

    init: function (tabsetId) {
      var _this = Tabs.col[tabsetId],
        links = Tabs.getTabs(tabsetId),
        // code uses hash in tab links but tabs can also link to other pages
        // so compare current location to link's href
        loc = Ut.getURLtoHash(location),
        lnk, pg, paneId, pane, sel, dflt, cur, c, q, hash;

      q = Ut.getValueFromQueryString(tabsetId);
      if (_this.useCookies) {
        c = Tabs.checkCookie(tabsetId);
      }
      // tab in query string or cookie?
      sel = q ? q : c ? c : null;

      // add ids and event handlers to links ...
      for (var i = 0; lnk = links[i]; i++) {
        paneId = '', pane = ''; // reset
        pg = Ut.getURLtoHash(lnk);
        hash = Ut.getHash(lnk);
        if (lnk.hash && (loc == pg)) { // has hash and points to current page
          paneId = hash;
          lnk.id = tabsetId + '__' + paneId; // double underscore between
        }
        // if tab associated with tabpane, set up onclick fn
        if (paneId) {
          try {
            pane = Ut.$(paneId);
          } catch (err) { // showClicked fn throws
          }

          // first tab/pane is default
          if (!dflt) {
            dflt = paneId;
          }

          // if set active in markup, hold as current
          if (pane && Ut.hasClass(lnk, 'activeTab') && Ut.hasClass(pane, 'activePane')) {
            _this.current = cur = paneId;
          }

          // to pass paneId, tabsetId to showClicked...
          Ev.add(lnk, 'click', function (paneId, tabsetId) {
            return function (e) {
              Tabs.showClicked(e, paneId, tabsetId);
            };
          }(paneId, tabsetId));
        }
      }

      // check if tab and pane for sel
      if (sel && (lnk = Ut.$(tabsetId + '__' + sel)) && (pane = Ut.$(sel))) {
        if (cur && cur !== sel) {
          Tabs.hideCurrent(tabsetId, cur);
        }
        Ut.addClass(lnk, 'activeTab');
        Ut.addClass(pane, 'activePane');
        _this.current = sel;
      } else if (!cur && dflt) {
        Ut.addClass(Ut.$(tabsetId + '__' + dflt), 'activeTab');
        Ut.addClass(Ut.$(dflt), 'activePane');
        _this.current = dflt;
      }
      _this.on_init();
    },

    getTabs: function (id) {
      var set = Ut.$(id),
        list, links;
      if (!set) {
        throw new Error('No element matching tabset id found.');
        return [];
      }
      list = Ut.getElementsByClassName('tabnavs', 'ul', set);
      if (list.length === 0) {
        throw new Error('No tabnavs were found in the tabset.');
        return [];
      }
      links = list[0].getElementsByTagName('a');
      return links;
    },

    showClicked: function (e, paneId, tabsetId) {
      var tabId = tabsetId + '__' + paneId;
      var _this = Tabs.col[tabsetId];
      _this.before_hide(tabId, paneId, tabsetId);
      Tabs.hideCurrent(tabsetId, _this.current);
      Ut.addClass(Ut.$(tabId), 'activeTab');

      try {
        Ut.addClass(Ut.$(paneId), 'activePane');
      } catch (err) {
        throw new Error('showClicked can\'t find pane associated with tab. Check tab hash and pane id.');
        return false;
      }

      _this.current = paneId;
      if (_this.useCookies) {
        Tabs.setCookie(tabsetId, paneId);
      }

      _this.on_activate(tabId, paneId, tabsetId);
      if (e) {
        Ev.DOMit(e);
        e.preventDefault();
      }
      return false;
    },

    hideCurrent: function (tabsetId, cur) {
      var tab = Ut.$(tabsetId + '__' + cur),
        pane = Ut.$(cur);
      Ut.removeClass(tab, 'activeTab');
      Ut.removeClass(pane, 'activePane');
    },

    checkCookie: function (tabsetId) {
      var c, cookies, tab_cookies = Cookie.get('dw_Tabs');
      if (tab_cookies) {
        cookies = tab_cookies.split(',');
        for (var i = 0; cookies[i]; i++) {
          c = cookies[i];
          if (c.indexOf(tabsetId + ':') === 0) {
            return decodeURI(c.slice(tabsetId.length + 1, c.length));
          }
        }
      }
      return null;
    },

    setCookie: function (tabsetId, paneId) {
      // format for cookies (multiple tabsets supported): dw_Tabs=tabsetId:paneId,tabsetId:paneId;
      var new_tab_cookies = '',
        cookies,
        tab_cookies = Cookie.get('dw_Tabs');
      if (tab_cookies) {
        cookies = tab_cookies.split(',');
        for (var i = 0; cookies[i]; i++) {
          if (cookies[i].indexOf(tabsetId + ':') === 0) {
            cookies[i] = tabsetId + ':' + paneId;
            new_tab_cookies = cookies.join(',');
            break;
          }
        }
        if (!new_tab_cookies) { // if no match for this tabsetId
          new_tab_cookies = tab_cookies + ',' + tabsetId + ':' + paneId;
        }
      } else { // no dw_Tabs set yet
        new_tab_cookies = tabsetId + ':' + paneId;
      }
      Cookie.set('dw_Tabs', new_tab_cookies, null, '/');
    }

  });
})();


// util

(function () {
  var Ut = DYN_WEB.Util;
  // add methods to DYN_WEB.Util
  Ut.augment(Ut, {
    trim: function (str) {
      if (String.prototype.trim) {
        return str.trim(); // ECMAScript 5
      } else {
        var re = /^\s+|\s+$/g;
        return str.replace(re, '');
      }
    },

    normalizeString: function (str) {
      var re = /\s\s+/g;
      return Ut.trim(str).replace(re, ' ');
    },

    hasClass: function (el, cl) {
      var re = new RegExp('\\b' + cl + '\\b', 'i');
      if (re.test(el.className)) {
        return true;
      }
      return false;
    },

    addClass: function (el, cl) {
      if (!Ut.hasClass(el, cl)) {
        el.className = Ut.trim(el.className + ' ' + cl);
      }
    },

    removeClass: function (el, cl) {
      el.className = Ut.normalizeString(el.className.replace(cl, ' '));
    },

    getElementsByClassName: function (sClass, sTag, oCont) {
      oCont = oCont ? oCont : document;
      if (oCont.getElementsByClassName) {
        return oCont.getElementsByClassName(sClass); // html5
      } else {
        sTag = sTag || '*';
        var result = [],
          re = new RegExp('\\b' + sClass + '\\b', 'i'),
          list = oCont.getElementsByTagName(sTag);
        for (var i = 0; list[i]; i++) {
          if (re.test(list[i].className)) result.push(list[i]);
        }
        return result;
      }
    },

    // obj: link or window.location
    getValueFromQueryString: function (name, obj) {
      obj = obj ? obj : window.location;
      var pairs, set;
      if (obj.search && obj.search.indexOf(name != -1)) {
        pairs = obj.search.slice(1).split('&'); // name/value pairs
        for (var i = 0; pairs[i]; i++) {
          set = pairs[i].split('='); // Check each pair for match on name
          if (set[0] == name && set[1]) {
            return set[1];
          }
        }
      }
      return '';
    },

    getURLtoHash: function (obj) {
      obj = obj ? obj : window.location;
      var href = obj.href,
        pt = href.indexOf('#'),
        url = (pt != -1) ? href.slice(0, pt) : href; // remove hash from href
      return url;
    },

    getHash: function (obj) {
      obj = obj ? obj : window.location;
      var hash = '';
      if (obj.hash) { // some browsers say true if just #, some '' (ff)
        hash = obj.hash.slice(1);
      }
      return hash;
    },

    // Alternate functions are available that use DOM methods instead of document.write
    writeStyleSheet: function (file, bScreen) {
      var screen = (bScreen !== false) ? '" media="screen" />\n' : '"/>\n';
      document.write('\n<link rel="stylesheet" href="' + file + screen);
    },

    // used to set min-height (as on dyn-web home page)
    writeStyleRule: function (rule, bScreen) {
      var screen = (bScreen !== false) ? ' media="screen">' : '>';
      document.write('\n<style type="text/css"' + screen + rule + '</style>');
    }
  });
})();


(function (window) {

/**
 * @param  {String} type - request | cancel | native.
 * @return {Function} Timing function.
 */
  function requestFrame(type) {
    // The only vendor prefixes required.
    var vendors = ['moz', 'webkit'],

      // Disassembled timing function abbreviations.
      aF = 'AnimationFrame',
      rqAF = 'Request' + aF,

      // Final assigned functions.
      assignedRequestAnimationFrame,
      assignedCancelAnimationFrame,

      // Initial time of the timing lapse.
      previousTime = 0,

      mozRAF = window.mozRequestAnimationFrame,
      mozCAF = window.mozCancelAnimationFrame,

      // Checks for firefox 4 - 10 function pair mismatch.
      hasMozMismatch = mozRAF && !mozCAF,

      func;

    // Date.now polyfill, mainly for legacy IE versions.
    if (!Date.now) {
      Date.now = function() {
        return new Date().getTime();
      };
    }

  /**
   * hasIOS6RequestAnimationFrameBug.
   * @See {@Link https://gist.github.com/julienetie/86ac394ec41f1271ff0a}
   * - for Commentary.
   * @Copyright 2015 - Julien Etienne.
   * @License: MIT.
   */
    function hasIOS6RequestAnimationFrameBug() {
      var webkitRAF = window.webkitRequestAnimationFrame,
        rAF = window.requestAnimationFrame,

        // CSS/ Device with max for iOS6 Devices.
        hasMobileDeviceWidth = screen.width <= 768 ? true : false,

        // Only supports webkit prefixed requestAnimtionFrane.
        requiresWebkitprefix = !(webkitRAF && rAF),

        // iOS6 webkit browsers don't support performance now.
        hasNoNavigationTiming = window.performance ? false : true,

        iOS6Notice = 'setTimeout is being used as a substitiue for' +
        'requestAnimationFrame due to a bug within iOS 6 builds',

        hasIOS6Bug = requiresWebkitprefix && hasMobileDeviceWidth &&
        hasNoNavigationTiming;

      function bugCheckresults(timingFnA, timingFnB, notice) {
        if (timingFnA || timingFnB) {
          console.warn(notice);
          return true;
        } else {
          return false;
        }
      }

      function displayResults() {
        if (hasIOS6Bug) {
          return bugCheckresults(webkitRAF, rAF, iOS6Notice);
        } else {
          return false;
        }
      }

      return displayResults();
    }

    /**
     * Native clearTimeout function.
     * @return {Function}
     */
    function clearTimeoutWithId(id) {
      clearTimeout(id);
    }

    /**
     * Based on a polyfill by Erik, introduced by Paul Irish &
     * further improved by Darius Bacon.
     * @see  {@link http://www.paulirish.com/2011/
     * requestanimationframe-for-smart-animating}
     * @see  {@link https://github.com/darius/requestAnimationFrame/blob/
     * master/requestAnimationFrame.js}
     * @callback {Number} Timestamp.
     * @return {Function} setTimeout Function.
     */
    function setTimeoutWithTimestamp(callback) {
      var immediateTime = Date.now(),
        lapsedTime = Math.max(previousTime + 16, immediateTime);
      return setTimeout(function() {
        callback(previousTime = lapsedTime);
      },
          lapsedTime - immediateTime);
    }

      /**
       * Queries the native function, prefixed function
       * or use the setTimeoutWithTimestamp function.
       * @return {Function}
       */
    function queryRequestAnimationFrame() {
      if (Array.prototype.filter) {
        assignedRequestAnimationFrame = window['request' + aF] ||
          window[vendors.filter(function(vendor) {
            if (window[vendor + rqAF] !== undefined)
              return vendor;
          }) + rqAF] || setTimeoutWithTimestamp;
      } else {
        return setTimeoutWithTimestamp;
      }
      if (!hasIOS6RequestAnimationFrameBug()) {
        return assignedRequestAnimationFrame;
      } else {
        return setTimeoutWithTimestamp;
      }
    }

    /**
     * Queries the native function, prefixed function
     * or use the clearTimeoutWithId function.
     * @return {Function}
     */
    function queryCancelAnimationFrame() {
      var cancellationNames = [];
      if (Array.prototype.map) {
        vendors.map(function(vendor) {
          return ['Cancel', 'CancelRequest'].map(
            function(cancellationNamePrefix) {
              cancellationNames.push(vendor +
                  cancellationNamePrefix + aF);
            });
        });
      } else {
        return clearTimeoutWithId;
      }

      /**
       * Checks for the prefixed cancelAnimationFrame implementation.
       * @param  {Array} prefixedNames - An array of the prefixed names.
       * @param  {Number} i - Iteration start point.
       * @return {Function} prefixed cancelAnimationFrame function.
       */
      function prefixedCancelAnimationFrame(prefixedNames, i) {
        var cancellationFunction;
        for (; i < prefixedNames.length; i++) {
          if (window[prefixedNames[i]]) {
            cancellationFunction = window[prefixedNames[i]];
            break;
          }
        }
        return cancellationFunction;
      }

      // Use truthly function
      assignedCancelAnimationFrame = window['cancel' + aF] ||
          prefixedCancelAnimationFrame(cancellationNames, 0) ||
          clearTimeoutWithId;

      // Check for iOS 6 bug
      if (!hasIOS6RequestAnimationFrameBug()) {
        return assignedCancelAnimationFrame;
      } else {
        return clearTimeoutWithId;
      }
    }

    function getRequestFn() {
      if (hasMozMismatch) {
        return setTimeoutWithTimestamp;
      } else {
        return queryRequestAnimationFrame();
      }
    }

    function getCancelFn() {
      return queryCancelAnimationFrame();
    }

    function setNativeFn() {
      if (hasMozMismatch) {
        window.requestAnimationFrame = setTimeoutWithTimestamp;
        window.cancelAnimationFrame = clearTimeoutWithId;
      } else {
        window.requestAnimationFrame = queryRequestAnimationFrame();
        window.cancelAnimationFrame = queryCancelAnimationFrame();
      }
    }

      /**
       * The type value "request" singles out firefox 4 - 10 and
       * assigns the setTimeout function if plausible.
       */

    switch (type) {
    case 'request':
    case '':
      func = getRequestFn();
      break;

    case 'cancel':
      func = getCancelFn();
      break;

    case 'native':
      setNativeFn();
      break;
    default:
      throw new Error('RequestFrame parameter is not a type.');
    }
    return func;
  }
  // Default to window as global
  if (typeof window === 'object') {
    window.requestFrame = requestFrame;
  }
  /* global-define */

}((typeof window === 'undefined' ? {} : window)));


// Icons

var Icons = {
  clock: {
    icn: '<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z" fill="'+ ALARM_YELLOW +'"/></svg>',
    title: 'Режим ожидания'
  },
  exclamination: {
    icn: '<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1088 1248v224q0 26-19 45t-45 19h-256q-26 0-45-19t-19-45v-224q0-26 19-45t45-19h256q26 0 45 19t19 45zm30-1056l-28 768q-1 26-20.5 45t-45.5 19h-256q-26 0-45.5-19t-20.5-45l-28-768q-1-26 17.5-45t44.5-19h320q26 0 44.5 19t17.5 45z" fill="'+ ALARM_RED +'"/></svg>',
    title: 'Авария'
  },
  normal: {
    icn: '<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1299 813l-422 422q-19 19-45 19t-45-19l-294-294q-19-19-19-45t19-45l102-102q19-19 45-19t45 19l147 147 275-275q19-19 45-19t45 19l102 102q19 19 19 45t-19 45zm141 83q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z" fill="'+ ALARM_GREEN +'"/></svg>',
    title: 'Норма'
  },
  shutdown: {
    icn: '<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1664 896q0 156-61 298t-164 245-245 164-298 61-298-61-245-164-164-245-61-298q0-182 80.5-343t226.5-270q43-32 95.5-25t83.5 50q32 42 24.5 94.5t-49.5 84.5q-98 74-151.5 181t-53.5 228q0 104 40.5 198.5t109.5 163.5 163.5 109.5 198.5 40.5 198.5-40.5 163.5-109.5 109.5-163.5 40.5-198.5q0-121-53.5-228t-151.5-181q-42-32-49.5-84.5t24.5-94.5q31-43 84-50t95 25q146 109 226.5 270t80.5 343zm-640-768v640q0 52-38 90t-90 38-90-38-38-90v-640q0-52 38-90t90-38 90 38 38 90z" fill="'+ ALARM_RED +'"/></svg>',
    title: 'Выключение'
  },
  batteryLow: {
    icn: '<svg width="30" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1920 576q53 0 90.5 37.5t37.5 90.5v384q0 53-37.5 90.5t-90.5 37.5v160q0 66-47 113t-113 47h-1856q-66 0-113-47t-47-113v-960q0-66 47-113t113-47h1856q66 0 113 47t47 113v160zm0 512v-384h-128v-288q0-14-9-23t-23-9h-1856q-14 0-23 9t-9 23v960q0 14 9 23t23 9h1856q14 0 23-9t9-23v-288h128z" fill="'+ ALARM_RED +'"/></svg>',
    title: 'Низкий уровень заряда'
  },
  batTest: {
    icn: '<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1024 1408h640v-128h-640v128zm-384-512h1024v-128h-1024v128zm640-512h384v-128h-384v128zm512 832v256q0 26-19 45t-45 19h-1664q-26 0-45-19t-19-45v-256q0-26 19-45t45-19h1664q26 0 45 19t19 45zm0-512v256q0 26-19 45t-45 19h-1664q-26 0-45-19t-19-45v-256q0-26 19-45t45-19h1664q26 0 45 19t19 45zm0-512v256q0 26-19 45t-45 19h-1664q-26 0-45-19t-19-45v-256q0-26 19-45t45-19h1664q26 0 45 19t19 45z" fill="'+ ALARM_YELLOW +'"/></svg>',
    title: 'Тестирование'
  }
};
