function __pwneo_populateObject(obj, row, colnamesmap) {
  for (var i in obj) {
    obj[i] = row[colnamesmap[i]];
  }
}

/**
 * @param selectresult array of rows; a row is an array, of which each element
 * is a column.
 * @param objconstructor objects constructor; prototype obj(row, colnamesmap)
 * @return array of objects.
 */
function pwneo_createObjects(objconstructor, selectresult) {
  var colnames = selectresult[0];
  var colnamesmap = new Array();
  for (var i in colnames) {
    colnamesmap[colnames[i]] = i;
  }
  var res = new Array();
  var len = selectresult.length;
  for (var i = 1; i < len; i++) {
    res.push(new objconstructor(selectresult[i], colnamesmap));
  }
  return res;
}

/**
 * @return index to the first event with type in the specified types or -1 not
 * found. Does not check event at offset.
 */
function pwneo_searchNextEventType(evsarray, offset, type) {
  var len = evsarray.length;
  while (++offset < len) {
    if (type == evsarray[offset].TYPE) {
      return offset;
    }
  }
  return -1;
}
/**
 * @return index to the first event with type in the specified types or -1 not
 * found. Does not check event at offset.
 */
function pwneo_searchPreviousEventType(evsarray, offset, stopind, type) {
  while (stopind != --offset) {
    if (type == evsarray[offset].TYPE) {
      return offset;
    }
  }
  return -1;
}

/**
 * @return array of system event types.
 */
function __pwneo_getSystemEventTypesWithActivation() {
  var res = [];
  var type;
  var activationType;
  var deactivationType;
  var len = PwneoSystemEvent.TYPES.length;
  for (var i = 0; i < len; i++) {
    activationType = PwneoSystemEvent.TYPES[i];
    deactivationType = PwneoSystemEvent.getDeactivationType(activationType);
    if (deactivationType && activationType == deactivationType) {
      res.push(activationType);
    }
  }
  return res;
}

/**
 * Inserts a deactivation event with the specified time for events that
 * remained activated at ind1. Applies only to events with not-null ACTIVATION
 * field. Only one event of each type is expected to remain activated.
 * @param evs sorted by time, descending order.
 * @return number of virtual events inserted.
 */
function __pwneo_closeUndeactivatedSystemEvents(systemevs, powerUpInd, powerDownInd) {
  var evsCnt0 = systemevs.length;
  var deactivationTime = systemevs[powerDownInd].TIME;
  var eventTypes = __pwneo_getSystemEventTypesWithActivation();
  var len = eventTypes.length;
  for (var i = 0; i != len; i++) {
    var type = eventTypes[i];
    var eventInd = pwneo_searchPreviousEventType(systemevs, powerDownInd, powerUpInd, type);
    if (-1 != eventInd) {
      var event = systemevs[eventInd];
      if (event.ACTIVATION) {
        systemevs.splice(powerDownInd, 0, new PwneoVirtualEvent(deactivationTime, 0, type, event));
        powerDownInd++;
      }
    }
  }
  return systemevs.length - evsCnt0;
}

/**
 * A close pair is an array in the form  [activation type, deactivation type]
 * (e.g. MONSTART, MONSTOP). POWERUP and POWERDOWN are not included in the
 * returned array.
 * @return array close pairs.
 */
function __pwneo_getSystemEventTypesClosePairs() {
  var res = [];
  var len = PwneoSystemEvent.TYPES.length;
  for (var i = 0; i < len; i++) {
    var activationType = PwneoSystemEvent.TYPES[i];
    if (PwneoSystemEvent.TYPE_POWERUP == activationType || PwneoSystemEvent.TYPE_POWERDOWN == activationType) {
      continue;
    }
    var deactivationType = PwneoSystemEvent.getDeactivationType(activationType);
    if (deactivationType && activationType != deactivationType) {
      res.push([activationType, deactivationType]);
    }
  }
  return res;
}

/**
 * Inserts a deactivation event at power down time for events that remained
 * activated at power down. Only one event of each type is expected to remain
 * activated.
 * @param systemevs sorted by time, descending order.
 * @return number of virtual events inserted.
 */
function __pwneo_closeSystemEventPairs(systemevs, powerUpInd, powerDownInd) {
  var evsCnt0 = systemevs.length;
  var eventPairs = __pwneo_getSystemEventTypesClosePairs();
  var deactivationTime = systemevs[powerDownInd].TIME;
  var len = eventPairs.length;
  for (var i = 0; i < len; i++) {
    var pair = eventPairs[i];
    var deactivationInd = pwneo_searchPreviousEventType(systemevs, powerDownInd, powerUpInd, pair[1]);
    var activationInd = pwneo_searchPreviousEventType(systemevs, powerDownInd, powerUpInd, pair[0]);
    //If any event is not found the corresponding index will be equal to -1
    if (activationInd <= deactivationInd) {
      continue;
    }
    systemevs.splice(powerDownInd, 0, new PwneoVirtualEvent(deactivationTime, null, pair[1], systemevs[activationInd]));
    powerDownInd++;
  }
  return systemevs.length - evsCnt0;
}

/**
 * Starts closing after the specified offset.
 * @return index of first not processed event.
 */
function __pwneo_closeUndeactivatedMonitorEvents(monitorevs, offset, monStopTime) {
  var virtualEvs = [];
  while (++offset < monitorevs.length && monitorevs[offset].TIME < monStopTime) {
    var event = monitorevs[offset];
    if (null != event.REFID || !event.ACTIVATION) {
      continue;
    }
    virtualEvs.push(new PwneoVirtualEvent(monStopTime, 0, event.TYPE, event));
  }
  monitorevs.splice.apply(monitorevs, [offset, 0].concat(virtualEvs));
  offset += virtualEvs.length;
  return offset;
}

/**
 * @param str a base64 encoded string.
 * @param ctor TypedArray constructor.
 */
function __pwneo_base64ToTypedArray(str, ctor) {
  var arr = Uint8Array.from(atob(str), function (v) {
    return v.charCodeAt(0);
  });
  return new ctor(arr.buffer);
}

/**
 * Inserts deactivation events lost because of a premature power down.
 * Both events arrays MUST be created with the same time bounds.
 * @param monitorevs can be NULL.
 * @param systemevs sorted by time, descending order.
 */
function pwneo_createLostEvents(systemevs, monitorevs) {
  var powerUpInd;
  var powerDownInd;
  var nextPowerUpInd;
  var powerUpEv;
  var nextPowerUpEv;
  var tmp;

  if (0 == systemevs.length) {
    return;
  }
  //Initialize nextPowerUpInd with 0 if first event is a POWERUP event so that it's
  //fast to detect wether MONITORSTART of first monitoring should be present
  //in systemevs
  if (PwneoSystemEvent.TYPE_POWERUP == systemevs[0].TYPE) {
    powerUpInd = 0; //MONITORSTART should be present in systemevs
    powerUpEv = systemevs[0];
  } else {
    powerUpInd = -1; //MONITORSTART may not be present in systemevs
    powerUpEv = null;
  }
  while (1) {
    nextPowerUpInd = pwneo_searchNextEventType(systemevs, powerUpInd, PwneoSystemEvent.TYPE_POWERUP);
    if (-1 == nextPowerUpInd) {
      break;
    }
    nextPowerUpEv = systemevs[nextPowerUpInd];
    //Check POWERDOWN
    powerDownInd = pwneo_searchPreviousEventType(systemevs, nextPowerUpInd, powerUpInd, PwneoSystemEvent.TYPE_POWERDOWN);
    if (-1 == powerDownInd) {
      powerDownInd = nextPowerUpInd;
      systemevs.splice(powerDownInd, 0, new PwneoVirtualEvent(nextPowerUpEv.TIME, null, PwneoSystemEvent.TYPE_POWERDOWN, powerUpEv));
      nextPowerUpInd++; //A virtual event inserted before next POWERUP event
    }
    //
    tmp = __pwneo_closeSystemEventPairs(systemevs, powerUpInd, powerDownInd);
    powerDownInd += tmp;
    nextPowerUpInd += tmp;
    //
    nextPowerUpInd += __pwneo_closeUndeactivatedSystemEvents(
      systemevs,
      powerUpInd,
      powerDownInd,
      systemevs[powerDownInd].TIME,
      __pwneo_getSystemEventTypesWithActivation(),
    );
    //
    powerUpInd = nextPowerUpInd;
    powerUpEv = nextPowerUpEv;
  }
  //
  if (!monitorevs || 0 == monitorevs.length) {
    return;
  }
  var lastTime;
  var monStopInd = -1;
  var monInd = 0;
  while (1) {
    monInd--; //Go back to the last processed event
    monStopInd = pwneo_searchNextEventType(systemevs, monStopInd, PwneoSystemEvent.TYPE_MONITORSTOP);
    if (-1 == monStopInd) {
      break;
    }
    monInd = __pwneo_closeUndeactivatedMonitorEvents(monitorevs, monInd, systemevs[monStopInd].TIME);
    if (monInd >= monitorevs.length) {
      break;
    }
  }
}

function PwneoVirtualEvent(timestamp, activation, type, refev) {
  this.EVID = --PwneoVirtualEvent.LASTEVID;
  this.TIME = timestamp;
  this.ACTIVATION = activation;
  this.TYPE = type;
  this.REFID = refev ? refev.EVID : null;
  if (refev) {
    refev.REFID = this.EVID;
  }
}
PwneoVirtualEvent.LASTEVID = 0;

function __PwneoLocatorValues(row, colnamesmap) {
  this.LOCATORVALUE1 = null;
  this.LOCATORVALUE2 = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function PwneoMeasureValue(row, colnamesmap) {
  this.MAGNITUDE = null; //See $SIGNAL_TYPE_MAGNITUDES in pwneo.php
  this.VALUE = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function PwneoMonitoring(row, colnamesmap) {
  this.MONID = null;
  this.MONNAME = null;
  this.MONDESCR = null;
  this.CHSETID = null;
  this.CREATIONTIME = null;
  this.LATITUDEDEG = null;
  this.LONGITUDEDEG = null;
  this.ANTENNAID = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function PwneoPolarization() {
  throw 'PwneoPolarization cannot be instantiated';
}
PwneoPolarization.isValid = function (v) {
  switch (v) {
    case PwneoPolarization.NONE:
    case PwneoPolarization.VERTICAL_HIGH:
    case PwneoPolarization.VERTICAL_LOW:
    case PwneoPolarization.HORIZONTAL_HIGH:
    case PwneoPolarization.HORIZONTAL_LOW:
    case PwneoPolarization.CIRCULAR_RIGHT:
    case PwneoPolarization.CIRCULAR_LEFT:
      return true;
  }
  return false;
};
PwneoPolarization.NONE = '--';
PwneoPolarization.VERTICAL_HIGH = 'VH';
PwneoPolarization.VERTICAL_LOW = 'VL';
PwneoPolarization.HORIZONTAL_HIGH = 'HH';
PwneoPolarization.HORIZONTAL_LOW = 'HL';
PwneoPolarization.CIRCULAR_RIGHT = 'CR';
PwneoPolarization.CIRCULAR_LEFT = 'CL';

function PwneoChannel(row, colnamesmap) {
  this.MONID = null;
  this.CHFREQKHZ = null;
  this.POLARIZATION = null;
  this.CHNAME = null;
  this.SIGNALTYPE = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!PwneoPolarization.isValid(this.POLARIZATION)) {
    throw 'Invalid polarization ' + this.POLARIZATION;
  }
}

function PwneoPriorityLocator(row, colnamesmap) {
  var locatorValues = new __PwneoLocatorValues(row, colnamesmap);
  switch (locatorValues.LOCATORVALUE1) {
    case 0:
      this.PRIORITY = PwneoPriorityLocator.LOW;
      break;
    case 1:
      this.PRIORITY = PwneoPriorityLocator.HIGH;
      break;
    default:
      throw 'Unexpected locatorvalue1 ' + locatorValues.LOCATORVALUE1 + ' for priority';
  }
}
PwneoPriorityLocator.isValid = function (v) {
  switch (v) {
    case PwneoPriorityLocator.HIGH:
    case PwneoPriorityLocator.LOW:
      return true;
  }
  return false;
};
PwneoPriorityLocator.HIGH = 'H';
PwneoPriorityLocator.LOW = 'L';

function PwneoLayerLocator(row, colnamesmap) {
  var locatorValues = new __PwneoLocatorValues(row, colnamesmap);
  switch (locatorValues.LOCATORVALUE1) {
    case 0:
      this.LAYER = PwneoLayerLocator.A;
      break;
    case 1:
      this.LAYER = PwneoLayerLocator.B;
      break;
    case 2:
      this.LAYER = PwneoLayerLocator.C;
      break;
    default:
      throw 'Unexpected locatorvalue1 ' + locatorValues.LOCATORVALUE1 + ' for layer';
  }
}
PwneoLayerLocator.isValid = function (v) {
  switch (v) {
    case PwneoLayerLocator.A:
    case PwneoLayerLocator.B:
    case PwneoLayerLocator.C:
      return true;
  }
  return false;
};
PwneoLayerLocator.A = 'A';
PwneoLayerLocator.B = 'B';
PwneoLayerLocator.C = 'C';

function PwneoDsliceLocator(row, colnamesmap) {
  var locatorValues = new __PwneoLocatorValues(row, colnamesmap);
  this.DSLICENUM = locatorValues.LOCATORVALUE1;
  this.PLPNUM = locatorValues.LOCATORVALUE2;
}

function PwneoProfileLocator(row, colnamesmap) {
  var locatorValues = new __PwneoLocatorValues(row, colnamesmap);
  switch (locatorValues.LOCATORVALUE1) {
    case 0:
      this.PROFILE = PwneoProfileLocator.NONE;
      break;
    case 1:
      this.PROFILE = PwneoProfileLocator.BASE;
      break;
    case 2:
      this.PROFILE = PwneoProfileLocator.LITE;
      break;
    default:
      throw 'Unexpected locatorvalue1 ' + locatorValues.LOCATORVALUE1 + ' for profile';
  }
  this.PLPNUM = locatorValues.LOCATORVALUE2;
}
PwneoProfileLocator.isValidProfile = function (v) {
  switch (v) {
    case PwneoProfileLocator.BASE:
    case PwneoProfileLocator.LITE:
    case PwneoProfileLocator.NONE:
      return true;
  }
  return false;
};
PwneoProfileLocator.BASE = 'BASE';
PwneoProfileLocator.LITE = 'LITE';
PwneoProfileLocator.NONE = 'NONE';

/**
 * Only one of its properties will not be NULL.
 */
function PwneoLocator(locatortype, row, colnamesmap) {
  switch (locatortype) {
    case PwneoLocator.TYPE_PRIORITY:
      this.PRIORITY = new PwneoPriorityLocator(row, colnamesmap);
      break;
    case PwneoLocator.TYPE_LAYER:
      this.LAYER = new PwneoLayerLocator(row, colnamesmap);
      break;
    case PwneoLocator.TYPE_DSLICE:
      this.DSLICE = new PwneoDsliceLocator(row, colnamesmap);
      break;
    case PwneoLocator.TYPE_PROFILE:
      this.PROFILE = new PwneoProfileLocator(row, colnamesmap);
      break;
    default:
      throw 'Unexpected locatortype ' + locatortype;
  }
}
PwneoLocator.isValidType = function (v) {
  switch (v) {
    case null:
    case PwneoLocator.TYPE_LAYER:
    case PwneoLocator.TYPE_PRIORITY:
    case PwneoLocator.TYPE_PROFILE:
    case PwneoLocator.TYPE_DSLICE:
      return true;
  }
  return false;
};

PwneoLocator.TYPE_LAYER = 'LAYER';
PwneoLocator.TYPE_PRIORITY = 'PRIORITY';
PwneoLocator.TYPE_PROFILE = 'PROFILE';
PwneoLocator.TYPE_DSLICE = 'DSLICE';

function PwneoMeasure(row, colnamesmap) {
  this.MEASID = null;
  this.CHFREQKHZ = null;
  this.POLARIZATION = null;
  this.MONID = null;
  this.TIME = null;
  this.SIGNALTYPE = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!PwneoPolarization.isValid(this.POLARIZATION)) {
    throw 'Invalid polarization ' + this.POLARIZATION;
  }
  //
  this.MEASURE = new PwneoMeasureValue(row, colnamesmap);
  var locatortype = row[colnamesmap.LOCATORTYPE];
  this.LOCATOR = locatortype ? new PwneoLocator(locatortype, row, colnamesmap) : null;
}

function PwneoSystemEvent(row, colnamesmap) {
  this.EVID = null;
  this.TIME = null; //Seconds since epoch (see time_t c data type)
  this.ACTIVATION = null;
  this.REFID = null;
  this.TYPE = null;
  this.INTINFO = null;
  this.STRINFO = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!PwneoSystemEvent.isValidType(this.TYPE)) {
    throw 'Invalid type ' + this.TYPE;
  }
}
PwneoSystemEvent.isValidType = function (v) {
  switch (v) {
    case PwneoSystemEvent.TYPE_HWERROR:
    case PwneoSystemEvent.TYPE_DISKFULLALARM:
    case PwneoSystemEvent.TYPE_DISKFULLWARN:
    case PwneoSystemEvent.TYPE_POWERUP:
    case PwneoSystemEvent.TYPE_POWERDOWN:
    case PwneoSystemEvent.TYPE_MONITORSTART:
    case PwneoSystemEvent.TYPE_MONITORSTOP:
    case PwneoSystemEvent.TYPE_LNBERROR:
    case PwneoSystemEvent.TYPE_TEMPERATUREERROR:
      return true;
  }
  return false;
};
/**
 * @return null the event has no deactivation (it may be the deactivation
 * itself).
 */
PwneoSystemEvent.getDeactivationType = function (type) {
  switch (type) {
    case PwneoSystemEvent.TYPE_HWERROR:
    case PwneoSystemEvent.TYPE_DISKFULLALARM:
    case PwneoSystemEvent.TYPE_DISKFULLWARN:
    case PwneoSystemEvent.TYPE_LNBERROR:
    case PwneoSystemEvent.TYPE_TEMPERATUREERROR:
      return type;
    case PwneoSystemEvent.TYPE_POWERUP:
      return PwneoSystemEvent.TYPE_POWERDOWN;
    case PwneoSystemEvent.TYPE_MONITORSTART:
      return PwneoSystemEvent.TYPE_MONITORSTOP;
    case PwneoSystemEvent.TYPE_POWERDOWN:
    case PwneoSystemEvent.TYPE_MONITORSTOP:
      return null;
  }
  throw 'Unexpected PwneoSystemEvent type: ' + type;
};
PwneoSystemEvent.TYPE_HWERROR = 'HWERROR';
PwneoSystemEvent.TYPE_DISKFULLALARM = 'DISKFULLALARM';
PwneoSystemEvent.TYPE_DISKFULLWARN = 'DISKFULLWARN';
PwneoSystemEvent.TYPE_POWERUP = 'POWUP';
PwneoSystemEvent.TYPE_POWERDOWN = 'POWDOWN';
PwneoSystemEvent.TYPE_MONITORSTART = 'MONSTART';
PwneoSystemEvent.TYPE_MONITORSTOP = 'MONSTOP';
PwneoSystemEvent.TYPE_LNBERROR = 'LNBERROR';
PwneoSystemEvent.TYPE_TEMPERATUREERROR = 'TEMPERROR';
PwneoSystemEvent.TYPES = [
  PwneoSystemEvent.TYPE_HWERROR,
  PwneoSystemEvent.TYPE_DISKFULLALARM,
  PwneoSystemEvent.TYPE_DISKFULLWARN,
  PwneoSystemEvent.TYPE_POWERUP,
  PwneoSystemEvent.TYPE_POWERDOWN,
  PwneoSystemEvent.TYPE_MONITORSTART,
  PwneoSystemEvent.TYPE_MONITORSTOP,
  PwneoSystemEvent.TYPE_LNBERROR,
  PwneoSystemEvent.TYPE_TEMPERATUREERROR,
];

function PwneoMonitorEvent(row, colnamesmap) {
  this.EVID = null;
  this.TIME = null; //Seconds since epoch (see time_t c data type)
  this.ACTIVATION = null;
  this.REFID = null;
  this.TYPE = null;
  this.SIGNALTYPE = null; //See $SIGNAL_TYPE_MAGNITUDES in pwneo.php
  this.CHFREQKHZ = null;
  this.POLARIZATION = null;
  this.MONID = null;
  this.THRESHOLD = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!PwneoPolarization.isValid(this.POLARIZATION)) {
    throw 'Invalid polarization ' + this.POLARIZATION;
  }
  if (!PwneoMonitorEvent.isValidType(this.TYPE)) {
    throw 'Invalid type ' + this.TYPE;
  }
  this.MEASURE = row[colnamesmap.MAGNITUDE] ? new PwneoMeasureValue(row, colnamesmap) : null;
  var locatortype = row[colnamesmap.LOCATORTYPE];
  this.LOCATOR = locatortype ? new PwneoLocator(locatortype, row, colnamesmap) : null;
}
PwneoMonitorEvent.isValidType = function (v) {
  switch (v) {
    case PwneoMonitorEvent.TYPE_OVERALARMTHRESHOLD:
    case PwneoMonitorEvent.TYPE_UNDERALARMTHRESHOLD:
    case PwneoMonitorEvent.TYPE_OVERWARNTHR:
    case PwneoMonitorEvent.TYPE_UNDERWARNTHR:
    case PwneoMonitorEvent.TYPE_SIGNALLOST:
    case PwneoMonitorEvent.TYPE_NEWSIGNAL:
      return true;
  }
  return false;
};
PwneoMonitorEvent.TYPE_OVERALARMTHRESHOLD = 'OVERALARMTHR';
PwneoMonitorEvent.TYPE_UNDERALARMTHRESHOLD = 'UNDERALARMTHR';
PwneoMonitorEvent.TYPE_OVERWARNTHR = 'OVERWARNTHR';
PwneoMonitorEvent.TYPE_UNDERWARNTHR = 'UNDERWARNTHR';
PwneoMonitorEvent.TYPE_SIGNALLOST = 'LOST';
PwneoMonitorEvent.TYPE_NEWSIGNAL = 'NEW';
PwneoMonitorEvent.TYPES = [
  PwneoMonitorEvent.TYPE_OVERALARMTHRESHOLD,
  PwneoMonitorEvent.TYPE_UNDERALARMTHRESHOLD,
  PwneoMonitorEvent.TYPE_OVERWARNTHR,
  PwneoMonitorEvent.TYPE_UNDERWARNTHR,
  PwneoMonitorEvent.TYPE_SIGNALLOST,
  PwneoMonitorEvent.TYPE_NEWSIGNAL,
];

function PwneoNotificationDestination(row, colnamesmap) {
  this.DESTINATIONID = null;
  this.TYPE = null;
  this.DESTINATION = null;
  this.NAME = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!PwneoNotificationDestination.isValidDestinationType(this.TYPE)) {
    throw 'Invalid destination type ' + this.TYPE;
  }
}
PwneoNotificationDestination.isValidDestinationType = function (v) {
  switch (v) {
    case PwneoNotificationDestination.TYPE_EMAIL:
    case PwneoNotificationDestination.TYPE_SMS:
      return true;
  }
  return false;
};
PwneoNotificationDestination.TYPE_EMAIL = 'EMAIL';
PwneoNotificationDestination.TYPE_SMS = 'SMS';

function PwneoMagnitudeSettings(row, colnamesmap) {
  this.MAGNITUDE = null;
  this.UNITS = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function PwneoSpectrumMonitoringGroup(row, colnamesmap) {
  this.GRPID = null;
  this.NAME = null;
  this.DESCR = null;
  this.CREATIONTIME = null;
  this.POINTUNITS = null;
  this.POINTSDB = null;
  this.BAND = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function PwneoSpectrumEvents(row, colnamesmap) {
  this.EVID = null;
  this.TIME = null;
  this.ACTIVATION = null;
  this.REFID = null;
  this.TYPE = null;
  this.SEVERITY = null;
  this.FREQC = null;
  this.FREQ0 = null;
  this.FREQ1 = null;
  this.VALUE = null;
  this.THRESHOLD = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function PwneoSpectrumMonitoring(row, colnamesmap) {
  this.SPMONID = null;
  this.RFENTRY = null;
  this.MONNAME = null;
  this.SCANPERIOD = null;
  this.MONTYPE = null;
  this.SIGNALTYPE = null; //See $SIGNAL_TYPE_MAGNITUDES in pwneo.php
  this.POLARIZATION = null;
  this.LNBOSCH = null;
  this.LNBOSCL = null;
  this.THRESHOLDMIN = null;
  this.THRESHOLDMAX = null;
  this.ALARMPERSISTENCY = null;
  this.FREQSTART = null;
  this.FREQEND = null;
  this.FREQANALYSIS = null;
  this.BWANALYSIS = null;
  this.AVERAGECOUNT = null;
  this.REFERENCELEVEL = null;
  this.RESOLUTIONFILTERBW = null;
  this.VIDEOFILTER = null;
  this.SPECTRUMFREQS = null;
  this.REFSPECTRUMPOINTS = null;
  __pwneo_populateObject(this, row, colnamesmap);
  this.SPECTRUMFREQS = __pwneo_base64ToTypedArray(this.SPECTRUMFREQS, Uint32Array);
  if (this.REFSPECTRUMPOINTS) {
    this.REFSPECTRUMPOINTS = __pwneo_base64ToTypedArray(this.REFSPECTRUMPOINTS, Float32Array);
  }
  if (!PwneoSpectrumMonitoring.isValidMonitorizationType(this.MONTYPE)) {
    throw 'Invalid monitorization type ' + this.MONTYPE;
  }
  if (this.POLARIZATION !== null) {
    if (!PwneoPolarization.isValid(this.POLARIZATION)) {
      throw 'Invalid polarization ' + this.POLARIZATION;
    }
    this.POLARIZATION = PwneoSpectrumMonitoring.convertPolarization(this.POLARIZATION);
  }
  if (this.MONTYPE == PwneoSpectrumMonitoring.TYPE_FMBAND || this.MONTYPE == PwneoSpectrumMonitoring.TYPE_NOALG) {
    this.FREQANALYSIS = null;
    this.BWANALYSIS = null;
    if (this.MONTYPE == PwneoSpectrumMonitoring.TYPE_NOALG) {
      this.THRESHOLDMIN = null;
      this.THRESHOLDMAX = null;
    }
  }
}

PwneoSpectrumMonitoring.convertPolarization = function (v) {
  switch (v) {
    case PwneoPolarization.NONE:
      return '--';
    case PwneoPolarization.VERTICAL_HIGH:
      return 'Vertical/High';
    case PwneoPolarization.VERTICAL_LOW:
      return 'Vertical/Low';
    case PwneoPolarization.HORIZONTAL_HIGH:
      return 'Horizontal/High';
    case PwneoPolarization.HORIZONTAL_LOW:
      return 'Horizontal/Low';
    case PwneoPolarization.CIRCULAR_RIGHT:
      return 'Right';
    case PwneoPolarization.CIRCULAR_LEFT:
      return 'Left';
  }
};
PwneoSpectrumMonitoring.isValidMonitorizationType = function (v) {
  switch (v) {
    case PwneoSpectrumMonitoring.TYPE_TVBAND:
    case PwneoSpectrumMonitoring.TYPE_FMBAND:
    case PwneoSpectrumMonitoring.TYPE_MINMAX:
    case PwneoSpectrumMonitoring.TYPE_DEVIATION:
    case PwneoSpectrumMonitoring.TYPE_NOALG:
      return true;
  }
  return false;
};

PwneoSpectrumMonitoring.TYPE_TVBAND = 'TVBAND';
PwneoSpectrumMonitoring.TYPE_FMBAND = 'FMBAND';
PwneoSpectrumMonitoring.TYPE_MINMAX = 'MINMAX';
PwneoSpectrumMonitoring.TYPE_DEVIATION = 'DEVIATION';
PwneoSpectrumMonitoring.TYPE_NOALG = 'NOALG';

function PwneoSpectrumPoint(row, colnamesmap) {
  this.TIME = null;
  this.POINTS = null;
  __pwneo_populateObject(this, row, colnamesmap);
  this.POINTS = __pwneo_base64ToTypedArray(this.POINTS, Float32Array);
}

function TkneoTaskScheduling(row, colnamesmap) {
  this.TASKID = null;
  this.TASKTYPE = null;
  this.NEXTRUNDATE = null;
  this.EXPIRATIONDATE = null;
  this.PREVIOUSRUNTIME = null;
  this.REPETITIONTYPE = null;
  this.REPETITIONSTARTMOMENT = null;
  this.REPETITIONP1 = null;
  this.REPETITIONP2 = null;
  this.RUNDURATION = null;
  this.ERRTYPE = null;
  this.ENABLED = null;
  this.TIME = null;
  this.descr = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!TkneoTaskScheduling.isValidTaskType(this.TASKTYPE)) {
    throw 'Invalid taskscheduling type ' + this.TASKTYPE;
  }
  if (!TkneoTaskScheduling.isValidRepetitionType(this.REPETITIONTYPE)) {
    throw 'Invalid taskscheduling repetitiontype ' + this.REPETITIONTYPE;
  }
  if (this.ERRTYPE != null && !TkneoTaskScheduling.isValidErrType(this.ERRTYPE)) {
    throw 'Invalid taskscheduling errtype ' + this.ERRTYPE;
  }
}

TkneoTaskScheduling.isValidTaskType = function (v) {
  switch (v) {
    case TkneoTaskScheduling.TYPE_SCANNING:
    case TkneoTaskScheduling.TYPE_MONITORING:
    case TkneoTaskScheduling.TYPE_CAPTURE:
    case TkneoTaskScheduling.TYPE_DATALOGGER:
    case TkneoTaskScheduling.TYPE_TSRECORD:
    case TkneoTaskScheduling.TYPE_AUDIORECORD:
    case TkneoTaskScheduling.TYPE_ETIRECORD:
      return true;
  }
  return false;
};

TkneoTaskScheduling.TYPE_SCANNING = 'SCANNING';
TkneoTaskScheduling.TYPE_MONITORING = 'MONITORING';
TkneoTaskScheduling.TYPE_CAPTURE = 'CAPTURE';
TkneoTaskScheduling.TYPE_DATALOGGER = 'DATALOGGER';
TkneoTaskScheduling.TYPE_TSRECORD = 'TSRECORD';
TkneoTaskScheduling.TYPE_AUDIORECORD = 'AUDIORECORD';
TkneoTaskScheduling.TYPE_ETIRECORD = 'ETIRECORD';

TkneoTaskScheduling.isValidRepetitionType = function (v) {
  switch (v) {
    case TkneoTaskScheduling.TYPE_BOOT:
    case TkneoTaskScheduling.TYPE_HOURLY:
    case TkneoTaskScheduling.TYPE_WEEKLY:
    case TkneoTaskScheduling.TYPE_MONTHLY:
    case TkneoTaskScheduling.TYPE_NONE:
      return true;
  }
  return false;
};

TkneoTaskScheduling.TYPE_BOOT = 'BOOT';
TkneoTaskScheduling.TYPE_HOURLY = 'HOURLY';
TkneoTaskScheduling.TYPE_WEEKLY = 'WEEKLY';
TkneoTaskScheduling.TYPE_MONTHLY = 'MONTHLY';
TkneoTaskScheduling.TYPE_NONE = 'NONE';

TkneoTaskScheduling.isValidErrType = function (v) {
  switch (v) {
    case TkneoTaskScheduling.TYPE_NOERROR:
    case TkneoTaskScheduling.TYPE_BUSY:
    case TkneoTaskScheduling.TYPE_DIDNTFIND:
    case TkneoTaskScheduling.TYPE_HWERROR:
    case TkneoTaskScheduling.TYPE_MEMERROR:
    case TkneoTaskScheduling.TYPE_NOSIGNAL:
    case TkneoTaskScheduling.TYPE_TIMEOUT:
    case TkneoTaskScheduling.TYPE_SKIPPEDLAUNCH:
    case TkneoTaskScheduling.TYPE_TYPE:
      return true;
  }
  return false;
};

TkneoTaskScheduling.TYPE_NOERROR = 'NOERROR';
TkneoTaskScheduling.TYPE_BUSY = 'BUSY';
TkneoTaskScheduling.TYPE_DIDNTFIND = 'DIDNTFIND';
TkneoTaskScheduling.TYPE_HWERROR = 'HWERROR';
TkneoTaskScheduling.TYPE_MEMERROR = 'MEMERROR';
TkneoTaskScheduling.TYPE_NOSIGNAL = 'NOSIGNAL';
TkneoTaskScheduling.TYPE_TIMEOUT = 'TIMEOUT';
TkneoTaskScheduling.TYPE_SKIPPEDLAUNCH = 'SKIPPEDLAUNCH';
TkneoTaskScheduling.TYPE_TYPE = 'TYPE';

function TkneoSpectralMonitoringTask(row, colnamesmap) {
  this.TASKID = null;
  this.GRPID = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function TkneoMonitoringTask(row, colnamesmap) {
  this.TASKID = null;
  this.MONID = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function TkneoCaptureTask(row, colnamesmap) {
  this.TASKID = null;
  this.CAPTURETYPE = null;
  this.CAPTUREFORM = null;
  this.IMAGEPATH = null;
  this.DATAPATH = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!TkneoCaptureTask.isValidCaptureType(this.CAPTURETYPE)) {
    throw 'Invalid capturetask type ' + this.CAPTURETYPE;
  }
  if (!TkneoCaptureTask.isValidCaptureForm(this.CAPTUREFORM)) {
    throw 'Invalid capturetask form ' + this.CAPTUREFORM;
  }
}

TkneoCaptureTask.isValidCaptureType = function (v) {
  switch (v) {
    case TkneoCaptureTask.TYPE_SCREEN:
    case TkneoCaptureTask.TYPE_DATA:
    case TkneoCaptureTask.TYPE_BOTH:
      return true;
  }
  return false;
};

TkneoCaptureTask.TYPE_SCREEN = 'SCREEN';
TkneoCaptureTask.TYPE_DATA = 'DATA';
TkneoCaptureTask.TYPE_BOTH = 'BOTH';

TkneoCaptureTask.isValidCaptureForm = function (v) {
  switch (v) {
    case TkneoCaptureTask.FORM_SP1:
    case TkneoCaptureTask.FORM_SP2:
    case TkneoCaptureTask.FORM_SP3:
    case TkneoCaptureTask.FORM_MEAS1:
    case TkneoCaptureTask.FORM_MEAS2:
    case TkneoCaptureTask.FORM_MEAS3:
    case TkneoCaptureTask.FORM_TV1:
    case TkneoCaptureTask.FORM_TV2:
    case TkneoCaptureTask.FORM_TV3:
    case TkneoCaptureTask.FORM_IPTV:
    case TkneoCaptureTask.FORM_IPMEAS:
    case TkneoCaptureTask.FORM_INTERPA:
      return true;
  }
  return false;
};

TkneoCaptureTask.FORM_SP1 = 'SP1';
TkneoCaptureTask.FORM_SP2 = 'SP2';
TkneoCaptureTask.FORM_SP3 = 'SP3';
TkneoCaptureTask.FORM_MEAS1 = 'MEAS1';
TkneoCaptureTask.FORM_MEAS2 = 'MEAS2';
TkneoCaptureTask.FORM_MEAS3 = 'MEAS3';
TkneoCaptureTask.FORM_TV1 = 'TV1';
TkneoCaptureTask.FORM_TV2 = 'TV2';
TkneoCaptureTask.FORM_TV3 = 'TV3';
TkneoCaptureTask.FORM_IPTV = 'IPTV';
TkneoCaptureTask.FORM_IPMEAS = 'IPMEAS';
TkneoCaptureTask.FORM_INTERPA = 'INTERPA';

function TkneoDataloggerTask(row, colnamesmap) {
  this.TASKID = null;
  this.DATALOGGERNAME = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function TkneoTSRecordTask(row, colnamesmap) {
  this.TASKID = null;
  this.BAND = null;
  this.CHANNEL = null;
  this.CHANNELNAME = null;
  this.SIGNALTYPE = null;
  this.SERVICE = null;
  this.PID = null;
  this.PLP = null;
  this.PLPID = null;
  this.CHANNELPLAN = null;
  this.FILENAME = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!TkneoTSRecordTask.isValidTSRecordBand(this.BAND)) {
    throw 'Invalid tsrecordtask band ' + this.BAND;
  }
}

TkneoTSRecordTask.BAND_TER = 'TER';
TkneoTSRecordTask.BAND_SAT = 'SAT';

TkneoTSRecordTask.isValidTSRecordBand = function (v) {
  switch (v) {
    case TkneoTSRecordTask.BAND_TER:
    case TkneoTSRecordTask.BAND_SAT:
      return true;
  }
  return false;
};

function TkneoAudioRecordTask(row, colnamesmap) {
  this.TASKID = null;
  this.BAND = null;
  this.CHANNEL = null;
  this.CHANNELNAME = null;
  this.SIGNALTYPE = null;
  this.SERVICE = null;
  this.PID = null;
  this.PLP = null;
  this.PLPID = null;
  this.CHANNELPLAN = null;
  this.FILENAME = null;
  __pwneo_populateObject(this, row, colnamesmap);
  if (!TkneoAudioRecordTask.isValidAudioRecordBand(this.BAND)) {
    throw 'Invalid audiorecordtask band ' + this.BAND;
  }
}

TkneoAudioRecordTask.BAND_TER = 'TER';
TkneoAudioRecordTask.BAND_SAT = 'SAT';

TkneoAudioRecordTask.isValidAudioRecordBand = function (v) {
  switch (v) {
    case TkneoAudioRecordTask.BAND_TER:
    case TkneoAudioRecordTask.BAND_SAT:
      return true;
  }
  return false;
};

function TkneoEtiRecordTask(row, colnamesmap) {
  this.TASKID = null;
  this.CHANNEL = null;
  this.CHANNELNAME = null;
  this.SERVICE = null;
  this.PID = null;
  this.CHANNELPLAN = null;
  this.FILENAME = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

function TkneoTaskExecutions(row, colnamesmap) {
  this.TASKID = null;
  this.ERRTYPE = null;
  this.TIME = null;
  this.DESCR = null;
  __pwneo_populateObject(this, row, colnamesmap);
}

TkneoTaskExecutions.isValidType = function (v) {
  switch (v) {
    case TkneoTaskExecutions.TYPE_NOERROR:
    case TkneoTaskExecutions.TYPE_BUSY:
    case TkneoTaskExecutions.TYPE_DIDNTFIND:
    case TkneoTaskExecutions.TYPE_HWERROR:
    case TkneoTaskExecutions.TYPE_MEMERROR:
    case TkneoTaskExecutions.TYPE_NOSIGNAL:
    case TkneoTaskExecutions.TYPE_TIMEOUT:
    case TkneoTaskExecutions.TYPE_SKIPPEDLAUNCH:
    case TkneoTaskExecutions.TYPE_TYPE:
      return true;
  }
  return false;
};

TkneoTaskExecutions.TYPE_NOERROR = 'NOERROR';
TkneoTaskExecutions.TYPE_BUSY = 'BUSY';
TkneoTaskExecutions.TYPE_DIDNTFIND = 'DIDNTFIND';
TkneoTaskExecutions.TYPE_HWERROR = 'HWERROR';
TkneoTaskExecutions.TYPE_MEMERROR = 'MEMERROR';
TkneoTaskExecutions.TYPE_NOSIGNAL = 'NOSIGNAL';
TkneoTaskExecutions.TYPE_TIMEOUT = 'TIMEOUT';
TkneoTaskExecutions.TYPE_SKIPPEDLAUNCH = 'SKIPPEDLAUNCH';
TkneoTaskExecutions.TYPE_TYPE = 'TYPE';
