<commit_before>/* jshint globalstrict: true */
"use strict";

var EventEmitter = require('./EventEmitter');
var ubjson = require('./ubjson');
var buffer = require('buffer');
var emcc_tools = require('./emcc_tools');
var xbee = require('./xbee');
var typpo = require('./typpo');

// 1 byte lost to the PiEMOS framing.
var MAX_XBEE_PAYLOAD_SIZE = 100 - 1;
var SEND_INTERVAL = 100;

var UBJSON_PORT = typpo.get_const('NDL3_UBJSON_PORT');
var STRING_PORT = typpo.get_const('NDL3_STRING_PORT');
var CODE_PORT = typpo.get_const('NDL3_CODE_PORT');

exports.RADIO_DEBUG = false;

try {
  var ndl3 = require('./ndl3');
} catch (_) {
  console.warn('Could not load ndl3.js. Did you run build.sh?');
}

function call(name) {
  var args = Array.prototype.slice.call(arguments, 1);
  var arg_ts = [];
  for (var i = 0; i < args.length; i++) {
    arg_ts.push('number');
  }
  return ndl3.ccall(name, 'number', arg_ts, args);
}

var Radio = function(address, serportObj) {
  EventEmitter.apply(this);
  this.connected = false;
  this._accumulator = null;
  this.net = call('NDL3_new', 0, 0, 0);
  if (this.net === 0) {
    throw 'Could not allocate NDL3.';
  }
  call('NDL3_open', this.net, UBJSON_PORT);
  call('NDL3_open', this.net, STRING_PORT);
  call('NDL3_open', this.net, CODE_PORT);

  this._tick = send_L2.bind(this);
  setInterval(this._tick, SEND_INTERVAL);

  this.on('send_object', send_object.bind(this));
  this.on('send_string', send_string.bind(this));
  this.on('send_code', send_code.bind(this));
  this.on('data', recv_L2.bind(this));

  if (address !== undefined &&
      serportObj !== undefined) {
    this.connectXBee(address, serportObj);
  } else {
    this.address = null;
    this.serportObj = null;
  }
  this._send_data = send_data.bind(this);

  if (exports.RADIO_DEBUG) {
    // Print out every message in or out of the radio, for debugging
    // purposes.
    var events = ['data', 'object', 'string', 'code'];
    for (var e = 0; e < events.length; e++) {
      var evt = events[e];
      this.on(evt, make_evt_callback(evt));
      this.on('send_' + evt, make_evt_callback('send_' + evt));
    }
  }
};

function make_evt_callback(evt) {
  return function (data) {
    console.log('radio: ', evt, ':', data);
  };
}

Radio.prototype = Object.create(EventEmitter.prototype);

Radio.prototype.isConnected = function () {
  return this.connected;
};

Radio.prototype.connectXBee = function (address, serportObj) {
  if (this.connected) {
    throw 'XBee has already been connected to radio.';
  }
  this.address = address;
  this.serportObj = serportObj;
  this._read_handler = read_handler.bind(this);
  this._accumulator = new xbee.Accumulator(serportObj);
  this._accumulator.on('data', this._read_handler);
  this._send_data = send_data.bind(this);
  this.on('send_data', this._send_data);
};

Radio.prototype.disconnectXBee = function () {
  this.off('send_data', this._send_data);
  this._accumulator.off('data', this._read_handler);
  this._accumulator.destroy();
  this._accumulator = null;
  this.address = null;
  this.serportObj = null;
};

function send_L2 () {
  /* jshint validthis: true */
  var out_size_ptr = call('malloc', emcc_tools.PTR_SIZE);
  var send_block = call('malloc', MAX_XBEE_PAYLOAD_SIZE);
  if (out_size_ptr === 0 || send_block === 0) {
    throw 'malloc failed';
  }

  emcc_tools.set_ptr(ndl3, out_size_ptr, 0);

  call('NDL3_elapse_time', this.net, SEND_INTERVAL);
  call('NDL3_L2_pop', this.net, send_block, MAX_XBEE_PAYLOAD_SIZE, out_size_ptr);
  var length = emcc_tools.get_ptr(ndl3, out_size_ptr);
  // 1 + makes room for ident byte.
  var send_buf = buffer.Buffer(1 + length);
  send_buf[0] = typpo.get_const('NDL3_IDENT');
  emcc_tools.ptr_to_buffer(ndl3, send_block, length, send_buf, 1);
  call('free', out_size_ptr);
  call('free', send_block);
  var xbee_packet = xbee.createPacket(send_buf, this.address);
  this.emit('send_data', xbee_packet);
  throw_on_NDL3_error(this.net);
}

function read_handler(data) {
  /* jshint validthis: true */
  this.emit('data', data);
}

function recv_L2 (rxbuf) {
  /* jshint validthis: true */
  // We need to extract the payload from the xbee packet.
  var data = xbee.extractPayload(rxbuf);
  if (data[0] !== typpo.get_const('NDL3_IDENT')) {
    // Not an NDL3 packet.
    return;
  } else {
    // Remove the framing.
    data = data.slice(1);
  }
  var ptr = emcc_tools.buffer_to_ptr(ndl3, data);
  call('NDL3_L2_push', this.net, ptr, data.length);
  call('free', ptr);

  check_L3.apply(this);
  // Ignore errors due to bad packets.
  call('NDL3_pop_error', this.net);
}

function check_L3() {
  /* jshint validthis: true */
  check_port.apply(this, [UBJSON_PORT, function (buf) {
    /* jshint validthis: true */
    this.emit('object', ubjson.decode(buf));
  }]);
  check_port.apply(this, [STRING_PORT, function (buf) {
    this.emit('string', buf.toString());
  }]);
  check_port.apply(this, [CODE_PORT, function (buf) {
    this.emit('code', buf);
  }]);
}

function check_port(port, callback) {
  /* jshint validthis: true */
  var ptrs_buf = buffer.Buffer(emcc_tools.PTR_SIZE * 2);
  ptrs_buf.fill(0);
  var ptrs = emcc_tools.buffer_to_ptr(ndl3, ptrs_buf);
  call('NDL3_recv', this.net, port, ptrs, ptrs + emcc_tools.PTR_SIZE);
  var msg_ptr = emcc_tools.get_ptr(ndl3, ptrs);
  var size = emcc_tools.get_ptr(ndl3, ptrs + emcc_tools.PTR_SIZE);
  call('free', ptrs);
  if (emcc_tools.get_ptr(ndl3, ptrs) !== 0) {
    var buf = emcc_tools.ptr_to_buffer(ndl3, msg_ptr, size);
    callback.apply(this, [buf]);
  }
  throw_on_NDL3_error(this.net);
}

function throw_on_NDL3_error(net) {
  var err = call('NDL3_pop_error', net);
  if (err !== 0) {
    if (exports.RADIO_DEBUG) {
      throw 'Error number ' + err + ' in NDL3.';
    }
  }
}

Radio.prototype.send = function(data, type) {
  if (type === undefined) {
    type = 'object';
  }
  this.emit('send_' + type, data);
};

function send_object(object) {
  /* jshint validthis: true */
  var buf = ubjson.encode(object);
  send(this.net, UBJSON_PORT, buf);
}

function send_string(string) {
  /* jshint validthis: true */
  send(this.net, STRING_PORT, buffer.Buffer(string));
}

function send_code(buf) {
  /* jshint validthis: true */
  if (typeof buf === 'string') {
    buf = buffer.Buffer(buf);
  }
  send(this.net, CODE_PORT, buf);
}

function send(net, port, buf, length) {
  if (length === undefined) {
    length = buf.length;
  }
  var ptr = emcc_tools.buffer_to_ptr(ndl3, buf, length);
  call('NDL3_send', net, port, ptr, length);
}

function send_data(data) {
  /* jshint validthis: true */
  this.serportObj.write(data);
}

Radio.prototype.close = function() {
  call('NDL3_close', this.net, UBJSON_PORT);
  call('NDL3_close', this.net, STRING_PORT);
  call('NDL3_close', this.net, CODE_PORT);
  call('free', this.net);
  // TODO(kzentner): NDL3 provides no way of deleteing a transport.
  clearInterval(this._tick);
  if (this.connected) {
    this.disconnectXBee();
  }
};

exports.Radio = Radio;
<commit_msg>Fix radio.js disconnectXBee.<commit_after>/* jshint globalstrict: true */
"use strict";

var EventEmitter = require('./EventEmitter');
var ubjson = require('./ubjson');
var buffer = require('buffer');
var emcc_tools = require('./emcc_tools');
var xbee = require('./xbee');
var typpo = require('./typpo');

// 1 byte lost to the PiEMOS framing.
var MAX_XBEE_PAYLOAD_SIZE = 100 - 1;
var SEND_INTERVAL = 100;

var UBJSON_PORT = typpo.get_const('NDL3_UBJSON_PORT');
var STRING_PORT = typpo.get_const('NDL3_STRING_PORT');
var CODE_PORT = typpo.get_const('NDL3_CODE_PORT');

exports.RADIO_DEBUG = false;

try {
  var ndl3 = require('./ndl3');
} catch (_) {
  console.warn('Could not load ndl3.js. Did you run build.sh?');
}

function call(name) {
  var args = Array.prototype.slice.call(arguments, 1);
  var arg_ts = [];
  for (var i = 0; i < args.length; i++) {
    arg_ts.push('number');
  }
  return ndl3.ccall(name, 'number', arg_ts, args);
}

var Radio = function(address, serportObj) {
  EventEmitter.apply(this);
  this.connected = false;
  this._accumulator = null;
  this.net = call('NDL3_new', 0, 0, 0);
  if (this.net === 0) {
    throw 'Could not allocate NDL3.';
  }
  call('NDL3_open', this.net, UBJSON_PORT);
  call('NDL3_open', this.net, STRING_PORT);
  call('NDL3_open', this.net, CODE_PORT);

  this._tick = send_L2.bind(this);
  setInterval(this._tick, SEND_INTERVAL);

  this.on('send_object', send_object.bind(this));
  this.on('send_string', send_string.bind(this));
  this.on('send_code', send_code.bind(this));
  this.on('data', recv_L2.bind(this));

  if (address !== undefined &&
      serportObj !== undefined) {
    this.connectXBee(address, serportObj);
  } else {
    this.address = null;
    this.serportObj = null;
  }
  this._send_data = send_data.bind(this);

  if (exports.RADIO_DEBUG) {
    // Print out every message in or out of the radio, for debugging
    // purposes.
    var events = ['data', 'object', 'string', 'code'];
    for (var e = 0; e < events.length; e++) {
      var evt = events[e];
      this.on(evt, make_evt_callback(evt));
      this.on('send_' + evt, make_evt_callback('send_' + evt));
    }
  }
};

function make_evt_callback(evt) {
  return function (data) {
    console.log('radio: ', evt, ':', data);
  };
}

Radio.prototype = Object.create(EventEmitter.prototype);

Radio.prototype.isConnected = function () {
  return this.connected;
};

Radio.prototype.connectXBee = function (address, serportObj) {
  if (this.connected) {
    throw 'XBee has already been connected to radio.';
  }
  this.address = address;
  this.serportObj = serportObj;
  this._read_handler = read_handler.bind(this);
  this._accumulator = new xbee.Accumulator(serportObj);
  this._accumulator.on('data', this._read_handler);
  this._send_data = send_data.bind(this);
  this.on('send_data', this._send_data);
};

Radio.prototype.disconnectXBee = function () {
  this.off('send_data', this._send_data);
  this._accumulator.off('data', this._read_handler);
  this._accumulator.destroy();
  this._accumulator = null;
  this.address = null;
  this.serportObj = null;
  this.off('send_data', this._send_data);
};

function send_L2 () {
  /* jshint validthis: true */
  var out_size_ptr = call('malloc', emcc_tools.PTR_SIZE);
  var send_block = call('malloc', MAX_XBEE_PAYLOAD_SIZE);
  if (out_size_ptr === 0 || send_block === 0) {
    throw 'malloc failed';
  }

  emcc_tools.set_ptr(ndl3, out_size_ptr, 0);

  call('NDL3_elapse_time', this.net, SEND_INTERVAL);
  call('NDL3_L2_pop', this.net, send_block, MAX_XBEE_PAYLOAD_SIZE, out_size_ptr);
  var length = emcc_tools.get_ptr(ndl3, out_size_ptr);
  // 1 + makes room for ident byte.
  var send_buf = buffer.Buffer(1 + length);
  send_buf[0] = typpo.get_const('NDL3_IDENT');
  emcc_tools.ptr_to_buffer(ndl3, send_block, length, send_buf, 1);
  call('free', out_size_ptr);
  call('free', send_block);
  var xbee_packet = xbee.createPacket(send_buf, this.address);
  this.emit('send_data', xbee_packet);
  throw_on_NDL3_error(this.net);
}

function read_handler(data) {
  /* jshint validthis: true */
  this.emit('data', data);
}

function recv_L2 (rxbuf) {
  /* jshint validthis: true */
  // We need to extract the payload from the xbee packet.
  var data = xbee.extractPayload(rxbuf);
  if (data[0] !== typpo.get_const('NDL3_IDENT')) {
    // Not an NDL3 packet.
    return;
  } else {
    // Remove the framing.
    data = data.slice(1);
  }
  var ptr = emcc_tools.buffer_to_ptr(ndl3, data);
  call('NDL3_L2_push', this.net, ptr, data.length);
  call('free', ptr);

  check_L3.apply(this);
  // Ignore errors due to bad packets.
  call('NDL3_pop_error', this.net);
}

function check_L3() {
  /* jshint validthis: true */
  check_port.apply(this, [UBJSON_PORT, function (buf) {
    /* jshint validthis: true */
    this.emit('object', ubjson.decode(buf));
  }]);
  check_port.apply(this, [STRING_PORT, function (buf) {
    this.emit('string', buf.toString());
  }]);
  check_port.apply(this, [CODE_PORT, function (buf) {
    this.emit('code', buf);
  }]);
}

function check_port(port, callback) {
  /* jshint validthis: true */
  var ptrs_buf = buffer.Buffer(emcc_tools.PTR_SIZE * 2);
  ptrs_buf.fill(0);
  var ptrs = emcc_tools.buffer_to_ptr(ndl3, ptrs_buf);
  call('NDL3_recv', this.net, port, ptrs, ptrs + emcc_tools.PTR_SIZE);
  var msg_ptr = emcc_tools.get_ptr(ndl3, ptrs);
  var size = emcc_tools.get_ptr(ndl3, ptrs + emcc_tools.PTR_SIZE);
  call('free', ptrs);
  if (emcc_tools.get_ptr(ndl3, ptrs) !== 0) {
    var buf = emcc_tools.ptr_to_buffer(ndl3, msg_ptr, size);
    callback.apply(this, [buf]);
  }
  throw_on_NDL3_error(this.net);
}

function throw_on_NDL3_error(net) {
  var err = call('NDL3_pop_error', net);
  if (err !== 0) {
    if (exports.RADIO_DEBUG) {
      throw 'Error number ' + err + ' in NDL3.';
    }
  }
}

Radio.prototype.send = function(data, type) {
  if (type === undefined) {
    type = 'object';
  }
  this.emit('send_' + type, data);
};

function send_object(object) {
  /* jshint validthis: true */
  var buf = ubjson.encode(object);
  send(this.net, UBJSON_PORT, buf);
}

function send_string(string) {
  /* jshint validthis: true */
  send(this.net, STRING_PORT, buffer.Buffer(string));
}

function send_code(buf) {
  /* jshint validthis: true */
  if (typeof buf === 'string') {
    buf = buffer.Buffer(buf);
  }
  send(this.net, CODE_PORT, buf);
}

function send(net, port, buf, length) {
  if (length === undefined) {
    length = buf.length;
  }
  var ptr = emcc_tools.buffer_to_ptr(ndl3, buf, length);
  call('NDL3_send', net, port, ptr, length);
}

function send_data(data) {
  /* jshint validthis: true */
  this.serportObj.write(data);
}

Radio.prototype.close = function() {
  call('NDL3_close', this.net, UBJSON_PORT);
  call('NDL3_close', this.net, STRING_PORT);
  call('NDL3_close', this.net, CODE_PORT);
  call('free', this.net);
  // TODO(kzentner): NDL3 provides no way of deleteing a transport.
  clearInterval(this._tick);
  if (this.connected) {
    this.disconnectXBee();
  }
};

exports.Radio = Radio;
<|endoftext|>


<commit_before>const path = require('path');
const fs = require('fs');

function fileValues(file, classification) {
  const format = ['chrome', 'firefox'].indexOf(classification) >= 0 ? ['br', 'gzip'] : ['gzip'];
  let returnValue = {
    finalFormat: null,
    finalFile: file
  };

  format.some((formatValue) => {
    const testFile = file.replace('.js', `.js.${formatValue}`);
    if (fs.existsSync(path.resolve('dist', classification, testFile))) {
      returnValue = {
        finalFormat: formatValue,
        finalFile: testFile
      };
      return true;
    }
    return false;
  });

  return returnValue;
}

function staticRoute(req, res, next) {
  const {classification, file} = req.params;

  if (['chrome', 'safari', 'firefox', 'edge', 'fallback'].indexOf(classification) >= 0) {
    const {finalFormat, finalFile} = fileValues(file, classification);

    fs.readFile(path.resolve('dist', classification, finalFile), 'binary', function(err, data) {
      res.writeHead(200, Object.assign({
        'Content-Type': 'text/javascript',
        'Cache-Control': 'public,max-age=31536000,immutable',
        'Timing-Allow-Origin': '*',
        'Access-Control-Allow-Credentials': 'true',
        'Access-Control-Allow-Origin': '*'
      }, finalFormat ? {'Content-Encoding': finalFormat} : {}));

      res.end(data, 'binary');
      next();
    });
  } else {
    res.writeHead(404);

    res.end();
    next();
  }
}

module.exports = staticRoute;<commit_msg>Attempt to make static route more easily modifyable.<commit_after>const path = require('path');
const fs = require('fs');

function fileValues(file, classification) {
  const format = ['chrome', 'firefox'].indexOf(classification) >= 0 ? ['br', 'gzip'] : ['gzip'];
  let returnValue = {
    finalFormat: null,
    finalFile: file
  };

  format.some((formatValue) => {
    const testFile = file.replace('.js', `.js.${formatValue}`);
    if (fs.existsSync(path.resolve('dist', classification, testFile))) {
      returnValue = {
        finalFormat: formatValue,
        finalFile: testFile
      };
      return true;
    }
    return false;
  });

  return returnValue;
}

function staticRoute(req, res, next) {
  const {classification, file} = req.params;

  if (['chrome', 'safari', 'firefox', 'edge', 'fallback'].indexOf(classification) >= 0) {
    const {finalFormat, finalFile} = fileValues(file, classification);
    const resolvedPath = path.resolve('dist', classification, finalFile);
    let stream = fs.createReadStream(resolvedPath);

    stream.on('error', (error) => {
      res.writeHead(404, {
        'Content-Type': 'text/plain'
      });

      res.end("file not found");
      req.log.warn(`${resolvedPath} file not found.`);
      next();
    });
    stream.on('open', () => {
      res.writeHead(200, {
        'Content-Type': 'text/javascript',
        'Cache-Control': 'public,max-age=31536000,immutable',
        'Timing-Allow-Origin': '*',
        'Access-Control-Allow-Credentials': 'true',
        'Access-Control-Allow-Origin': '*',
        'Content-Encoding': finalFormat
      });
      stream.pipe(res);
    });
    stream.on('end', () => {
      req.log.info(`${resolvedPath} file delivered.`);
      next();
    });
  } else {
    res.writeHead(404, {
      'Content-Type': 'text/plain'
    });

    res.end("file not found");
    req.log.warn(`${resolvedPath} file not found.`);
    next();
  }
}

module.exports = staticRoute;<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

describe('LocalDatabase', function() {

    var LocalDatabase, pouchDb, database, $rootScope, dbResponded;

    beforeEach(function() {
        module('openlmis-database', function($provide, PouchDB) {
            var originalPouchDB = PouchDB;

            $provide.constant('PouchDB', function(name) {
                pouchDb = new originalPouchDB(name);
                return pouchDb;
            });
        });

        inject(function($injector) {
            LocalDatabase = $injector.get('LocalDatabase');
            $rootScope = $injector.get('$rootScope');
        });

        database = new LocalDatabase('testDatabase');
        dbResponded = false;
    });

    describe('put', function() {

        it('should throw exception if object is undefined', function() {
            expect(function() {
                database.put();
            }).toThrow('Object must be defined!');

            expect(function() {
                database.put(null);
            }).toThrow('Object must be defined!');

            expect(function() {
                database.put(undefined);
            }).toThrow('Object must be defined!');
        });

        it('should throw exception if object does not have ID', function() {
            expect(function() {
                database.put({});
            }).toThrow('Object must have ID!');
        });

        it('should copy the id of the object to _id', function() {
            var success;

            runs(function() {
                database.put({
                    id: 'some-id'
                })
                    .then(function() {
                        return pouchDb.get('some-id');
                    })
                    .then(function(object) {
                        expect(object).not.toBeUndefined();
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });

                $rootScope.$apply();
            });

            waitsFor(function() {
                $rootScope.$apply();
                return dbResponded;
            }, 'The database should have responded', 500);

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should update existing object with the same id', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    id: 'some-id',
                    _id: 'some-id',
                    field: 'value'
                })
                    .then(function() {
                        return database.put({
                            id: 'some-id',
                            field: 'updated value'
                        });
                    })
                    .then(function() {
                        return pouchDb.get('some-id');
                    })
                    .then(function(updated) {
                        expect(updated.id).toEqual('some-id');
                        expect(updated.field).toEqual('updated value');
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should save the object if an object with the given id is not stored yet', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    id: 'some-id-one',
                    _id: 'some-id-one'
                })
                    .then(function() {
                        return pouchDb.put({
                            id: 'some-id-two',
                            _id: 'some-id-two'
                        });
                    })
                    .then(function() {
                        return pouchDb.put({
                            id: 'some-id-three',
                            _id: 'some-id-three'
                        });
                    })
                    .then(function() {
                        return database.put({
                            id: 'some-other-id'
                        });
                    })
                    .then(function() {
                        return pouchDb.allDocs();
                    })
                    .then(function(response) {
                        expect(response.total_rows).toBe(4);
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should save multiple object with different ID', function() {
            var success;

            runs(function() {
                return database.put({
                    id: 'some-id-one'
                })
                    .then(function() {
                        return database.put({
                            id: 'some-id-two'
                        });
                    })
                    .then(function() {
                        return database.put({
                            id: 'some-id-three'
                        });
                    })
                    .then(function() {
                        return pouchDb.allDocs();
                    })
                    .then(function(response) {
                        expect(response.total_rows).toBe(3);
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

    });

    describe('get', function() {

        it('should throw exception if ID is not given', function() {
            expect(function() {
                database.get();
            }).toThrow('ID must be defined!');

            expect(function() {
                database.get(null);
            }).toThrow('ID must be defined!');

            expect(function() {
                database.get(undefined);
            }).toThrow('ID must be defined!');
        });

        it('should resolve promise if object exists', function() {
            var success, _rev;

            runs(function() {
                pouchDb.put({
                    _id: 'some-id',
                    id: 'some-id'
                })
                    .then(function(response) {
                        _rev = response.rev;
                        return database.get('some-id');
                    })
                    .then(function(stored) {
                        expect(stored).toEqual({
                            id: 'some-id',
                            _id: 'some-id',
                            _rev: _rev
                        });
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should reject promise if object does not exist', function() {
            var error;

            runs(function() {
                database.get('some-id')
                    .then(function() {
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                        error = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(error).toBe(true);
            });
        });

    });

    describe('remove', function() {

        it('should throw exception if ID is not given', function() {
            expect(function() {
                database.remove();
            }).toThrow('ID must be defined!');

            expect(function() {
                database.remove(null);
            }).toThrow('ID must be defined!');

            expect(function() {
                database.remove(undefined);
            }).toThrow('ID must be defined!');
        });

        it('should resolve promise if doc was removed', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    _id: 'some-id',
                    id: 'some-id'
                })
                    .then(function() {
                        return database.remove('some-id');
                    })
                    .then(function() {
                        return pouchDb.allDocs();
                    })
                    .then(function(response) {
                        expect(response.total_rows).toEqual(0);
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should reject promise if doc with the given ID does not exist', function() {
            var error;

            runs(function() {
                database.remove('some-id')
                    .then(function() {
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                        error = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(error).toBe(true);
            });
        });

    });

    describe('getAll', function() {

        it('should return list of all docs', function() {
            var success, putDocs = [];

            runs(function() {
                pouchDb.put({
                    _id: 'one',
                    id: 'one'
                })
                    .then(function(doc) {
                        putDocs.push({
                            id: 'one',
                            _id: 'one',
                            _rev: doc.rev
                        });
                        return pouchDb.put({
                            _id: 'two',
                            id: 'two'
                        });
                    })
                    .then(function(doc) {
                        putDocs.push({
                            id: 'two',
                            _id: 'two',
                            _rev: doc.rev
                        });
                        return pouchDb.put({
                            _id: 'three',
                            id: 'three'
                        });
                    })
                    .then(function(doc) {
                        putDocs.push({
                            id: 'three',
                            _id: 'three',
                            _rev: doc.rev
                        });
                        return database.getAll();
                    })
                    .then(function(docs) {
                        expect(docs.length).toBe(3);
                        angular.forEach(putDocs, function(putDoc) {
                            var contains = false;
                            angular.forEach(docs, function(doc) {
                                contains = angular.equals(putDoc, doc) || contains;
                            });

                            expect(contains).toBe(true);
                        });
                        success = true;
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should return empty list if database is empty', function() {
            var success;

            runs(function() {
                database.getAll()
                    .then(function(docs) {
                        expect(docs).toEqual([]);
                        success = true;
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

    });

    describe('removeAll', function() {

        it('should remove all entries', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    _id: 'one',
                    id: 'one'
                })
                    .then(function() {
                        return pouchDb.put({
                            _id: 'two',
                            id: 'two'
                        });
                    })
                    .then(function() {
                        return pouchDb.put({
                            _id: 'three',
                            id: 'three'
                        });
                    })
                    .then(function() {
                        return database.removeAll();
                    })
                    .then(function() {
                        return database.getAll();
                    })
                    .then(function(docs) {
                        expect(docs.length).toBe(0);
                        success = true;
                        dbResponded = true;
                    })
                    .catch(function(error) {
                        console.log(error);
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

    });

    afterEach(function() {
        var dbDestroyed;

        runs(function() {
            pouchDb.destroy().then(function() {
                dbDestroyed = true;
            });
        });

        waitsFor(function() {
            return dbDestroyed;
        }, 'The database should be destroyed', 1000);

    });

    function waitForDb() {
        waitsFor(function() {
            $rootScope.$apply();
            return dbResponded;
        }, 'The database should have responded', 1000);
    }

});<commit_msg>OLMIS-5390: Increased wait time in LocalDatabase tests<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

describe('LocalDatabase', function() {

    var LocalDatabase, pouchDb, database, $rootScope, dbResponded;

    beforeEach(function() {
        module('openlmis-database', function($provide, PouchDB) {
            var originalPouchDB = PouchDB;

            $provide.constant('PouchDB', function(name) {
                pouchDb = new originalPouchDB(name);
                return pouchDb;
            });
        });

        inject(function($injector) {
            LocalDatabase = $injector.get('LocalDatabase');
            $rootScope = $injector.get('$rootScope');
        });

        database = new LocalDatabase('testDatabase');
        dbResponded = false;
    });

    describe('put', function() {

        it('should throw exception if object is undefined', function() {
            expect(function() {
                database.put();
            }).toThrow('Object must be defined!');

            expect(function() {
                database.put(null);
            }).toThrow('Object must be defined!');

            expect(function() {
                database.put(undefined);
            }).toThrow('Object must be defined!');
        });

        it('should throw exception if object does not have ID', function() {
            expect(function() {
                database.put({});
            }).toThrow('Object must have ID!');
        });

        it('should copy the id of the object to _id', function() {
            var success;

            runs(function() {
                database.put({
                    id: 'some-id'
                })
                    .then(function() {
                        return pouchDb.get('some-id');
                    })
                    .then(function(object) {
                        expect(object).not.toBeUndefined();
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });

                $rootScope.$apply();
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should update existing object with the same id', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    id: 'some-id',
                    _id: 'some-id',
                    field: 'value'
                })
                    .then(function() {
                        return database.put({
                            id: 'some-id',
                            field: 'updated value'
                        });
                    })
                    .then(function() {
                        return pouchDb.get('some-id');
                    })
                    .then(function(updated) {
                        expect(updated.id).toEqual('some-id');
                        expect(updated.field).toEqual('updated value');
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should save the object if an object with the given id is not stored yet', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    id: 'some-id-one',
                    _id: 'some-id-one'
                })
                    .then(function() {
                        return pouchDb.put({
                            id: 'some-id-two',
                            _id: 'some-id-two'
                        });
                    })
                    .then(function() {
                        return pouchDb.put({
                            id: 'some-id-three',
                            _id: 'some-id-three'
                        });
                    })
                    .then(function() {
                        return database.put({
                            id: 'some-other-id'
                        });
                    })
                    .then(function() {
                        return pouchDb.allDocs();
                    })
                    .then(function(response) {
                        expect(response.total_rows).toBe(4);
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should save multiple object with different ID', function() {
            var success;

            runs(function() {
                return database.put({
                    id: 'some-id-one'
                })
                    .then(function() {
                        return database.put({
                            id: 'some-id-two'
                        });
                    })
                    .then(function() {
                        return database.put({
                            id: 'some-id-three'
                        });
                    })
                    .then(function() {
                        return pouchDb.allDocs();
                    })
                    .then(function(response) {
                        expect(response.total_rows).toBe(3);
                    })
                    .then(function() {
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

    });

    describe('get', function() {

        it('should throw exception if ID is not given', function() {
            expect(function() {
                database.get();
            }).toThrow('ID must be defined!');

            expect(function() {
                database.get(null);
            }).toThrow('ID must be defined!');

            expect(function() {
                database.get(undefined);
            }).toThrow('ID must be defined!');
        });

        it('should resolve promise if object exists', function() {
            var success, _rev;

            runs(function() {
                pouchDb.put({
                    _id: 'some-id',
                    id: 'some-id'
                })
                    .then(function(response) {
                        _rev = response.rev;
                        return database.get('some-id');
                    })
                    .then(function(stored) {
                        expect(stored).toEqual({
                            id: 'some-id',
                            _id: 'some-id',
                            _rev: _rev
                        });
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should reject promise if object does not exist', function() {
            var error;

            runs(function() {
                database.get('some-id')
                    .then(function() {
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                        error = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(error).toBe(true);
            });
        });

    });

    describe('remove', function() {

        it('should throw exception if ID is not given', function() {
            expect(function() {
                database.remove();
            }).toThrow('ID must be defined!');

            expect(function() {
                database.remove(null);
            }).toThrow('ID must be defined!');

            expect(function() {
                database.remove(undefined);
            }).toThrow('ID must be defined!');
        });

        it('should resolve promise if doc was removed', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    _id: 'some-id',
                    id: 'some-id'
                })
                    .then(function() {
                        return database.remove('some-id');
                    })
                    .then(function() {
                        return pouchDb.allDocs();
                    })
                    .then(function(response) {
                        expect(response.total_rows).toEqual(0);
                        dbResponded = true;
                        success = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should reject promise if doc with the given ID does not exist', function() {
            var error;

            runs(function() {
                database.remove('some-id')
                    .then(function() {
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                        error = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(error).toBe(true);
            });
        });

    });

    describe('getAll', function() {

        it('should return list of all docs', function() {
            var success, putDocs = [];

            runs(function() {
                pouchDb.put({
                    _id: 'one',
                    id: 'one'
                })
                    .then(function(doc) {
                        putDocs.push({
                            id: 'one',
                            _id: 'one',
                            _rev: doc.rev
                        });
                        return pouchDb.put({
                            _id: 'two',
                            id: 'two'
                        });
                    })
                    .then(function(doc) {
                        putDocs.push({
                            id: 'two',
                            _id: 'two',
                            _rev: doc.rev
                        });
                        return pouchDb.put({
                            _id: 'three',
                            id: 'three'
                        });
                    })
                    .then(function(doc) {
                        putDocs.push({
                            id: 'three',
                            _id: 'three',
                            _rev: doc.rev
                        });
                        return database.getAll();
                    })
                    .then(function(docs) {
                        expect(docs.length).toBe(3);
                        angular.forEach(putDocs, function(putDoc) {
                            var contains = false;
                            angular.forEach(docs, function(doc) {
                                contains = angular.equals(putDoc, doc) || contains;
                            });

                            expect(contains).toBe(true);
                        });
                        success = true;
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

        it('should return empty list if database is empty', function() {
            var success;

            runs(function() {
                database.getAll()
                    .then(function(docs) {
                        expect(docs).toEqual([]);
                        success = true;
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

    });

    describe('removeAll', function() {

        it('should remove all entries', function() {
            var success;

            runs(function() {
                pouchDb.put({
                    _id: 'one',
                    id: 'one'
                })
                    .then(function() {
                        return pouchDb.put({
                            _id: 'two',
                            id: 'two'
                        });
                    })
                    .then(function() {
                        return pouchDb.put({
                            _id: 'three',
                            id: 'three'
                        });
                    })
                    .then(function() {
                        return database.removeAll();
                    })
                    .then(function() {
                        return database.getAll();
                    })
                    .then(function(docs) {
                        expect(docs.length).toBe(0);
                        success = true;
                        dbResponded = true;
                    })
                    .catch(function() {
                        dbResponded = true;
                    });
            });

            waitForDb();

            runs(function() {
                expect(success).toBe(true);
            });
        });

    });

    afterEach(function() {
        var dbDestroyed;

        runs(function() {
            pouchDb.destroy().then(function() {
                dbDestroyed = true;
            });
        });

        waitsFor(function() {
            return dbDestroyed;
        }, 'The database should be destroyed', 5000);

    });

    function waitForDb() {
        waitsFor(function() {
            $rootScope.$apply();
            return dbResponded;
        }, 'The database should have responded', 5000);
    }

});<|endoftext|>


<commit_before>/**
 * Props params:
 *
 * playCallback:    Function to be called with response from server. should take one parameter.
 * calc:            Only used when testing hardware.
 * postURL:         The url after the globally set url.
 * formDataBuilder  Function to create formdata containing information to send. Function takes:.
 *                                                                                video(blob) as first param
 *                                                                                filename as second param.
 * recButtonID:     [Optional] Button to start recording video. If left out it autorecords on render.
 * stopButtonID:    Id of the button to stop recording video. Might post video as well(read about postButtonID).
 * postButtonID:    [Optional] Id of the post video button. If left out the stop button posts the video to server.
 * replay:          replay="true" if you want the recording to be playable in the same video tag.
 * fileName:        The name the video recording should have.
 * camOnLoad:       camOnLoad="true" If the camera is to start before recording. User will have to click
 *                  stopbutton to be able to reuse camera.
 * autoRecord:      autoRecord="true" if the camera should start recording when class is instantiated.
 *
 *
 * watch HardwareTest.js for example of use.
 */

var Recorder = React.createClass({
    componentDidMount: function() {
        var props = this.props;

        //used for hw testing
        var blobsize;
        var sendTime;

        var cameraStartOnLoad = (typeof props.camOnLoad === "undefined") ?
                        false : props.camOnLoad == "true";
        var cameraStarted = false;
        var startRecordButtonExists = (typeof props.recButtonID !== "undefined");
        var shouldAutoRecord = (typeof props.autoRecord === "undefined") ?
                        !startRecordButtonExists : props.autoRecord == "true";

        var replay = props.replay == "true";
        var stopButton = document.getElementById(props.stopButtonID);
        var previewElement;
        var recordAudio, recordVideo;
        var mediaStream;

        if(startRecordButtonExists) {
            var recordButton = document.getElementById(props.recButtonID);
            if(cameraStarted) {
                recordButton.disabled = true;
            }
        }

        if(typeof props.calc !== "undefined")
            previewElement = document.getElementById('prev-test');
        else
            previewElement = document.getElementById('preview');

        navigator.getUserMedia = ( navigator.getUserMedia ||
                                  navigator.webkitGetUserMedia ||
        navigator.mediaDevices.getUserMedia ||
                                  navigator.msGetUserMedia);

        if(cameraStartOnLoad) {
            startCamera();
        }

        /* The onclick function for the start record button if it exists. */
        if(startRecordButtonExists) {
            recordButton.onclick = startRecord;
        }

        /* The onclick function for the stop record button. */
        stopButton.onclick = stopRecording;

        /* Will start recording and start the webcam if not enabled. */
        function startRecord() {
            if(!cameraStarted) {
                startCamera();
                window.setTimeout(function() {
                    recordAudio.startRecording();
                    recordingStarted();
                }, 1000);
            } else {
                recordAudio.startRecording();
                recordingStarted();
            }
        }

        function recordingStarted() {
            if(startRecordButtonExists) {
                recordButton.disabled = true;
            }
            stopButton.disabled = false;

            if(typeof props.calc !== "undefined") {
                document.getElementById("test-rec-text").innerHTML = "🔴";
            }
            else {
                document.getElementById("rec-text").innerHTML = "🔴";
            }
        }

        /* Start stream from webcam and start recording if autoRecording is true,
         * will record with forced low settings for smaller files. */
        function startCamera () {
            navigator.getUserMedia({
                audio: true,
                video: {
                    mandatory: {
                        minWidth: 160,
                        maxWidth: 320,
                        minHeight: 120,
                        maxHeight: 240,
                        minFrameRate: 5,
                        maxFrameRate: 10
                    }
                }
            }, function (stream) {
                mediaStream = stream;
                previewElement.src = window.URL.createObjectURL(mediaStream);
                previewElement.removeAttribute("controls");
                previewElement.setAttribute("muted", "muted");
                window.setTimeout(function() { previewElement.play(); }, 200);

                recordAudio = RecordRTC(mediaStream, {
                    onAudioProcessStarted: function () {
                        recordVideo.startRecording();
                    }
                });

                recordVideo = RecordRTC(mediaStream, {
                    type: 'video'
                });

                if(startRecordButtonExists && cameraStartOnLoad) {
                    recordButton.disabled = false;
                }

                if(shouldAutoRecord) {
                    startRecord();
                }
                cameraStarted = true;
            }, function (error) {
                alert("Problem occured, make sure camera is not\nused elsewhere and that you are connected\nby https.");
            });
        }

        /* Closes the webcam stream and post to server if auto recording is on. */
        function stopRecording() {
            if(!shouldAutoRecord){
                recordButton.disabled = false;
            }

            stopButton.disabled = true;

            previewElement.src = '';

            var postbutton = null;
            if (typeof props.postButtonID !== "undefined") {
                postbutton = document.getElementById(props.postButtonID);
            }

            recordVideo.stopRecording(function (url) {
                if(replay) {
                    previewElement.src = url;
                    previewElement.setAttribute("controls","controls");
                    previewElement.removeAttribute("muted");
                }

                if(postbutton == null) {
                    if(props.siteView !== null) {
                        PostBlob(recordVideo.getBlob(), props.siteView);
                    } else {
                        PostBlob(recordVideo.getBlob());
                    }
                }
                else {
                    previewElement.src = url;
                    previewElement.setAttribute("controls","controls");
                    previewElement.removeAttribute("muted");
                    postbutton.disabled = false;
                    postbutton.onclick = function () {
                        if(props.siteView !== null) {
                            PostBlob(recordVideo.getBlob(), props.siteView);
                        } else {
                            PostBlob(recordVideo.getBlob());
                        }
                    }
                }
                mediaStream.stop();
                mediaStream = null;
                if(typeof props.calc !== "undefined") {
                    document.getElementById("test-rec-text").innerHTML = "⭕";
                }
                else {
                    document.getElementById("rec-text").innerHTML = "⭕";
                }
                cameraStarted = false;
            });
            var hasModal = document.getElementById("assignment-modal");
            if (hasModal !== null) {
                hasModal.style.display = 'none';
            }
        }

        /* Post to the server */
        function PostBlob(blob, siteView) {
            // FormData - data to be sent to the server
            var formData = props.formDataBuilder(blob,props.fileName);

            //used for hw testing
            if(typeof props.calc !== "undefined") {
              blobsize = blob.size / 1048576;
              sendTime = Date.now();
            }

            //call xhr with full url, data and callback function
            xhr(props.postURL, formData, props.playCallback);
        }

        /* Function for sending XMLHttpRequests. */
        function xhr(url, data, callback) {
            var request = new XMLHttpRequest();
            request.onreadystatechange = function () {
                if (request.readyState == 4 && request.status == 200) {
                    callback(request.responseText);
                } else if(request.readyState == 4 && request.status !== 200) {
                    alert(request.responseText);
                }
            };

            if(typeof props.calc !== "undefined") {
                request.upload.onloadstart = function () {
                    $("#internet-speed").text("Uploading...");
                }
                request.onloadstart = function () {
                    $("#internet-speed").text("Uploading...");
                }
            }
            request.onload = function(){
                if(typeof props.calc !== "undefined") {
                    if(request.status == 404)
                        $("#internet-speed").text("Upload failed, no server connection.");
                    else if(request.status == 408)
                        $("#internet-speed").text("Connection timed out.");
                    else
                        props.calc(blobsize,sendTime);
                }
                else if(request.status == 404) {
                    alert("Upload failed, no server connection.");
                }
                else if(request.status == 408) {
                    alert("Connection timed out.");
                }
            }

            request.open('POST', url,true);
            request.send(data);
        }

        /* Showing recording-light on load (not recording) */

        if(typeof props.calc !== "undefined") {
            document.getElementById("test-rec-text").innerHTML = "⭕";
        }
        else {
            document.getElementById("rec-text").innerHTML = "⭕";
        }
    },
    render: function() {
        var id;
        var pId;
        var contId;
        if(typeof this.props.contID === "undefined"){
            contId = "prev-container";
        }
        else {
            contId = this.prop.contID;
        }
        if(typeof this.props.calc !== "undefined") {
            id="prev-test";
            pId="test-rec-text";

        }
        else {
            id="preview";
            pId="rec-text";

        }

        return (

                    <video id={id} muted ></video>

        );
    }
});

window.Recorder = Recorder;<commit_msg>adds error texts<commit_after>/**
 * Props params:
 *
 * playCallback:    Function to be called with response from server. should take one parameter.
 * calc:            Only used when testing hardware.
 * postURL:         The url after the globally set url.
 * formDataBuilder  Function to create formdata containing information to send. Function takes:.
 *                                                                                video(blob) as first param
 *                                                                                filename as second param.
 * recButtonID:     [Optional] Button to start recording video. If left out it autorecords on render.
 * stopButtonID:    Id of the button to stop recording video. Might post video as well(read about postButtonID).
 * postButtonID:    [Optional] Id of the post video button. If left out the stop button posts the video to server.
 * replay:          replay="true" if you want the recording to be playable in the same video tag.
 * fileName:        The name the video recording should have.
 * camOnLoad:       camOnLoad="true" If the camera is to start before recording. User will have to click
 *                  stopbutton to be able to reuse camera.
 * autoRecord:      autoRecord="true" if the camera should start recording when class is instantiated.
 *
 *
 * watch HardwareTest.js for example of use.
 */

var Recorder = React.createClass({
    componentDidMount: function() {
        var props = this.props;

        //used for hw testing
        var blobsize;
        var sendTime;

        var cameraStartOnLoad = (typeof props.camOnLoad === "undefined") ?
                        false : props.camOnLoad == "true";
        var cameraStarted = false;
        var startRecordButtonExists = (typeof props.recButtonID !== "undefined");
        var shouldAutoRecord = (typeof props.autoRecord === "undefined") ?
                        !startRecordButtonExists : props.autoRecord == "true";

        var replay = props.replay == "true";
        var stopButton = document.getElementById(props.stopButtonID);
        var previewElement;
        var recordAudio, recordVideo;
        var mediaStream;

        if(startRecordButtonExists) {
            var recordButton = document.getElementById(props.recButtonID);
            if(cameraStarted) {
                recordButton.disabled = true;
            }
        }

        if(typeof props.calc !== "undefined")
            previewElement = document.getElementById('prev-test');
        else
            previewElement = document.getElementById('preview');

        navigator.getUserMedia = ( navigator.getUserMedia ||
                                  navigator.webkitGetUserMedia ||
        navigator.mediaDevices.getUserMedia ||
                                  navigator.msGetUserMedia);

        if(cameraStartOnLoad) {
            startCamera();
        }

        /* The onclick function for the start record button if it exists. */
        if(startRecordButtonExists) {
            recordButton.onclick = startRecord;
        }

        /* The onclick function for the stop record button. */
        stopButton.onclick = stopRecording;

        /* Will start recording and start the webcam if not enabled. */
        function startRecord() {
            if(!cameraStarted) {
                startCamera();
                window.setTimeout(function() {
                    recordAudio.startRecording();
                    recordingStarted();
                }, 1000);
            } else {
                recordAudio.startRecording();
                recordingStarted();
            }
        }

        function recordingStarted() {
            if(startRecordButtonExists) {
                recordButton.disabled = true;
            }
            stopButton.disabled = false;

            if(typeof props.calc !== "undefined") {
                document.getElementById("test-rec-text").innerHTML = "🔴";
            }
            else {
                document.getElementById("rec-text").innerHTML = "🔴";
            }
        }

        /* Start stream from webcam and start recording if autoRecording is true,
         * will record with forced low settings for smaller files. */
        function startCamera () {
            navigator.getUserMedia({
                audio: true,
                video: {
                    mandatory: {
                        minWidth: 160,
                        maxWidth: 320,
                        minHeight: 120,
                        maxHeight: 240,
                        minFrameRate: 5,
                        maxFrameRate: 10
                    }
                }
            }, function (stream) {
                mediaStream = stream;
                previewElement.src = window.URL.createObjectURL(mediaStream);
                previewElement.removeAttribute("controls");
                previewElement.setAttribute("muted", "muted");
                window.setTimeout(function() { previewElement.play(); }, 200);

                recordAudio = RecordRTC(mediaStream, {
                    onAudioProcessStarted: function () {
                        recordVideo.startRecording();
                    }
                });

                recordVideo = RecordRTC(mediaStream, {
                    type: 'video'
                });

                if(startRecordButtonExists && cameraStartOnLoad) {
                    recordButton.disabled = false;
                }

                if(shouldAutoRecord) {
                    startRecord();
                }
                cameraStarted = true;
            }, function (error) {
                alert("Problem occured, make sure camera is not\nused elsewhere and that you are connected\nby https.");
            });
        }

        /* Closes the webcam stream and post to server if auto recording is on. */
        function stopRecording() {
            if(!shouldAutoRecord){
                recordButton.disabled = false;
            }

            stopButton.disabled = true;

            previewElement.src = '';

            var postbutton = null;
            if (typeof props.postButtonID !== "undefined") {
                postbutton = document.getElementById(props.postButtonID);
            }

            recordVideo.stopRecording(function (url) {
                if(replay) {
                    previewElement.src = url;
                    previewElement.setAttribute("controls","controls");
                    previewElement.removeAttribute("muted");
                }

                if(postbutton == null) {
                    if(props.siteView !== null) {
                        PostBlob(recordVideo.getBlob(), props.siteView);
                    } else {
                        PostBlob(recordVideo.getBlob());
                    }
                }
                else {
                    previewElement.src = url;
                    previewElement.setAttribute("controls","controls");
                    previewElement.removeAttribute("muted");
                    postbutton.disabled = false;
                    postbutton.onclick = function () {
                        if(props.siteView !== null) {
                            PostBlob(recordVideo.getBlob(), props.siteView);
                        } else {
                            PostBlob(recordVideo.getBlob());
                        }
                    }
                }
                mediaStream.stop();
                mediaStream = null;
                if(typeof props.calc !== "undefined") {
                    document.getElementById("test-rec-text").innerHTML = "⭕";
                }
                else {
                    document.getElementById("rec-text").innerHTML = "⭕";
                }
                cameraStarted = false;
            });
            var hasModal = document.getElementById("assignment-modal");
            if (hasModal !== null) {
                hasModal.style.display = 'none';
            }
        }

        /* Post to the server */
        function PostBlob(blob, siteView) {
            // FormData - data to be sent to the server
            var formData = props.formDataBuilder(blob,props.fileName);

            //used for hw testing
            if(typeof props.calc !== "undefined") {
              blobsize = blob.size / 1048576;
              sendTime = Date.now();
            }

            //call xhr with full url, data and callback function
            xhr(props.postURL, formData, props.playCallback);
        }

        /* Function for sending XMLHttpRequests. */
        function xhr(url, data, callback) {
            var request = new XMLHttpRequest();
            request.onreadystatechange = function () {
                if (request.readyState == 4 && request.status == 200) {
                    callback(request.responseText);
                } else if(request.readyState == 4 && request.status !== 200) {
                    alert(request.responseText);
                }
            };

            if(typeof props.calc !== "undefined") {
                request.upload.onloadstart = function () {
                    $("#internet-speed").text("Uploading...");
                }
                request.onloadstart = function () {
                    $("#internet-speed").text("Uploading...");
                }
            }
            request.onload = function(){
                if(typeof props.calc !== "undefined") {
                    if(request.status == 404)
                        $("#internet-speed").text("Upload failed, no server connection.");
                    else if(request.status == 408)
                        $("#internet-speed").text("Connection timed out.");
                    else
                        props.calc(blobsize,sendTime);
                }
                else if(request.status == 404) {
                    alert("Upload failed, no server connection.");
                }
                else if(request.status == 408) {
                    alert("Connection timed out.");
                }
            }

            request.open('POST', url,true);
            request.send(data);
        }

        /* Showing recording-light on load (not recording) */

        if(typeof props.calc !== "undefined") {
            document.getElementById("test-rec-text").innerHTML = "⭕";
        }
        else {
            document.getElementById("rec-text").innerHTML = "⭕";
        }
    },
    render: function() {
        var id;
        var pId;
        var contId;
        console.log(this.props.contID);
        console.log(this.props);
        console.log(typeof this.props.contID);
        if(typeof this.props.contID === "undefined"){
            contId = "prev-container";
        }
        else {
            contId = this.prop.contID;
        }
        if(typeof this.props.calc !== "undefined") {
            id="prev-test";
            pId="test-rec-text";

        }
        else {
            id="preview";
            pId="rec-text";

        }

        return (

                    <video id={id} muted ></video>

        );
    }
});

window.Recorder = Recorder;<|endoftext|>


<commit_before>'use strict';

if ('undefined' == typeof(TabEater)) {
    var TabEater = {};
}

if ('undefined' == typeof(TabEater.options)) {
    TabEater.options = function() {

        var $private = {};

        $private.init = function () {

            $private.prepareElements();
            $private.setUrls();

        };

        /**
         * Url list populated from the chrome storage once the app is initiated
         */
        $private.urls = [];

        /**
         * Reference to the form element
         */
        $private.form = '';

        /**
         * Reference to the clear history checkbox
         */
        $private.clearHistory = '';

        /**
         * Reference to the fallback input
         */
        $private.fallback = false;

        /**
         * Reference to the add input element
         */
        $private.addInput = null;

        /**
         * Prepare elements for interaction
         */
        $private.prepareElements = function () {

            $private.form = document.getElementById("url-list");
            $private.clearHistory = document.querySelector('#clear-history');
            $private.fallback = document.querySelector('#fallback');

            $private.fallback.addEventListener('input', $private.saveOtherOptions);
            // TODO  see if we need this
            // $private.clearHistory.addEventListener('change', $private.saveOtherOptions);

        };

        /**
         * Create empty add input
         */
        $private.createAddInput = function () {

            var addInput = $private.createChild();

            $private.form.appendChild(addInput);

        }

        /**
         * Cleare add input to be used for another url
         */
        $private.clearAndFocusAddInput = function () {

            $private.addInput.value = '';
            $private.addInput.focus();

        }

        /**
         * Get urls form chrome storage and generate HTML structure
         * Namespace for the storage is is TE
         * @returns {*}
         */
        $private.setUrls = function () {

            chrome.storage.sync.get('TE.options', function(obj) {

                var options = obj["TE.options"];
                var urls = (options !== undefined && options.urls !== undefined) ? options.urls : [];

                if (urls.length) {
                    for (var i = 0; i < urls.length; i++) {

                        var child = $private.createChild(urls[i]);

                        $private.form.appendChild(child);
                    }
                }

                if (!$private.urls.length) {
                    $private.createAddInput();
                }

                $private.clearAndFocusAddInput();

                /*
                var clearHistory = (options !== undefined && options.clearHistory !== undefined) ? options.clearHistory : false;
                if (clearHistory === true) {
                    $private.clearHistory.setAttribute('checked', 'checked');
                } else {
                    $private.clearHistory.removeAttribute('checked');
                }
                */

                $private.fallback.value = (options !== undefined && options.fallback !== undefined) ? options.fallback : '';

                $private.urls = urls;

            });

        };

        /**
         * Get urls
         * @returns {*}
         */
        $private.getUrls = function () {

            return $private.urls;

        };

        /**
         * Save other options when changed (fallback url and clearHistory)
         */
        $private.saveOtherOptions = function () {

            if ($private.disabled) {
                return;
            }

            $private.disabled = true;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: $private.urls,
                    // clearHistory: $private.clearHistory.checked,
                    fallback: $private.fallback.value
                }
            }, function () {
                if ($private.timeoutId) {
                    clearTimeout($private.timeoutId);
                }

                $private.timeoutId = setTimeout(function() {
                    $private.disabled = false;
                }, 300);
            })

        };

        /**
         * Save new url into chrome storage
         */
        $private.saveUrl = function (e) {

            if (e.which !== 1 && e.which !== 13) {
                return;
            }

            var url = $private.addInput && $private.addInput.value ? $private.addInput.value : '';
            var urls = $private.urls.slice();

            if (!url) {
                return;
            }

            // check if url exists in the list already
            if (urls.indexOf(url) === -1) {
                urls.push(url);
            }

            // var clearHistory = $private.clearHistory.checked;
            var fallback = $private.fallback.value;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: urls,
                    // clearHistory: clearHistory,
                    fallback: fallback
                }
            }, function () {

                var child = $private.createChild(url)

                $private.form.insertBefore(child, $private.addInput.parentNode)

                $private.clearAndFocusAddInput()

                $private.urls = urls

            })

        };

        /**
         * Remove url from the chrome storage and from the list
         * @param e
         */
        $private.removeUrl = function (e) {

            var button = e.target;
            var holder = button.parentNode;
            var input = holder.children[0];

            if (!$private.urls.length) {
                return;
            }

            $private.urls.splice($private.urls.indexOf(input.value), 1);

            // var clearHistory = $private.clearHistory.checked;
            var fallback = $private.fallback.value;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: $private.urls,
                    // clearHistory: clearHistory,
                    fallback: fallback
                }
            }, function () {

                $private.form.removeChild(holder)

                button.removeEventListener('click', $private.removeUrl, false)
            })

        };

        /**
         * Create child for the url list
         * @param url
         * @returns {HTMLElement}
         */
        $private.createChild = function (url) {

            url = (url === undefined) ? '' : url;

            var child = document.createElement('div');
            child.className = 'input-container';

            var input = document.createElement('input');
            input.type = 'url';
            input.value = url;
            input.setAttribute('placeholder', 'Type your url here...');

            if (!url) {
                input.addEventListener('keyup', $private.saveUrl);

                $private.addInput = input;
            }

            child.appendChild(input);

            if (url) {
                var remove = document.createElement('button');
                remove.innerHTML = '×';
                remove.className = 'remove icon-button';

                remove.addEventListener('click', $private.removeUrl);

                child.appendChild(remove);
            } else {
                var add = document.createElement('button');
                add.innerHTML = '+';
                add.className = 'add icon-button green';

                add.addEventListener('click', $private.saveUrl);

                child.appendChild(add);
            }

            return child;

        };

        var $shared = {
            get init() {
                $private.init();
            },
            set init(value) { return false; }
        };

        return $shared;

    }();
}

document.addEventListener('DOMContentLoaded', TabEater.options.init);
<commit_msg>updates existing url on change<commit_after>'use strict';

if ('undefined' == typeof(TabEater)) {
    var TabEater = {};
}

if ('undefined' == typeof(TabEater.options)) {
    TabEater.options = function() {

        var $private = {};

        $private.init = function () {

            $private.prepareElements();
            $private.setUrls();

        };

        /**
         * Url list populated from the chrome storage once the app is initiated
         */
        $private.urls = [];

        /**
         * Reference to the form element
         */
        $private.form = '';

        /**
         * Reference to the clear history checkbox
         */
        $private.clearHistory = '';

        /**
         * Reference to the fallback input
         */
        $private.fallback = false;

        /**
         * Reference to the add input element
         */
        $private.addInput = null;

        /**
         * Prepare elements for interaction
         */
        $private.prepareElements = function () {

            $private.form = document.getElementById("url-list");
            $private.clearHistory = document.querySelector('#clear-history');
            $private.fallback = document.querySelector('#fallback');

            $private.fallback.addEventListener('input', $private.saveOtherOptions);
            // TODO  see if we need this
            // $private.clearHistory.addEventListener('change', $private.saveOtherOptions);

        };

        /**
         * Create empty add input
         */
        $private.createAddInput = function () {

            var addInput = $private.createChild();

            $private.form.appendChild(addInput);

        }

        /**
         * Cleare add input to be used for another url
         */
        $private.clearAndFocusAddInput = function () {

            $private.addInput.value = '';
            $private.addInput.focus();

        }

        /**
         * Get urls form chrome storage and generate HTML structure
         * Namespace for the storage is is TE
         * @returns {*}
         */
        $private.setUrls = function () {

            chrome.storage.sync.get('TE.options', function(obj) {

                var options = obj["TE.options"];
                var urls = (options !== undefined && options.urls !== undefined) ? options.urls : [];

                if (urls.length) {
                    for (var i = 0; i < urls.length; i++) {

                        var child = $private.createChild(urls[i]);

                        $private.form.appendChild(child);
                    }
                }

                if (!$private.urls.length) {
                    $private.createAddInput();
                }

                $private.clearAndFocusAddInput();

                /*
                var clearHistory = (options !== undefined && options.clearHistory !== undefined) ? options.clearHistory : false;
                if (clearHistory === true) {
                    $private.clearHistory.setAttribute('checked', 'checked');
                } else {
                    $private.clearHistory.removeAttribute('checked');
                }
                */

                $private.fallback.value = (options !== undefined && options.fallback !== undefined) ? options.fallback : '';

                $private.urls = urls;

            });

        };

        /**
         * Get urls
         * @returns {*}
         */
        $private.getUrls = function () {

            return $private.urls;

        };

        /**
         * Save other options when changed (fallback url and clearHistory)
         */
        $private.saveOtherOptions = function () {

            if ($private.disabled) {
                return;
            }

            $private.disabled = true;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: $private.urls,
                    // clearHistory: $private.clearHistory.checked,
                    fallback: $private.fallback.value
                }
            }, function () {
                if ($private.timeoutId) {
                    clearTimeout($private.timeoutId);
                }

                $private.timeoutId = setTimeout(function() {
                    $private.disabled = false;
                }, 100);
            })

        };

        /**
         * Save new url into chrome storage
         */
        $private.saveUrl = function (e) {

            if (e.which !== 1 && e.which !== 13) {
                return;
            }

            var url = $private.addInput && $private.addInput.value ? $private.addInput.value : '';
            var urls = $private.urls.slice();

            if (!url) {
                return;
            }

            // check if url exists in the list already
            if (urls.indexOf(url) === -1) {
                urls.push(url);
            }

            // var clearHistory = $private.clearHistory.checked;
            var fallback = $private.fallback.value;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: urls,
                    // clearHistory: clearHistory,
                    fallback: fallback
                }
            }, function () {

                var child = $private.createChild(url)

                $private.form.insertBefore(child, $private.addInput.parentNode)

                $private.clearAndFocusAddInput()

                $private.urls = urls

            })

        };

        /**
         * Updates particular url on change
         *
         * @param e
         */
        $private.updateUrl = function (e) {

            if ($private.disabled) {
                return;
            }

            $private.disabled = true;

            var input = e.target;
            var newValue = input.value;
            var index = $private.urls.indexOf(input.dataset.prev);

            $private.urls.splice(index, 1, newValue);
            input.dataset.prev = newValue;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: $private.urls,
                    // clearHistory: $private.clearHistory.checked,
                    fallback: $private.fallback.value
                }
            }, function () {
                if ($private.timeoutId) {
                    clearTimeout($private.timeoutId);
                }

                $private.timeoutId = setTimeout(function() {
                    $private.disabled = false;
                }, 100);
            })

        };

        /**
         * Remove url from the chrome storage and from the list
         * @param e
         */
        $private.removeUrl = function (e) {

            var button = e.target;
            var holder = button.parentNode;
            var input = holder.children[0];

            if (!$private.urls.length) {
                return;
            }

            $private.urls.splice($private.urls.indexOf(input.value), 1);

            // var clearHistory = $private.clearHistory.checked;
            var fallback = $private.fallback.value;

            chrome.storage.sync.set({
                'TE.options': {
                    urls: $private.urls,
                    // clearHistory: clearHistory,
                    fallback: fallback
                }
            }, function () {

                $private.form.removeChild(holder)

                button.removeEventListener('click', $private.removeUrl, false)
                input.removeEventListener('keyup', $private.updateUrl, false);
            })

        };

        /**
         * Create child for the url list
         * @param url
         * @returns {HTMLElement}
         */
        $private.createChild = function (url) {

            url = (url === undefined) ? '' : url;

            var child = document.createElement('div');
            child.className = 'input-container';

            var input = document.createElement('input');
            input.type = 'url';
            input.value = url;
            input.setAttribute('placeholder', 'Type your url here...');

            if (url) {
                input.dataset.prev = url;
                input.addEventListener('keyup', $private.updateUrl);
            } else {
                input.addEventListener('keyup', $private.saveUrl);

                $private.addInput = input;
            }

            child.appendChild(input);

            if (url) {
                var remove = document.createElement('button');
                remove.innerHTML = '×';
                remove.className = 'remove icon-button';

                remove.addEventListener('click', $private.removeUrl);

                child.appendChild(remove);
            } else {
                var add = document.createElement('button');
                add.innerHTML = '+';
                add.className = 'add icon-button green';

                add.addEventListener('click', $private.saveUrl);

                child.appendChild(add);
            }

            return child;

        };

        var $shared = {
            get init() {
                $private.init();
            },
            set init(value) { return false; }
        };

        return $shared;

    }();
}

document.addEventListener('DOMContentLoaded', TabEater.options.init);
<|endoftext|>


<commit_before>const env = {
  "browser": true,
  "es6": true,
  "node": true
};

const rules = {
  "array-bracket-spacing": ["error", "never"],
  "arrow-parens": [
    "error",
    "as-needed",
    {
      "requireForBlockBody": true
    }
  ],
  "arrow-spacing": "error",
  "block-spacing": ["error", "always"],
  "brace-style": ["error", "1tbs"],
  "camelcase": [
    "error",
    {
      "properties": "never"
    }
  ],
  "comma-dangle": ["error", "never"],
  "eol-last": ["error", "always"],
  "func-name-matching": "error",
  "indent": [
    "off",
    2,
    {
      "ArrayExpression": "off",
      "SwitchCase": 1,
      "CallExpression": {
        "arguments": "off"
      },
      "FunctionDeclaration": {
        "parameters": "off"
      },
      "FunctionExpression": {
        "parameters": "off"
      },
      "MemberExpression": "off",
      "ObjectExpression": "off",
      "ImportDeclaration": "off"
    }
  ],
  "handle-callback-err": "off",
  "linebreak-style": ["error", "unix"],
  "max-lines": [
    "error",
    {
      "max": 200,
      "skipBlankLines": true,
      "skipComments": true
    }
  ],
  "max-lines-per-function": [
    "error",
    {
      "skipBlankLines": true,
      "skipComments": true
    }
  ],
  "max-statements-per-line": [
    "error",
    {
      "max": 1
    }
  ],
  "new-cap": [
    "error",
    {
      "newIsCap": true,
      "capIsNew": false
    }
  ],
  "new-parens": "error",
  "no-buffer-constructor": "error",
  "no-console": "off",
  "no-extra-semi": "off",
  "no-fallthrough": "off",
  "no-func-assign": "off",
  "no-implicit-coercion": "error",
  "no-multi-assign": "error",
  "no-multiple-empty-lines": [
    "error",
    {
      "max": 1
    }
  ],
  "no-nested-ternary": "error",
  "no-param-reassign": "off",
  "no-return-assign": "error",
  "no-return-await": "off",
  "no-shadow-restricted-names": "error",
  "no-tabs": "error",
  "no-trailing-spaces": "error",
  "no-unused-vars": [
    "error",
    {
      "vars": "all",
      "args": "none",
      "ignoreRestSiblings": false
    }
  ],
  "no-use-before-define": [
    "error",
    {
      "functions": false,
      "classes": false
    }
  ],
  "no-useless-escape": "off",
  "no-var": "error",
  "nonblock-statement-body-position": ["error", "below"],
  "object-curly-spacing": ["error", "always"],
  "padded-blocks": ["error", "never"],
  "prefer-arrow-callback": "error",
  "prefer-const": [
    "error",
    {
      "destructuring": "all",
      "ignoreReadBeforeAssign": true
    }
  ],
  "prefer-template": "off",
  "quotes": ["error", "single"],
  "semi": ["error", "always"],
  "spaced-comment": [
    "error",
    "always",
    {
      "exceptions": ["!"]
    }
  ],
  "space-before-blocks": "error",
  "unicode-bom": ["error", "never"],
  "valid-jsdoc": "error",
  "wrap-iife": ["error", "inside"],
  "react/jsx-closing-bracket-location": 1,
  "react/jsx-tag-spacing": 1,
  "react/jsx-max-props-per-line": ["error", { "maximum": 2, "when": "multiline" }],
  "react/prop-types": 0
};

module.exports = {
  "env": env,
  "extends": [
    "plugin:react/recommended",
    "eslint:recommended",
  ],
  "settings": {
    "react": {
      "version": "^16.5.2"
    }
  },
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaVersion": 10,
    "requireConfigFile": false,
    "sourceType": "module"
  },
  "root": true,
  "rules": rules,
  "overrides": [
    {
      "files": ["**/*.ts", "**/*.tsx"],
      "env": env,
      "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended"
      ],
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "ecmaFeatures": { "jsx": true },
        "ecmaVersion": 10,
        "requireConfigFile": false,
        "sourceType": "module"
      },
      "plugins": ["@typescript-eslint"],
      "rules": rules
    }
  ]
};
<commit_msg>interface: max-lines 300, warn for function max<commit_after>const env = {
  "browser": true,
  "es6": true,
  "node": true
};

const rules = {
  "array-bracket-spacing": ["error", "never"],
  "arrow-parens": [
    "error",
    "as-needed",
    {
      "requireForBlockBody": true
    }
  ],
  "arrow-spacing": "error",
  "block-spacing": ["error", "always"],
  "brace-style": ["error", "1tbs"],
  "camelcase": [
    "error",
    {
      "properties": "never"
    }
  ],
  "comma-dangle": ["error", "never"],
  "eol-last": ["error", "always"],
  "func-name-matching": "error",
  "indent": [
    "off",
    2,
    {
      "ArrayExpression": "off",
      "SwitchCase": 1,
      "CallExpression": {
        "arguments": "off"
      },
      "FunctionDeclaration": {
        "parameters": "off"
      },
      "FunctionExpression": {
        "parameters": "off"
      },
      "MemberExpression": "off",
      "ObjectExpression": "off",
      "ImportDeclaration": "off"
    }
  ],
  "handle-callback-err": "off",
  "linebreak-style": ["error", "unix"],
  "max-lines": [
    "error",
    {
      "max": 300,
      "skipBlankLines": true,
      "skipComments": true
    }
  ],
  "max-lines-per-function": [
    "warn",
    {
      "skipBlankLines": true,
      "skipComments": true
    }
  ],
  "max-statements-per-line": [
    "error",
    {
      "max": 1
    }
  ],
  "new-cap": [
    "error",
    {
      "newIsCap": true,
      "capIsNew": false
    }
  ],
  "new-parens": "error",
  "no-buffer-constructor": "error",
  "no-console": "off",
  "no-extra-semi": "off",
  "no-fallthrough": "off",
  "no-func-assign": "off",
  "no-implicit-coercion": "error",
  "no-multi-assign": "error",
  "no-multiple-empty-lines": [
    "error",
    {
      "max": 1
    }
  ],
  "no-nested-ternary": "error",
  "no-param-reassign": "off",
  "no-return-assign": "error",
  "no-return-await": "off",
  "no-shadow-restricted-names": "error",
  "no-tabs": "error",
  "no-trailing-spaces": "error",
  "no-unused-vars": [
    "error",
    {
      "vars": "all",
      "args": "none",
      "ignoreRestSiblings": false
    }
  ],
  "no-use-before-define": [
    "error",
    {
      "functions": false,
      "classes": false
    }
  ],
  "no-useless-escape": "off",
  "no-var": "error",
  "nonblock-statement-body-position": ["error", "below"],
  "object-curly-spacing": ["error", "always"],
  "padded-blocks": ["error", "never"],
  "prefer-arrow-callback": "error",
  "prefer-const": [
    "error",
    {
      "destructuring": "all",
      "ignoreReadBeforeAssign": true
    }
  ],
  "prefer-template": "off",
  "quotes": ["error", "single"],
  "semi": ["error", "always"],
  "spaced-comment": [
    "error",
    "always",
    {
      "exceptions": ["!"]
    }
  ],
  "space-before-blocks": "error",
  "unicode-bom": ["error", "never"],
  "valid-jsdoc": "error",
  "wrap-iife": ["error", "inside"],
  "react/jsx-closing-bracket-location": 1,
  "react/jsx-tag-spacing": 1,
  "react/jsx-max-props-per-line": ["error", { "maximum": 2, "when": "multiline" }],
  "react/prop-types": 0
};

module.exports = {
  "env": env,
  "extends": [
    "plugin:react/recommended",
    "eslint:recommended",
  ],
  "settings": {
    "react": {
      "version": "^16.5.2"
    }
  },
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaVersion": 10,
    "requireConfigFile": false,
    "sourceType": "module"
  },
  "root": true,
  "rules": rules,
  "overrides": [
    {
      "files": ["**/*.ts", "**/*.tsx"],
      "env": env,
      "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended"
      ],
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "ecmaFeatures": { "jsx": true },
        "ecmaVersion": 10,
        "requireConfigFile": false,
        "sourceType": "module"
      },
      "plugins": ["@typescript-eslint"],
      "rules": rules
    }
  ]
};
<|endoftext|>