<commit_before>// USGS Landsat Imagery Metadata RES API
//
// Forked from https://github.com/FDA/openfda/tree/master/api
// Exposes /landsat/metadata.json and /healthcheck GET endpoints
//
// Author: developmentseed
// Contributer: scisco
//
// License: CC0 1.0 Universal

var join = require('path').join;
var fse = require('fs-extra');
var env = require('node-env-file');

// Read and load env variables from .env FILE if it exists
var envFile = join(__dirname, '.env');

if (fse.existsSync(envFile)) {
  try {
    env(__dirname + '/.env');
  }
  catch(err) {
    console.log(err);
  }
}

// New Relic monitoring
require('newrelic');
var ejs = require('elastic.js');
var elasticsearch = require('elasticsearch');
var express = require('express');
var moment = require('moment');
var _ = require('underscore');
var inside = require('turf-inside');
var point = require('turf-point');
var polygon = require('turf-polygon');

var api_request = require('./api_request.js');
var elasticsearch_query = require('./elasticsearch_query.js');
var logging = require('./logging.js');
var META = {
  'credit': 'This API is based on the openFDA\'s API ' +
            'https://github.com/FDA/openfda/tree/master/api ',
  'author': 'Development Seed',
  'contributor': 'Scisco',
  'license': 'http://creativecommons.org/publicdomain/zero/1.0/legalcode',
  'last_updated': '2015-04-13'
};

var HTTP_CODE = {
  OK: 200,
  BAD_REQUEST: 400,
  NOT_FOUND: 404,
  SERVER_ERROR: 500
};

// Internal fields to remove from ES objects before serving
// via the API.
var FIELDS_TO_REMOVE = [

];

var MAIN_INDEX = 'landsat';

var app = express();

var containsPattern = /(\sAND\s)?contains:(\d+(?:\.\d*)?,\d+(?:\.\d*)?)/;

app.disable('x-powered-by');

// Set caching headers for Amazon Cloudfront
CacheMiddleware = function(seconds) {
  return function(request, response, next) {
    response.setHeader('Cache-Control', 'public, max-age=' + seconds);
    return next();
  };
};
app.use(CacheMiddleware(60));

// Use gzip compression
app.use(express.compress());

// Setup defaults for API JSON error responses
app.set('json spaces', 2);
app.set('json replacer', undefined);

var log = logging.GetLogger();

var client = new elasticsearch.Client({
  host: process.env.ES_HOST || 'localhost:9200',
  log: logging.ElasticsearchLogger,

  // Note that this doesn't abort the query.
  requestTimeout: 10000  // milliseconds
});

app.get('/healthcheck', function(request, response) {
  client.cluster.health({
    index: MAIN_INDEX,
    timeout: 1000 * 60,
    waitForStatus: 'yellow'
  }, function(error, health_response, status) {
    health_json = JSON.stringify(health_response, undefined, 2);
    if (error != undefined) {
      response.send(500, 'NAK.\n' + error + '\n');
    } else if (health_response['status'] == 'red') {
      response.send(500, 'NAK.\nStatus: ' + health_json + '\n');
    } else {
      response.send('OK\n\n' + health_json + '\n');
    }
  });
});

ApiError = function(response, code, message) {
  error_response = {};
  error_response.error = {};
  error_response.error.code = code;
  error_response.error.message = message;
  response.json(HTTP_CODE[code], error_response);
};

LogRequest = function(request) {
  log.info(request.headers, 'Request Headers');
  log.info(request.query, 'Request Query');
};

SetHeaders = function(response) {
  response.header('Server', process.env.RESPONSE_HEADER_SERVER || 'api.developmentseed.org');
  // http://john.sh/blog/2011/6/30/cross-domain-ajax-expressjs-
  // and-access-control-allow-origin.html
  response.header('Access-Control-Allow-Origin', '*');
  response.header('Access-Control-Allow-Headers', 'X-Requested-With');
  response.header('Content-Security-Policy', "default-src 'none'");
  // https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
  // #Send_security_headers
  response.header('X-Content-Type-Options', 'nosniff');
  response.header('X-Frame-Options', 'deny');
  response.header('X-XSS-Protection', '1; mode=block');
};

TryToCheckApiParams = function(request, response) {
  try {
    return api_request.CheckParams(request.query);
  } catch (e) {
    log.error(e);
    if (e.name == api_request.API_REQUEST_ERROR) {
      ApiError(response, 'BAD_REQUEST', e.message);
    } else {
      ApiError(response, 'BAD_REQUEST', '');
    }
    return null;
  }
};

TryToBuildElasticsearchParams = function(params, elasticsearch_index, response) {

  try {
    var es_query = elasticsearch_query.BuildQuery(params);
    log.info(es_query.toString(), 'Elasticsearch Query');
  } catch (e) {
    log.error(e);
    if (e.name == elasticsearch_query.ELASTICSEARCH_QUERY_ERROR) {
      ApiError(response, 'BAD_REQUEST', e.message);
    } else {
      ApiError(response, 'BAD_REQUEST', '');
    }
    return null;
  }

  var es_search_params = {
    index: elasticsearch_index,
    body: es_query.toString()
  };

  if (!params.count) {
    es_search_params.from = params.skip;
    es_search_params.size = params.limit;
  }

  return es_search_params;
};

TrySearch = function(index, params, es_search_params, response, cLonLat) {
  client.search(es_search_params).then(function(body) {
    if (body.hits.hits.length == 0) {
      ApiError(response, 'NOT_FOUND', 'No matches found!');
    }

    var response_json = {};
    response_json.meta = _.clone(META);

    if (!params.count) {
      response_json.meta.results = {
        'skip': params.skip,
        'limit': params.limit,
        'total': body.hits.total
      };

      response_json.results = [];
      for (i = 0; i < body.hits.hits.length; i++) {
        var es_results = body.hits.hits[i]._source;
        for (j = 0; j < FIELDS_TO_REMOVE.length; j++) {
          delete es_results[FIELDS_TO_REMOVE[j]];
        }
        response_json.results.push(es_results);
      }
      response.json(HTTP_CODE.OK, responseFilter(response_json, cLonLat, params.userLimit));

    } else if (params.count) {
      if (body.facets.count.terms) {
        // Term facet count
        if (body.facets.count.terms.length != 0) {
          response_json.results = body.facets.count.terms;
          response.json(HTTP_CODE.OK, responseFilter(response_json, cLonLat, params.userLimit));
        } else {
          ApiError(response, 'NOT_FOUND', 'Nothing to count');
        }
      } else if (body.facets.count.entries) {
        // Date facet count
        if (body.facets.count.entries.length != 0) {
          for (i = 0; i < body.facets.count.entries.length; i++) {
            var day = moment(body.facets.count.entries[i].time);
            body.facets.count.entries[i].time = day.format('YYYYMMDD');
          }
          response_json.results = body.facets.count.entries;
          response.json(HTTP_CODE.OK, responseFilter(response_json, cLonLat, params.userLimit));
        } else {
          ApiError(response, 'NOT_FOUND', 'Nothing to count');
        }
      } else {
        ApiError(response, 'NOT_FOUND', 'Nothing to count');
      }
    } else {
      ApiError(response, 'NOT_FOUND', 'No matches found!');
    }
  }, function(error) {
    log.error(error);
    ApiError(response, 'SERVER_ERROR', 'Check your request and try again');
  });
};

Endpoint = function(noun) {
  app.get('/' + noun, function(request, response) {
    LogRequest(request);
    SetHeaders(response);

    var params = TryToCheckApiParams(request, response);
    if (params == null) {
      return;
    }

    var index = noun;

    // remove contains clause for use in turf
    // add a search parameter to limit the extent
    var cLonLat;
    if (containsPattern.test(params.search)) {
      contains = params.search.match(containsPattern)[2];
      cLonLat = contains.split(',');
      // because we are filtering after the elasticsearch query, limit our results to the extent
      // but allow unlimited results
      params.search = params.search.replace(containsPattern,'$1upperLeftCornerLatitude:[' +
        cLonLat[1] + ' TO 1000] AND lowerRightCornerLatitude:[-1000 TO ' +
        cLonLat[1] + '] AND lowerLeftCornerLongitude:[-1000 TO ' +
        cLonLat[0] + '] AND upperRightCornerLongitude:[' +
        cLonLat[0] + ' TO 1000]');
      // need to return all results internally but retain the user selected limit
      params.userLimit = _.clone(params.limit)
      params.limit = process.env.QUERY_LIMIT || 1000000000;
    }

    var es_search_params =
      TryToBuildElasticsearchParams(params, index, response);
    if (es_search_params == null) {
      return;
    }

    TrySearch(index, params, es_search_params, response, cLonLat);
  });
};

  /**
   * This returns the response_json optionally filtered for scenes containing a given point.
   * @param {object} response_json the api response object
   * @param {array} cLonLat an array containing a longitude and latitude for filtering
   * @param {number} limit user provided value for number of results to return
   * @returns {object} the reponse_json with the results property filtered by cLonLat.
   */

responseFilter = function (response_json, cLonLat, limit) {
  if (!cLonLat) return response_json;
  var thePoint = point(cLonLat);
  var resultPolygon;
  response_json.results = response_json.results.filter(function(result){
    resultPolygon = polygon([[
      [result.lowerLeftCornerLongitude, result.lowerLeftCornerLatitude],
      [result.upperLeftCornerLongitude, result.upperLeftCornerLatitude],
      [result.upperRightCornerLongitude, result.upperRightCornerLatitude],
      [result.lowerRightCornerLongitude, result.lowerRightCornerLatitude],
      [result.lowerLeftCornerLongitude, result.lowerLeftCornerLatitude]
    ]]);
    return inside(thePoint, resultPolygon);
  })

  // overwrite the metadata to show the user selected limit
  // slice the response accordingly
  response_json.meta.results.limit = limit
  response_json.meta.results.total = response_json.results.length
  response_json.results = response_json.results.slice(0,limit)

  return response_json;
}

Endpoint('landsat');

// From http://strongloop.com/strongblog/
// robust-node-applications-error-handling/
if (process.env.NODE_ENV === 'production') {
  process.on('uncaughtException', function(e) {
    log.error(e);
    process.exit(1);
  });
}

var port = process.env.PORT || 8000;
app.listen(port, function() {
  console.log('Listening on ' + port);
});
<commit_msg>read negative sign<commit_after>// USGS Landsat Imagery Metadata RES API
//
// Forked from https://github.com/FDA/openfda/tree/master/api
// Exposes /landsat/metadata.json and /healthcheck GET endpoints
//
// Author: developmentseed
// Contributer: scisco
//
// License: CC0 1.0 Universal

var join = require('path').join;
var fse = require('fs-extra');
var env = require('node-env-file');

// Read and load env variables from .env FILE if it exists
var envFile = join(__dirname, '.env');

if (fse.existsSync(envFile)) {
  try {
    env(__dirname + '/.env');
  }
  catch(err) {
    console.log(err);
  }
}

// New Relic monitoring
require('newrelic');
var ejs = require('elastic.js');
var elasticsearch = require('elasticsearch');
var express = require('express');
var moment = require('moment');
var _ = require('underscore');
var inside = require('turf-inside');
var point = require('turf-point');
var polygon = require('turf-polygon');

var api_request = require('./api_request.js');
var elasticsearch_query = require('./elasticsearch_query.js');
var logging = require('./logging.js');
var META = {
  'credit': 'This API is based on the openFDA\'s API ' +
            'https://github.com/FDA/openfda/tree/master/api ',
  'author': 'Development Seed',
  'contributor': 'Scisco',
  'license': 'http://creativecommons.org/publicdomain/zero/1.0/legalcode',
  'last_updated': '2015-04-13'
};

var HTTP_CODE = {
  OK: 200,
  BAD_REQUEST: 400,
  NOT_FOUND: 404,
  SERVER_ERROR: 500
};

// Internal fields to remove from ES objects before serving
// via the API.
var FIELDS_TO_REMOVE = [

];

var MAIN_INDEX = 'landsat';

var app = express();

var containsPattern = /(\sAND\s)?contains:(-?\d+(?:\.\d*)?,-?\d+(?:\.\d*)?)/;

app.disable('x-powered-by');

// Set caching headers for Amazon Cloudfront
CacheMiddleware = function(seconds) {
  return function(request, response, next) {
    response.setHeader('Cache-Control', 'public, max-age=' + seconds);
    return next();
  };
};
app.use(CacheMiddleware(60));

// Use gzip compression
app.use(express.compress());

// Setup defaults for API JSON error responses
app.set('json spaces', 2);
app.set('json replacer', undefined);

var log = logging.GetLogger();

var client = new elasticsearch.Client({
  host: process.env.ES_HOST || 'localhost:9200',
  log: logging.ElasticsearchLogger,

  // Note that this doesn't abort the query.
  requestTimeout: 10000  // milliseconds
});

app.get('/healthcheck', function(request, response) {
  client.cluster.health({
    index: MAIN_INDEX,
    timeout: 1000 * 60,
    waitForStatus: 'yellow'
  }, function(error, health_response, status) {
    health_json = JSON.stringify(health_response, undefined, 2);
    if (error != undefined) {
      response.send(500, 'NAK.\n' + error + '\n');
    } else if (health_response['status'] == 'red') {
      response.send(500, 'NAK.\nStatus: ' + health_json + '\n');
    } else {
      response.send('OK\n\n' + health_json + '\n');
    }
  });
});

ApiError = function(response, code, message) {
  error_response = {};
  error_response.error = {};
  error_response.error.code = code;
  error_response.error.message = message;
  response.json(HTTP_CODE[code], error_response);
};

LogRequest = function(request) {
  log.info(request.headers, 'Request Headers');
  log.info(request.query, 'Request Query');
};

SetHeaders = function(response) {
  response.header('Server', process.env.RESPONSE_HEADER_SERVER || 'api.developmentseed.org');
  // http://john.sh/blog/2011/6/30/cross-domain-ajax-expressjs-
  // and-access-control-allow-origin.html
  response.header('Access-Control-Allow-Origin', '*');
  response.header('Access-Control-Allow-Headers', 'X-Requested-With');
  response.header('Content-Security-Policy', "default-src 'none'");
  // https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
  // #Send_security_headers
  response.header('X-Content-Type-Options', 'nosniff');
  response.header('X-Frame-Options', 'deny');
  response.header('X-XSS-Protection', '1; mode=block');
};

TryToCheckApiParams = function(request, response) {
  try {
    return api_request.CheckParams(request.query);
  } catch (e) {
    log.error(e);
    if (e.name == api_request.API_REQUEST_ERROR) {
      ApiError(response, 'BAD_REQUEST', e.message);
    } else {
      ApiError(response, 'BAD_REQUEST', '');
    }
    return null;
  }
};

TryToBuildElasticsearchParams = function(params, elasticsearch_index, response) {

  try {
    var es_query = elasticsearch_query.BuildQuery(params);
    log.info(es_query.toString(), 'Elasticsearch Query');
  } catch (e) {
    log.error(e);
    if (e.name == elasticsearch_query.ELASTICSEARCH_QUERY_ERROR) {
      ApiError(response, 'BAD_REQUEST', e.message);
    } else {
      ApiError(response, 'BAD_REQUEST', '');
    }
    return null;
  }

  var es_search_params = {
    index: elasticsearch_index,
    body: es_query.toString()
  };

  if (!params.count) {
    es_search_params.from = params.skip;
    es_search_params.size = params.limit;
  }

  return es_search_params;
};

TrySearch = function(index, params, es_search_params, response, cLonLat) {
  client.search(es_search_params).then(function(body) {
    if (body.hits.hits.length == 0) {
      ApiError(response, 'NOT_FOUND', 'No matches found!');
    }

    var response_json = {};
    response_json.meta = _.clone(META);

    if (!params.count) {
      response_json.meta.results = {
        'skip': params.skip,
        'limit': params.limit,
        'total': body.hits.total
      };

      response_json.results = [];
      for (i = 0; i < body.hits.hits.length; i++) {
        var es_results = body.hits.hits[i]._source;
        for (j = 0; j < FIELDS_TO_REMOVE.length; j++) {
          delete es_results[FIELDS_TO_REMOVE[j]];
        }
        response_json.results.push(es_results);
      }
      response.json(HTTP_CODE.OK, responseFilter(response_json, cLonLat, params.userLimit));

    } else if (params.count) {
      if (body.facets.count.terms) {
        // Term facet count
        if (body.facets.count.terms.length != 0) {
          response_json.results = body.facets.count.terms;
          response.json(HTTP_CODE.OK, responseFilter(response_json, cLonLat, params.userLimit));
        } else {
          ApiError(response, 'NOT_FOUND', 'Nothing to count');
        }
      } else if (body.facets.count.entries) {
        // Date facet count
        if (body.facets.count.entries.length != 0) {
          for (i = 0; i < body.facets.count.entries.length; i++) {
            var day = moment(body.facets.count.entries[i].time);
            body.facets.count.entries[i].time = day.format('YYYYMMDD');
          }
          response_json.results = body.facets.count.entries;
          response.json(HTTP_CODE.OK, responseFilter(response_json, cLonLat, params.userLimit));
        } else {
          ApiError(response, 'NOT_FOUND', 'Nothing to count');
        }
      } else {
        ApiError(response, 'NOT_FOUND', 'Nothing to count');
      }
    } else {
      ApiError(response, 'NOT_FOUND', 'No matches found!');
    }
  }, function(error) {
    log.error(error);
    ApiError(response, 'SERVER_ERROR', 'Check your request and try again');
  });
};

Endpoint = function(noun) {
  app.get('/' + noun, function(request, response) {
    LogRequest(request);
    SetHeaders(response);

    var params = TryToCheckApiParams(request, response);
    if (params == null) {
      return;
    }

    var index = noun;

    // remove contains clause for use in turf
    // add a search parameter to limit the extent
    var cLonLat;
    if (containsPattern.test(params.search)) {
      contains = params.search.match(containsPattern)[2];
      cLonLat = contains.split(',');
      // because we are filtering after the elasticsearch query, limit our results to the extent
      // but allow unlimited results
      params.search = params.search.replace(containsPattern,'$1upperLeftCornerLatitude:[' +
        cLonLat[1] + ' TO 1000] AND lowerRightCornerLatitude:[-1000 TO ' +
        cLonLat[1] + '] AND lowerLeftCornerLongitude:[-1000 TO ' +
        cLonLat[0] + '] AND upperRightCornerLongitude:[' +
        cLonLat[0] + ' TO 1000]');
      // need to return all results internally but retain the user selected limit
      params.userLimit = _.clone(params.limit)
      params.limit = process.env.QUERY_LIMIT || 1000000000;
    }

    var es_search_params =
      TryToBuildElasticsearchParams(params, index, response);
    if (es_search_params == null) {
      return;
    }

    TrySearch(index, params, es_search_params, response, cLonLat);
  });
};

  /**
   * This returns the response_json optionally filtered for scenes containing a given point.
   * @param {object} response_json the api response object
   * @param {array} cLonLat an array containing a longitude and latitude for filtering
   * @param {number} limit user provided value for number of results to return
   * @returns {object} the reponse_json with the results property filtered by cLonLat.
   */

responseFilter = function (response_json, cLonLat, limit) {
  if (!cLonLat) return response_json;
  var thePoint = point(cLonLat);
  var resultPolygon;
  response_json.results = response_json.results.filter(function(result){
    resultPolygon = polygon([[
      [result.lowerLeftCornerLongitude, result.lowerLeftCornerLatitude],
      [result.upperLeftCornerLongitude, result.upperLeftCornerLatitude],
      [result.upperRightCornerLongitude, result.upperRightCornerLatitude],
      [result.lowerRightCornerLongitude, result.lowerRightCornerLatitude],
      [result.lowerLeftCornerLongitude, result.lowerLeftCornerLatitude]
    ]]);
    return inside(thePoint, resultPolygon);
  })

  // overwrite the metadata to show the user selected limit
  // slice the response accordingly
  response_json.meta.results.limit = limit
  response_json.meta.results.total = response_json.results.length
  response_json.results = response_json.results.slice(0,limit)

  return response_json;
}

Endpoint('landsat');

// From http://strongloop.com/strongblog/
// robust-node-applications-error-handling/
if (process.env.NODE_ENV === 'production') {
  process.on('uncaughtException', function(e) {
    log.error(e);
    process.exit(1);
  });
}

var port = process.env.PORT || 8000;
app.listen(port, function() {
  console.log('Listening on ' + port);
});
<|endoftext|>


<commit_before>var myCharacteristic;

function state() {
  var bufferOut;
	var expected = "";
	var end;

	this.start = function(buffer, expectation) {
	  end = 0;
	  bufferOut = buffer;
	  expected = expectation;
	  sendNext(4);
	};

	var sendNext = function(sz) {
    var buffer = new ArrayBuffer(sz);
    var view = new Uint8Array(buffer);
    for (var i = 0; i < sz; i++) {
      view[i] = bufferOut[end + i];
    }
    end += sz;
    console.log("AWUQIEU");
    console.log(view);
    myCharacteristic.writeValue(buffer)
    .catch(error => {
      console.log('Argh! ' + error);
    });
	};

	this.verify = function(received) {
	  if (received == expected) {
	    if (expected == "RD-OK") expected = "k";
	    sendNext(1);
	    return true;
	  }
	  else return false;
	};
}

var TM = new state();

var sendX = function(binary) {
  TM.expected = "RD-OK";
  if (!myCharacteristic) {
    console.log('Argh! ' + 'No connection active!!');
    return;
  }
  var buffer = new ArrayBuffer(binary.length + 4);
  var view = new Uint8Array(buffer);
  view[0] = 82; //Send command in ASCII
  view[1] = 68;
  view[2] = binary.length & 0xFF;
  view[3] = (binary.length >> 8) & 0xFF;
  for (var i in binary) {
    view[i+4] = binary[i];
  }
  console.log(view);
  TM.start(view, "RD-OK");
};

function onStartButtonClick() {
  let serviceUuid = '0x2020';
  if (serviceUuid.startsWith('0x')) {
    serviceUuid = parseInt(serviceUuid, 16);
  }

  let characteristicUuid = '0x2021';
  if (characteristicUuid.startsWith('0x')) {
    characteristicUuid = parseInt(characteristicUuid, 16);
  }

  console.log('Requesting Bluetooth Device...');
  navigator.bluetooth.requestDevice({filters: [{services: [serviceUuid]}]})
  .then(device => device.gatt.connect())
  .then(server => server.getPrimaryService(serviceUuid))
  .then(service => service.getCharacteristic(characteristicUuid))
  .then(characteristic => {
    myCharacteristic = characteristic;
    return myCharacteristic.startNotifications().then(_ => {
      console.log('> Notifications started');
      myCharacteristic.addEventListener('characteristicvaluechanged',
        handleNotifications);
    });
  })
  .catch(error => {
    console.log('Argh! ' + error);
  });
}

function onStopButtonClick() {
  if (myCharacteristic) {
    myCharacteristic.stopNotifications().then(_ => {
      console.log('> Notifications stopped');
      myCharacteristic.removeEventListener('characteristicvaluechanged',
        handleNotifications);
    });
  }
}

function handleNotifications(event) {
  let value = event.target.value;
  let a = [];
  // Convert raw data bytes to hex values just for the sake of showing something.
  // In the "real" world, you'd use data.getUint8, data.getUint16 or even
  // TextDecoder to process raw data bytes.
  for (var i = 0; i < value.byteLength; i++) {
    a.push(String.fromCharCode(value.getUint8(i)));
  }
  var response = a.join('');
  console.log(response);
  TM.verify(response);
}<commit_msg>Protocol related fix<commit_after>var myCharacteristic;

function state() {
  var bufferOut;
	var expected = "";
	var end;

	this.start = function(buffer, expectation) {
	  end = 0;
	  bufferOut = buffer;
	  expected = expectation;
	  sendNext(2); //Command has 2 chars
	};

	var sendNext = function(sz) {
    var buffer = new ArrayBuffer(sz);
    var view = new Uint8Array(buffer);
    for (var i = 0; i < sz; i++) {
      view[i] = bufferOut[end + i];
    }
    end += sz;
    console.log(view);
    myCharacteristic.writeValue(buffer)
    .catch(error => {
      console.log('Argh! ' + error);
    });
	};

	this.verify = function(received) {
	  if (received == expected) {
	    if (expected == "RD-OK") {
	      expected = "k";
	      sendNext(2); //Sends size
	    }
	    else sendNext(1); //Keeps sending code
	    return true;
	  }
	  else return false;
	};
}

var TM = new state();

var sendX = function(binary) {
  TM.expected = "RD-OK";
  if (!myCharacteristic) {
    console.log('Argh! ' + 'No connection active!!');
    return;
  }
  var buffer = new ArrayBuffer(binary.length + 4);
  var view = new Uint8Array(buffer);
  view[0] = 82; //Send command in ASCII
  view[1] = 68;
  view[2] = binary.length & 0xFF;
  view[3] = (binary.length >> 8) & 0xFF;
  for (var i in binary) {
    view[i+4] = binary[i];
  }
  console.log(view);
  TM.start(view, "RD-OK");
};

function onStartButtonClick() {
  let serviceUuid = '0x2020';
  if (serviceUuid.startsWith('0x')) {
    serviceUuid = parseInt(serviceUuid, 16);
  }

  let characteristicUuid = '0x2021';
  if (characteristicUuid.startsWith('0x')) {
    characteristicUuid = parseInt(characteristicUuid, 16);
  }

  console.log('Requesting Bluetooth Device...');
  navigator.bluetooth.requestDevice({filters: [{services: [serviceUuid]}]})
  .then(device => device.gatt.connect())
  .then(server => server.getPrimaryService(serviceUuid))
  .then(service => service.getCharacteristic(characteristicUuid))
  .then(characteristic => {
    myCharacteristic = characteristic;
    return myCharacteristic.startNotifications().then(_ => {
      console.log('> Notifications started');
      myCharacteristic.addEventListener('characteristicvaluechanged',
        handleNotifications);
    });
  })
  .catch(error => {
    console.log('Argh! ' + error);
  });
}

function onStopButtonClick() {
  if (myCharacteristic) {
    myCharacteristic.stopNotifications().then(_ => {
      console.log('> Notifications stopped');
      myCharacteristic.removeEventListener('characteristicvaluechanged',
        handleNotifications);
    });
  }
}

function handleNotifications(event) {
  let value = event.target.value;
  let a = [];
  // Convert raw data bytes to hex values just for the sake of showing something.
  // In the "real" world, you'd use data.getUint8, data.getUint16 or even
  // TextDecoder to process raw data bytes.
  for (var i = 0; i < value.byteLength; i++) {
    a.push(String.fromCharCode(value.getUint8(i)));
  }
  var response = a.join('');
  console.log(response);
  TM.verify(response);
}<|endoftext|>


<commit_before>import {TASKS} from './messageHandler';
import {has, map, merge, split, trim} from 'ramda';
import {QUERY_PARAM, DATABASE_PARAM, TABLES_PARAM} from './errors';

const sequelizeSetup = (connection) => {
    return merge(
        connection ? connection.options : null,
        connection ? connection.config : null
    );
};

const foundParams = (params, wantedParam) => {

    if (Boolean(params) && has(wantedParam, params)) {
        return true;
    }

    return false;
};

export function v0(requestEvent, sequelizeManager, callback) {

    const {connection} = sequelizeManager;

    let task;
    let message;

    const endpoint = split('/', requestEvent.route.path)[2];

    switch (endpoint) {

        case 'connect': {
            task = TASKS.CHECK_CONNECTION_AND_SHOW_DATABASES;
            message = sequelizeSetup(connection);
            break;
        }

        case 'login': {
            task = TASKS.CONNECT_AND_SHOW_DATABASES;
            message = sequelizeSetup(connection);
            break;
        }

        case 'query': {
            task = TASKS.QUERY;
            message = requestEvent.params.statement;
            break;
        }

        case 'tables': {
            task = TASKS.SELECT_DATABASE_AND_SHOW_TABLES;
            message = sequelizeSetup(connection);
            message.database = requestEvent.params.database;
            break;
        }

        case 'disconnect': {
            task = TASKS.DISCONNECT;
            message = sequelizeSetup(connection);
            break;
        }

        default: {
            sequelizeManager.raiseError(
                merge(`Endpoint ${endpoint} is not implemented in API v0.`),
                callback
            );
        }

    }

    return {task, message};

}

export function v1(requestEvent, sequelizeManager, callback) {

    const {connection} = sequelizeManager;

    let task;
    let message;

    const endpoint = split('/', requestEvent.route.path)[2];

    switch (endpoint) {

        case 'connect': {

            /*
             * action: establish connection via config file when headless or
             * ipc payload when not
             * returns: connection state
             */

            task = TASKS.CONNECT;
            message = sequelizeSetup(connection);
            break;

        }

        case 'authenticate': {

            /*
             * action: checks for existing valid connection
             * returns: connection state
             */

            task = TASKS.AUTHENTICATE;
            message = sequelizeSetup(connection);
            break;

        }

        case 'databases': {

            /*
             * action: authenticate, get databases
             * returns: databases list = ['database1', 'database2' ...]
             */

            task = TASKS.DATABASES;
            message = sequelizeSetup(connection);
            break;

        }

        case 'selectdatabase': {

            /*
             * action: authenticate, get databases
             * returns: connection state
             */

            task = TASKS.CONNECT;
            message = sequelizeSetup(connection);

            if (!foundParams(requestEvent.params, 'database')) {
                sequelizeManager.raiseError(
                    {mesasge: DATABASE_PARAM}, callback
                );
            } else {
                message.database = requestEvent.params.database;
            }

            break;
        }

        case 'tables': {

            /*
             * action: authenticate, get tables
             * returns: tables list
             */

            task = TASKS.TABLES;
            message = sequelizeSetup(connection);
            break;

        }

        case 'preview': {

            /*
             * action: authenticate, send top 5 query
             * returns: table preview of 5 rows
             */

            task = TASKS.PREVIEW;

            if (!foundParams(requestEvent.params, 'tables')) {
                sequelizeManager.raiseError(
                    {mesasge: TABLES_PARAM}, callback
                );
            } else {
                message = map(trim(), split(',', requestEvent.params.tables));
            }

            break;

        }

        case 'query': {

            /*
             * action: authenticate, send raw query
             * returns: query response
             */

            task = TASKS.QUERY;

            if (!foundParams(requestEvent.params, 'statement')) {
                sequelizeManager.raiseError(
                    {mesasge: QUERY_PARAM}, callback
                );
            } else {
                message = requestEvent.params.statement;
            }

            break;

        }

        case 'disconnect': {

            /*
             * action: disconnect, authenticate
             * return: connection state object
             */

            task = TASKS.DISCONNECT;
            message = sequelizeSetup(connection);
            break;

        }

        default: {

            sequelizeManager.raiseError(
                merge(`Endpoint ${endpoint} is not implemented in API v1.`),
                callback
            );

        }
    }

    return {task, message};

}
<commit_msg>:see_no_evil: typo<commit_after>import {TASKS} from './messageHandler';
import {has, map, merge, split, trim} from 'ramda';
import {QUERY_PARAM, DATABASE_PARAM, TABLES_PARAM} from './errors';

const sequelizeSetup = (connection) => {
    return merge(
        connection ? connection.options : null,
        connection ? connection.config : null
    );
};

const foundParams = (params, wantedParam) => {

    if (Boolean(params) && has(wantedParam, params)) {
        return true;
    }

    return false;
};

export function v0(requestEvent, sequelizeManager, callback) {

    const {connection} = sequelizeManager;

    let task;
    let message;

    const endpoint = split('/', requestEvent.route.path)[2];

    switch (endpoint) {

        case 'connect': {
            task = TASKS.CHECK_CONNECTION_AND_SHOW_DATABASES;
            message = sequelizeSetup(connection);
            break;
        }

        case 'login': {
            task = TASKS.CONNECT_AND_SHOW_DATABASES;
            message = sequelizeSetup(connection);
            break;
        }

        case 'query': {
            task = TASKS.QUERY;
            message = requestEvent.params.statement;
            break;
        }

        case 'tables': {
            task = TASKS.SELECT_DATABASE_AND_SHOW_TABLES;
            message = sequelizeSetup(connection);
            message.database = requestEvent.params.database;
            break;
        }

        case 'disconnect': {
            task = TASKS.DISCONNECT;
            message = sequelizeSetup(connection);
            break;
        }

        default: {
            sequelizeManager.raiseError(
                merge(`Endpoint ${endpoint} is not implemented in API v0.`),
                callback
            );
        }

    }

    return {task, message};

}

export function v1(requestEvent, sequelizeManager, callback) {

    const {connection} = sequelizeManager;

    let task;
    let message;

    const endpoint = split('/', requestEvent.route.path)[2];

    switch (endpoint) {

        case 'connect': {

            /*
             * action: establish connection via config file when headless or
             * ipc payload when not
             * returns: connection state
             */

            task = TASKS.CONNECT;
            message = sequelizeSetup(connection);
            break;

        }

        case 'authenticate': {

            /*
             * action: checks for existing valid connection
             * returns: connection state
             */

            task = TASKS.AUTHENTICATE;
            message = sequelizeSetup(connection);
            break;

        }

        case 'databases': {

            /*
             * action: authenticate, get databases
             * returns: databases list = ['database1', 'database2' ...]
             */

            task = TASKS.DATABASES;
            message = sequelizeSetup(connection);
            break;

        }

        case 'selectdatabase': {

            /*
             * action: authenticate, get databases
             * returns: connection state
             */

            task = TASKS.CONNECT;
            message = sequelizeSetup(connection);

            if (!foundParams(requestEvent.params, 'database')) {
                sequelizeManager.raiseError(
                    {message: DATABASE_PARAM}, callback
                );
            } else {
                message.database = requestEvent.params.database;
            }

            break;
        }

        case 'tables': {

            /*
             * action: authenticate, get tables
             * returns: tables list
             */

            task = TASKS.TABLES;
            message = sequelizeSetup(connection);
            break;

        }

        case 'preview': {

            /*
             * action: authenticate, send top 5 query
             * returns: table preview of 5 rows
             */

            task = TASKS.PREVIEW;

            if (!foundParams(requestEvent.params, 'tables')) {
                sequelizeManager.raiseError(
                    {message: TABLES_PARAM}, callback
                );
            } else {
                message = map(trim(), split(',', requestEvent.params.tables));
            }

            break;

        }

        case 'query': {

            /*
             * action: authenticate, send raw query
             * returns: query response
             */

            task = TASKS.QUERY;

            if (!foundParams(requestEvent.params, 'statement')) {
                sequelizeManager.raiseError(
                    {message: QUERY_PARAM}, callback
                );
            } else {
                message = requestEvent.params.statement;
            }

            break;

        }

        case 'disconnect': {

            /*
             * action: disconnect, authenticate
             * return: connection state object
             */

            task = TASKS.DISCONNECT;
            message = sequelizeSetup(connection);
            break;

        }

        default: {

            sequelizeManager.raiseError(
                merge(`Endpoint ${endpoint} is not implemented in API v1.`),
                callback
            );

        }
    }

    return {task, message};

}
<|endoftext|>


<commit_before>var presence = require('./model');

function getPresence(params, callback) {
    if (params.uid) {
        var r = presence.get(params.uid);
        callback(undefined, r);
    } else callback();
}

function putPresence(params, callback) {
    if (params.uid && params.cid && params.status)
        presence.register(params.uid, params.cid, params.status);
    callback();
}

function delPresence(params, callback) {
    if (params.uid && params.cid)
        presence.unregister(params.uid, params.cid);
    callback();
}

function postPresenceQ(params, callback) {
    if (params.uid) {
        var r = presence.query(params.uid);
        callback(undefined, r);
    } else callback();
}

function putSubscription(params, callback) {
    if (params.cid && params.uid)
        presence.subscribe(params.cid, params.uid);
    callback();
}

function delSubscription(params, callback) {
    if (params.cid && params.uid)
        presence.unsubscribe(params.cid, params.uid);
    callback();
}

function getSubscriber(params, callback) {
    if(params.uid) {
        var r = presence.subscribers(params.uid);
        callback(undefined, r);
    }
    callback();
}

var route = {
    '/presence': {
        get: getPresence,
        put: putPresence,
        del: delPresence
    },
    '/presence/q': {
        post: postPresenceQ
    },
    '/subscription': {
        put: putSubscription,
        del: delSubscription
    },
    '/subscriber': {
        get: getSubscriber
    }
};

var router = module.exports = function (res, method, params, callback) {
    if (route[res] && route[res][method])
        route[res][method](params, callback);
    else callback();
};<commit_msg>Modify router of presence service<commit_after>var presence = require('./model');

function getPresence(params, callback) {
    if (params.uid) {
        var r = presence.get(params.uid);
        callback(undefined, r);
    } else callback();
}

function putPresence(params, callback) {
    if (params.uid && params.cid && params.status)
        presence.register(params.uid, params.cid, params.status);
    callback();
}

function delPresence(params, callback) {
    if (params.uid && params.cid)
        presence.unregister(params.uid, params.cid);
    callback();
}

function postPresenceQ(params, callback) {
    if (params.uid) {
        var r = presence.query(params.uid);
        callback(undefined, r);
    } else callback();
}

function putSubscription(params, callback) {
    if (params.cid && params.uid)
        presence.subscribe(params.cid, params.uid);
    callback();
}

function delSubscription(params, callback) {
    if (params.cid && params.uid)
        presence.unsubscribe(params.cid, params.uid);
    callback();
}

function getSubscriber(params, callback) {
    if(params.uid) {
        var r = presence.subscribers(params.uid);
        callback(undefined, r);
    }
    callback();
}

var route = {
    '/presence': {
        get: getPresence,
        put: putPresence,
        del: delPresence
    },
    '/presence/q': {
        post: postPresenceQ
    },
    '/subscription': {
        put: putSubscription,
        del: delSubscription
    },
    '/subscriber': {
        get: getSubscriber
    }
};

var router = module.exports = function (res, method, params, callback) {

    if (method == 'delete') method = 'del';

    if (route[res] && route[res][method])
        route[res][method](params, callback);
    else callback();
};<|endoftext|>


<commit_before>var http = require('http'),
    url = require('url'),
    fs = require('fs'),
    ejs = require('ejs'),
    path = require('path'),
    exec = require('child_process').exec,
    util = require('util'),
    zlib = require('zlib');
//var querystring = require('querystring');

var mime_types = {}
var routes = []
//--------------------------------------------------
var Route = function(){

    this.get = new Handler();
    this.post = new Handler();
    return this;
}
//--------------------------------------------------
var Handler = function(){
    return this;
}
//--------------------------------------------------
Handler.prototype.html = function(template_path){
    //load template
    var t = this;
    fs.readFile(template_path, function (err, data) {
          if (err) throw err;
          t.compiled = ejs.compile(String(data));
    });
    return this;
}
//===================================================
Handler.prototype.static = function(base_dir){

    //----------------------------------------------------
    var send_stream = function(fs_path,req,res,headers) {

        fs.stat(fs_path,function(err,stats){

            if(err){
                res.writeHead(404);
                res.end("404 - not found.");
                return;

            }
            var ins = util.inspect(stats);
            var size = ins.match(/size:\s*(\d+)/)[1];
            headers['Content-Length'] = size;

           var flags = {};
           //console.log(req.headers);
           range = req.headers['range'];

           if(range){
                var match = range.match(/^bytes\s*=\s*(\d+)-(\d*)/);
                if(match){
                    var start = parseInt(match[1]);
                    var end = match[2].length > 0 ? parseInt(match[2]) : parseInt(size) -1;
                    headers["Content-Range"] =  'bytes %start-%end/%length'.replace("%start",start).replace("%end",end).replace("%length",size);
                    res.writeHead(206,headers);
                    flags["start"] = start;
                    flags["end"] = end;
                }
                else{
                    res.writeHead(416,headers);
                }
            }
            else
                res.writeHead(200,headers);
            /*fs.readFile(fs_path, function (err, data) {
              if (err)
                throw err;

                res.end(data);
            });*/
            var fstream = fs.createReadStream(fs_path,flags);
            fstream.pipe(res);

        });

        /*}
            kv = range.split("=");
            if(!kv[1])
        }*/
    }
    //----------------------------------------------------
    var send_ogg= function(path,req,res,headers,flags){

       var child = exec("ogginfo %s | grep 'Playback length'".replace("%s",path),
                  function (error, stdout, stderr) {
                      if(error)
                            throw error;

                    var lens = stdout.trim().split(":");
                    var MINUTES = 1, SECONDS = 2;
                    var duration = parseFloat(lens[MINUTES])*60 + parseFloat(lens[SECONDS]);
                    headers['X-Content-Duration'] = String(duration);
                    send_stream(path,req,res,headers);
            });
    }
    //----------------------------------------------------

    if(typeof(base_dir)==="undefined")
        base_dir = "";

    this.send_static = function(file_path,req,res){

        var ext = path.extname(file_path).substring(1),
            mime_type = mime_types[ext],
            fs_path = path.join(path.resolve(base_dir),file_path),
            headers = {'Accept-Ranges': 'bytes','Content-Type':mime_type};

        if(Ys.ogg_header_support && headers["Content-Type"] && headers["Content-Type"].match(/^\w+\/ogg$/)){
            send_ogg(fs_path,req,res,headers);
            return;
        }

        send_stream(fs_path,req,res,headers);
    }
}
//===================================================
Handler.prototype.gzip = function(base_dir){

    if(typeof(base_dir)==="undefined")
        base_dir = "";

    this.send_gzip = function(file_path,req,res){

        var ext = path.extname(file_path).substring(1),
            mime_type = mime_types[ext],
            fs_path = path.join(path.resolve(base_dir),file_path),
            headers = {'Content-Type':mime_type};

        var raw = fs.createReadStream(fs_path);
        write_gzip(raw,req,res,headers);
        /*
        var acceptEncoding = req.headers['accept-encoding'];
        if (!acceptEncoding)
            acceptEncoding = '';

        var stream = raw;

        // Note: this is not a conformant accept-encoding parser.
        // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
        if (acceptEncoding.match(/\bdeflate\b/)) {
            headers['content-encoding'] = 'deflate';
            stream = raw.pipe(zlib.createDeflate());
        } else if (acceptEncoding.match(/\bgzip\b/)) {
            headers['content-encoding'] = 'gzip';
            stream = raw.pipe(zlib.createGzip());
        }

       res.writeHead(200,headers);
       stream.pipe(res);
       */
    }
}
//===================================================
var Ys = exports.Ys = function(url) {

    var idx = -1;
    for(var i=0; i < routes.length; i++){
        if(routes[i][0]===url){
            idx = i;
        }
    }

    if(idx===-1){
        routes.push([url,new Route()]);
        idx = routes.length - 1;
    }

    return routes[idx][1]

}
//--------------------------------------------------
var jsonify = function(object){
    this.end(JSON.stringify(object));
}
//--------------------------------------------------
var htmlify = function(compiled_template){

    return function(object){
        this.end(compiled_template(object));
    }
}
//--------------------------------------------------
var write_gzip = function(raw_stream,req,res,headers){

        var acceptEncoding = req.headers['accept-encoding'];
        if (!acceptEncoding)
            acceptEncoding = '';

        var stream = raw_stream;

        // Note: this is not a conformant accept-encoding parser.
        // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
        if (acceptEncoding.match(/\bdeflate\b/)) {
            headers['content-encoding'] = 'deflate';
            stream = raw_stream.pipe(zlib.createDeflate());
        } else if (acceptEncoding.match(/\bgzip\b/)) {
            headers['content-encoding'] = 'gzip';
            stream = raw_stream.pipe(zlib.createGzip());
        }

       res.writeHead(200,headers);
       stream.pipe(res);
}
//--------------------------------------------------
var PATH_REGEXP = 0, HANDLERS = 1;
var handle_request = function(req,res){

    var pathname = url.parse(req.url).pathname;
    for(var i=0; i < routes.length; i++){
        var regexp = RegExp(routes[i][PATH_REGEXP]);
        var route = routes[i];
        var match = regexp.exec(pathname);
        if(!match)
            continue;

        if(typeof(route[HANDLERS]["redirect"]) === "string"){
            pathname = route[HANDLERS]["redirect"].replace("$1",match[1]);
            res.writeHead(301,{"Location":pathname});
            res.end();
            return;
        }

        if(typeof(route[HANDLERS]["rewrite"]) === "string"){
            pathname = route[HANDLERS]["rewrite"].replace("$1",match[1]);
            continue;
        }

        if(typeof(route[HANDLERS][req.method.toLowerCase()])==="undefined")
            continue;

        if(match.length > 1)
            req.$1 = match[1];

        var handler = route[HANDLERS][req.method.toLowerCase()];
        if(typeof(handler)==="function"){
            handler(req,res);
            return;
        }

        if(typeof(handler)==="object"){

            if("send_gzip" in handler){
                handler.send_gzip(pathname,req,res);
                return;
            }
            if("send_static" in handler){
                handler.send_static(pathname,req,res);
                return;
            }

            if("json" in handler){
                res.writeHead(200, {'Content-Type': 'application/json'});
                res.returnObject = jsonify;
                handler.json(req,res);
                return;
            }

            if("html" in handler){

                res.writeHead(200, {'Content-Type': 'text/html'});
                res.returnObject = htmlify(handler.compiled);
                if("args" in handler)//actual template
                    handler.args(req,res);
                else
                    res.returnObject();
            }

            return;
        }

    }

    throw new Error(pathname +" >> No mapping for this path");
}
//--------------------------------------------------
Ys.run = function(port,host,user){

    if(!port)
        port = 8780;

    if(!host)
        host= "127.0.0.1";

    var mimes_raw  = fs.readFileSync('/etc/mime.types','utf-8').split('\n')
    for(var i=0; i<mimes_raw.length; i++){
        var next = mimes_raw[i].split(/\s+/g)
        if(next && next.length >= 2)
            for(var j=1; j < next.length; j++)
                mime_types[next[j]] = next[0];
    }

    //correction for some types
    //mime_types["mp3"] = "audio/mp3";
    process.on('uncaughtException', function (err) {
            var str = err.stack;
            console.log(str);
            //res.end(str);
    });

    var server = http.createServer(function (req, res) {

        try{
            handle_request(req,res);
        }
        catch(e){
            var str = e.stack;
            console.log(str);
            res.end(str);
        }

    });

    if(user){
        server.once("listening",function(){
            process.setuid(user);
            //process.setgid(user);
        });
    }

    server.listen(port,host);

    console.log('Server running at '+host+':'+port+'/');
}
//--------------------------------------------------
<commit_msg>better error when no handler found for path + method<commit_after>var http = require('http'),
    url = require('url'),
    fs = require('fs'),
    ejs = require('ejs'),
    path = require('path'),
    exec = require('child_process').exec,
    util = require('util'),
    zlib = require('zlib');
//var querystring = require('querystring');

var mime_types = {}
var routes = []
//--------------------------------------------------
var Route = function(){

    this.get = new Handler();
    this.post = new Handler();
    return this;
}
//--------------------------------------------------
var Handler = function(){
    return this;
}
//--------------------------------------------------
Handler.prototype.html = function(template_path){
    //load template
    var t = this;
    fs.readFile(template_path, function (err, data) {
          if (err) throw err;
          t.compiled = ejs.compile(String(data));
    });
    return this;
}
//===================================================
Handler.prototype.static = function(base_dir){

    //----------------------------------------------------
    var send_stream = function(fs_path,req,res,headers) {

        fs.stat(fs_path,function(err,stats){

            if(err){
                res.writeHead(404);
                res.end("404 - not found.");
                return;

            }
            var ins = util.inspect(stats);
            var size = ins.match(/size:\s*(\d+)/)[1];
            headers['Content-Length'] = size;

           var flags = {};
           //console.log(req.headers);
           range = req.headers['range'];

           if(range){
                var match = range.match(/^bytes\s*=\s*(\d+)-(\d*)/);
                if(match){
                    var start = parseInt(match[1]);
                    var end = match[2].length > 0 ? parseInt(match[2]) : parseInt(size) -1;
                    headers["Content-Range"] =  'bytes %start-%end/%length'.replace("%start",start).replace("%end",end).replace("%length",size);
                    res.writeHead(206,headers);
                    flags["start"] = start;
                    flags["end"] = end;
                }
                else{
                    res.writeHead(416,headers);
                }
            }
            else
                res.writeHead(200,headers);
            /*fs.readFile(fs_path, function (err, data) {
              if (err)
                throw err;

                res.end(data);
            });*/
            var fstream = fs.createReadStream(fs_path,flags);
            fstream.pipe(res);

        });

        /*}
            kv = range.split("=");
            if(!kv[1])
        }*/
    }
    //----------------------------------------------------
    var send_ogg= function(path,req,res,headers,flags){

       var child = exec("ogginfo %s | grep 'Playback length'".replace("%s",path),
                  function (error, stdout, stderr) {
                      if(error)
                            throw error;

                    var lens = stdout.trim().split(":");
                    var MINUTES = 1, SECONDS = 2;
                    var duration = parseFloat(lens[MINUTES])*60 + parseFloat(lens[SECONDS]);
                    headers['X-Content-Duration'] = String(duration);
                    send_stream(path,req,res,headers);
            });
    }
    //----------------------------------------------------

    if(typeof(base_dir)==="undefined")
        base_dir = "";

    this.send_static = function(file_path,req,res){

        var ext = path.extname(file_path).substring(1),
            mime_type = mime_types[ext],
            fs_path = path.join(path.resolve(base_dir),file_path),
            headers = {'Accept-Ranges': 'bytes','Content-Type':mime_type};

        if(Ys.ogg_header_support && headers["Content-Type"] && headers["Content-Type"].match(/^\w+\/ogg$/)){
            send_ogg(fs_path,req,res,headers);
            return;
        }

        send_stream(fs_path,req,res,headers);
    }
}
//===================================================
Handler.prototype.gzip = function(base_dir){

    if(typeof(base_dir)==="undefined")
        base_dir = "";

    this.send_gzip = function(file_path,req,res){

        var ext = path.extname(file_path).substring(1),
            mime_type = mime_types[ext],
            fs_path = path.join(path.resolve(base_dir),file_path),
            headers = {'Content-Type':mime_type};

        var raw = fs.createReadStream(fs_path);
        write_gzip(raw,req,res,headers);
        /*
        var acceptEncoding = req.headers['accept-encoding'];
        if (!acceptEncoding)
            acceptEncoding = '';

        var stream = raw;

        // Note: this is not a conformant accept-encoding parser.
        // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
        if (acceptEncoding.match(/\bdeflate\b/)) {
            headers['content-encoding'] = 'deflate';
            stream = raw.pipe(zlib.createDeflate());
        } else if (acceptEncoding.match(/\bgzip\b/)) {
            headers['content-encoding'] = 'gzip';
            stream = raw.pipe(zlib.createGzip());
        }

       res.writeHead(200,headers);
       stream.pipe(res);
       */
    }
}
//===================================================
var Ys = exports.Ys = function(url) {

    var idx = -1;
    for(var i=0; i < routes.length; i++){
        if(routes[i][0]===url){
            idx = i;
        }
    }

    if(idx===-1){
        routes.push([url,new Route()]);
        idx = routes.length - 1;
    }

    return routes[idx][1]

}
//--------------------------------------------------
var jsonify = function(object){
    this.end(JSON.stringify(object));
}
//--------------------------------------------------
var htmlify = function(compiled_template){

    return function(object){
        this.end(compiled_template(object));
    }
}
//--------------------------------------------------
var write_gzip = function(raw_stream,req,res,headers){

        var acceptEncoding = req.headers['accept-encoding'];
        if (!acceptEncoding)
            acceptEncoding = '';

        var stream = raw_stream;

        // Note: this is not a conformant accept-encoding parser.
        // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
        if (acceptEncoding.match(/\bdeflate\b/)) {
            headers['content-encoding'] = 'deflate';
            stream = raw_stream.pipe(zlib.createDeflate());
        } else if (acceptEncoding.match(/\bgzip\b/)) {
            headers['content-encoding'] = 'gzip';
            stream = raw_stream.pipe(zlib.createGzip());
        }

       res.writeHead(200,headers);
       stream.pipe(res);
}
//--------------------------------------------------
var PATH_REGEXP = 0, HANDLERS = 1;
var handle_request = function(req,res){

    var pathname = url.parse(req.url).pathname;
    for(var i=0; i < routes.length; i++){
        var regexp = RegExp(routes[i][PATH_REGEXP]);
        var route = routes[i];
        var match = regexp.exec(pathname);
        if(!match)
            continue;

        if(typeof(route[HANDLERS]["redirect"]) === "string"){
            pathname = route[HANDLERS]["redirect"].replace("$1",match[1]);
            res.writeHead(301,{"Location":pathname});
            res.end();
            return;
        }

        if(typeof(route[HANDLERS]["rewrite"]) === "string"){
            pathname = route[HANDLERS]["rewrite"].replace("$1",match[1]);
            continue;
        }

        if(typeof(route[HANDLERS][req.method.toLowerCase()])==="undefined")
            continue;

        if(match.length > 1)
            req.$1 = match[1];

        var handler = route[HANDLERS][req.method.toLowerCase()];

        function isEmpty(obj) {
            for(var prop in obj)
                if(obj.hasOwnProperty(prop))
                    return false;
            return true;
        }

        if(isEmpty(handler))
            throw new Error(pathname +" >> No handler defined for this path and method "+req.method);

        if(typeof(handler)==="function"){
            handler(req,res);
            return;
        }

        if(typeof(handler)==="object"){

            if("send_gzip" in handler){
                handler.send_gzip(pathname,req,res);
                return;
            }
            if("send_static" in handler){
                handler.send_static(pathname,req,res);
                return;
            }

            if("json" in handler){
                res.writeHead(200, {'Content-Type': 'application/json'});
                res.returnObject = jsonify;
                handler.json(req,res);
                return;
            }

            if("html" in handler){
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.returnObject = htmlify(handler.compiled);
                if("args" in handler)//actual template
                    handler.args(req,res);
                else
                    res.returnObject();

            }

            return;
        }

    }

    throw new Error(pathname +" >> No mapping for this path");
}
//--------------------------------------------------
Ys.run = function(port,host,user){

    if(!port)
        port = 8780;

    if(!host)
        host= "127.0.0.1";

    var mimes_raw  = fs.readFileSync('/etc/mime.types','utf-8').split('\n')
    for(var i=0; i<mimes_raw.length; i++){
        var next = mimes_raw[i].split(/\s+/g)
        if(next && next.length >= 2)
            for(var j=1; j < next.length; j++)
                mime_types[next[j]] = next[0];
    }

    //correction for some types
    //mime_types["mp3"] = "audio/mp3";
    process.on('uncaughtException', function (err) {
            var str = err.stack;
            console.log(str);
            //res.end(str);
    });

    var server = http.createServer(function (req, res) {

        try{
            handle_request(req,res);
        }
        catch(e){
            var str = e.stack;
            console.log(str);
            res.end(str);
        }

    });

    if(user){
        server.once("listening",function(){
            process.setuid(user);
            //process.setgid(user);
        });
    }

    server.listen(port,host);

    console.log('Server running at '+host+':'+port+'/');
}
//--------------------------------------------------
<|endoftext|>


<commit_before>var Game = function(sock, ser) {
  var mapLoader = new MapLoader(emptyMap);

  var GAMEOPTS = {
    w: mapLoader.widthInPixels(),
    h: mapLoader.heightInPixels(),
    color: '#000',
    speed: 4
  };
  this.getOpts = function getOpts(){
    return GAMEOPTS;
  };
  var ANGLES = {n: 0.0, e: 1.57079633, s: 3.1415926, w: 4.71238898} //north, east, south, west
  var REV_ANGLES = {0.0: 'n', 1.57079633: 'e', 3.1415926: 's', 4.71238898: 'w'}
  this.scene = sjs.Scene(GAMEOPTS);

  var socket = sock;
  var background = this.scene.Layer('background', GAMEOPTS);
  var debrisLayer = this.scene.Layer('debris', {w: GAMEOPTS.w, h: GAMEOPTS.h});
  var bulletLayer = this.scene.Layer('bullets', {w: GAMEOPTS.w, h: GAMEOPTS.h});

  // keep all game objects in spritelists
  var debris = sjs.SpriteList([]);
  var players = sjs.SpriteList([]);
  var bullets = sjs.SpriteList([]);
  var bricks = mapLoader.getSpritelistFor(this.scene, background, 1);

  var tank = new Tank(this.scene, background, this);
  tank.reset();

  var input  = new sjs.Input();

  var result = document.getElementById('result');

  // var cycle = new sjs.Cycle([[0, 0, 1]]);
  function paint() {

    // -------- HANDLE BULLETS ----------
    var bul;
    while(bul = bullets.iterate()) {
      bul.applyVelocity();
      bul.update();
      if(bul.x < 0 || bul.y < 0 || bul.x > GAMEOPTS.w || bul.y > GAMEOPTS.h){
          bullets.remove(bul);
          // bul.remove();
      };
      if(bul.collidesWith(tank)){
        bullets.remove(bul);
        explosion(tank);
        tank.reset();
      };
      var collidePlayer;
      if(collidePlayer = bul.collidesWithArray(players)){
        bullets.remove(bul);
        explosion(collidePlayer);
        collidePlayer.reset(true);
      };
    };
    // -------- HANDLE EXPLOSION DEBRIS ---
    var debri;
    while(debri = debris.iterate()) {
        debri.applyVelocity();
        if(debri.rv < 0.001) {
        //if(false){
            debris.remove(debri);
            //debri.remove();
        } else {
            debri.update();
        }
        debri.xv *= 0.95;
        debri.yv *= 0.95;
        debri.rv *= 0.95;
    }

    // canvas backend clears screen automatically, so all players are cleaned as well
    // therefore we need to draw them to each frame. It is not true for html backend
    if (background.useCanvas) {
      var x;
      while(x = players.iterate()){
        x.update();
      }
      while(x = bricks.iterate()){
        x.update();
      }
    };

    if(input.keyboard.left) {
      if (!doesColideWest()){
        tank.move(-GAMEOPTS.speed, 0);
      };
      tank.scale(1, 1);
      tank.setAngle(ANGLES.w);
    }else if(input.keyboard.right) {
      if (!doesColideEast()){
        tank.move(GAMEOPTS.speed, 0);
      };
      tank.scale(-1, 1);
      tank.setAngle(ANGLES.e);
    }else if(input.keyboard.up) {
      if (!doesColideNorth()){
        tank.move(0, -GAMEOPTS.speed);
      };
      tank.scale(1, 1);
      tank.setAngle(ANGLES.n);
    }else if(input.keyboard.down) {
      if (!doesColideSouth()){
        tank.move(0, GAMEOPTS.speed);
      };
      tank.scale(-1, 1);
      tank.setAngle(ANGLES.s);
    }

    if(input.keyboard.space){
      tank.shoot();
    };

    tank.update();

    if(ticker.currentTick % 30 == 0) {
        result.innerHTML = ' ' + ticker.load + '%';
    }
    socket.send(ser.serialize(ser.MSG_PLAYER_POSITION, {x: tank.x, y: tank.y, a: REV_ANGLES[tank.angle]}));
  };

  // TODO: move to tank object
  var doesColideWest = function(){
    // with game world
    if((tank.x - GAMEOPTS.speed) <= 0.0){
      return true;
    };
    return false;
  };
  var doesColideEast = function(){
    if((tank.x + tank.w) >= GAMEOPTS.w){
      return true;
    };
    return false;
  };
  var doesColideNorth = function(){
    // with game world
    if((tank.y - GAMEOPTS.speed) <= 0.0){
      return true;
    };
    return false;
  };
  var doesColideSouth = function(){
    if((tank.y + tank.h) >= GAMEOPTS.h){
      return true;
    };
    return false;
  };

  // creates a cloud of debris and adds randov velocities to each particle
  // adds all debris to the list. Does nothing to original sprite (i.e. removal of it
  // has to be done out of this function)
  var explosion = function explosion(sprite){
    if(Math.random() > 0.5) {
      var x = 4 + Math.random() * 24 | 0;
      var y = 4 + Math.random() * 24 | 0;
      var _debris = sprite.explode4(x, y, debrisLayer);
    } else {
      var horizontal = Math.random() > 0.5;
      var position = 4 + Math.random() * 24 | 0;
      var _debris = sprite.explode2(position, horizontal, debrisLayer);
    }
    for (var j=0; j < _debris.length; j++) {
      var part = _debris[j];
      part.xv = 7 * (Math.random() - 0.5)
      part.yv = 7 * (Math.random() - 0.5)
      part.rv = Math.random() / 2;
      part.applyVelocity();
    }
    debris.add(_debris);
  }
  // msg: {x : x position, y: y position, xv: x velocity, yv: y velocity}
  // send: optional parameter. If true then other players will receive info about bullet.
  // send is only used for locally created bullets
  this.addBullet = function(msg, send){
    var speed_multipl = 1.2;
    var b = this.scene.Sprite(null, bulletLayer);
    b.position(msg.x, msg.y);
    b.size(4, 4);
    b.setColor('#fff');
    b.xv = msg.xv;
    b.yv = msg.yv;
    b.update();
    bullets.add(b);
    if (send){
      socket.send(ser.serialize(ser.MSG_NEW_BULLET, {x: b.x, y: b.y, xv: b.xv, yv: b.yv}));
    };
    return b;
  };

  this.createPlayer = function(id){
    var tmpPlayer = new Tank(this.scene, background, this);
    // var tmpPlayer = this.scene.Sprite('assets/images/tank.png', background);
    tmpPlayer.move(50, 80);
    tmpPlayer.size(32, 32);
    tmpPlayer.id = id; //ugh, adding id property to sprite illegaly
    players.add(tmpPlayer);
    tmpPlayer.update();
    console.log("I haz " + players.length + " playerz now");
  };

  // msg is a hash of {i: id, x: x, y: y}
  this.updatePlayer = function(msg){
    var player;
    while (player = players.iterate()) {
      if(msg.i == player.id){
        player.setX(msg.x)
        player.setY(msg.y);
        player.setAngle(ANGLES[msg.a]);
        player.update();
      };
    };
  };

  this.removePlayer = function(id){
    var player;
    while (player = players.iterate()) {
    if(player.id == id){
      //player.remove();
      players.remove(player);
      break;
    };
    console.log("I haz " + players.lenght + " players now");
  };
  };
  var ticker = this.scene.Ticker(35, paint);
  ticker.run();
};
<commit_msg>performance improvements for canvas frontent<commit_after>var Game = function(sock, ser) {
  var mapLoader = new MapLoader(emptyMap);

  var GAMEOPTS = {
    w: mapLoader.widthInPixels(),
    h: mapLoader.heightInPixels(),
    color: '#000',
    speed: 4
  };
  this.getOpts = function getOpts(){
    return GAMEOPTS;
  };
  var ANGLES = {n: 0.0, e: 1.57079633, s: 3.1415926, w: 4.71238898} //north, east, south, west
  var REV_ANGLES = {0.0: 'n', 1.57079633: 'e', 3.1415926: 's', 4.71238898: 'w'}
  this.scene = sjs.Scene(GAMEOPTS);

  var socket = sock;
  var staticOpts = GAMEOPTS;
  staticOpts['autoClear'] = false;
  var staticLayer = this.scene.Layer('staticLayer', staticOpts );
  var dinamicLayer = this.scene.Layer('dinamicLayer', {w: GAMEOPTS.w, h: GAMEOPTS.h});

  // keep all game objects in spritelists
  var debris = sjs.SpriteList([]);
  var players = sjs.SpriteList([]);
  var bullets = sjs.SpriteList([]);
  var bricks = mapLoader.getSpritelistFor(this.scene, staticLayer, 1);

  var tank = new Tank(this.scene, dinamicLayer, this);
  tank.reset();

  var input  = new sjs.Input();

  var result = document.getElementById('result');

  var bricksDrawn = false; // we only need to draw bricks once, as staticLayer is set to not autoclear;
  // var cycle = new sjs.Cycle([[0, 0, 1]]);
  function paint() {

    // -------- HANDLE BULLETS ----------
    var bul;
    while(bul = bullets.iterate()) {
      bul.applyVelocity();
      bul.update();
      if(bul.x < 0 || bul.y < 0 || bul.x > GAMEOPTS.w || bul.y > GAMEOPTS.h || bul.collidesWithArray(bricks)){
          bullets.remove(bul);
          // bul.remove();
      };
      if(bul.collidesWith(tank)){
        bullets.remove(bul);
        explosion(tank);
        tank.reset();
      };
      var collidePlayer;
      if(collidePlayer = bul.collidesWithArray(players)){
        bullets.remove(bul);
        explosion(collidePlayer);
        collidePlayer.reset(true);
      };
    };
    // -------- HANDLE EXPLOSION DEBRIS ---
    var debri;
    while(debri = debris.iterate()) {
        debri.applyVelocity();
        if(debri.rv < 0.001) {
        //if(false){
            debris.remove(debri);
            //debri.remove();
        } else {
            debri.update();
        }
        debri.xv *= 0.95;
        debri.yv *= 0.95;
        debri.rv *= 0.95;
    }

    // canvas backend clears screen automatically, so all players are cleaned as well
    // therefore we need to draw them to each frame. It is not true for html backend
    if (staticLayer.useCanvas) {
      var x;
      while(x = players.iterate()){
        x.update();
      }
      if(!bricksDrawn){ // we only draw it once
        while(x = bricks.iterate()){
          x.update();
        }
        bricksDrawn = true;
      }
    };

    if(input.keyboard.left) {
      if (!doesColideWest()){
        tank.move(-GAMEOPTS.speed, 0);
      };
      tank.scale(1, 1);
      tank.setAngle(ANGLES.w);
    }else if(input.keyboard.right) {
      if (!doesColideEast()){
        tank.move(GAMEOPTS.speed, 0);
      };
      tank.scale(-1, 1);
      tank.setAngle(ANGLES.e);
    }else if(input.keyboard.up) {
      if (!doesColideNorth()){
        tank.move(0, -GAMEOPTS.speed);
      };
      tank.scale(1, 1);
      tank.setAngle(ANGLES.n);
    }else if(input.keyboard.down) {
      if (!doesColideSouth()){
        tank.move(0, GAMEOPTS.speed);
      };
      tank.scale(-1, 1);
      tank.setAngle(ANGLES.s);
    }

    if(input.keyboard.space){
      tank.shoot();
    };

    tank.update();

    if(ticker.currentTick % 30 == 0) {
        result.innerHTML = ' ' + ticker.load + '%';
    }
    socket.send(ser.serialize(ser.MSG_PLAYER_POSITION, {x: tank.x, y: tank.y, a: REV_ANGLES[tank.angle]}));
  };

  // TODO: move to tank object
  var doesColideWest = function(){
    // with game world
    if((tank.x - GAMEOPTS.speed) <= 0.0){
      return true;
    };
    return false;
  };
  var doesColideEast = function(){
    if((tank.x + tank.w) >= GAMEOPTS.w){
      return true;
    };
    return false;
  };
  var doesColideNorth = function(){
    // with game world
    if((tank.y - GAMEOPTS.speed) <= 0.0){
      return true;
    };
    return false;
  };
  var doesColideSouth = function(){
    if((tank.y + tank.h) >= GAMEOPTS.h){
      return true;
    };
    return false;
  };

  // creates a cloud of debris and adds randov velocities to each particle
  // adds all debris to the list. Does nothing to original sprite (i.e. removal of it
  // has to be done out of this function)
  var explosion = function explosion(sprite){
    if(Math.random() > 0.5) {
      var x = 4 + Math.random() * 24 | 0;
      var y = 4 + Math.random() * 24 | 0;
      var _debris = sprite.explode4(x, y, dinamicLayer);
    } else {
      var horizontal = Math.random() > 0.5;
      var position = 4 + Math.random() * 24 | 0;
      var _debris = sprite.explode2(position, horizontal, dinamicLayer);
    }
    for (var j=0; j < _debris.length; j++) {
      var part = _debris[j];
      part.xv = 7 * (Math.random() - 0.5)
      part.yv = 7 * (Math.random() - 0.5)
      part.rv = Math.random() / 2;
      part.applyVelocity();
    }
    debris.add(_debris);
  }
  // msg: {x : x position, y: y position, xv: x velocity, yv: y velocity}
  // send: optional parameter. If true then other players will receive info about bullet.
  // send is only used for locally created bullets
  this.addBullet = function(msg, send){
    var speed_multipl = 1.2;
    var b = this.scene.Sprite(null, dinamicLayer);
    b.position(msg.x, msg.y);
    b.size(4, 4);
    b.setColor('#fff');
    b.xv = msg.xv;
    b.yv = msg.yv;
    b.update();
    bullets.add(b);
    if (send){
      socket.send(ser.serialize(ser.MSG_NEW_BULLET, {x: b.x, y: b.y, xv: b.xv, yv: b.yv}));
    };
    return b;
  };

  this.createPlayer = function(id){
    var tmpPlayer = new Tank(this.scene, dinamicLayer, this);
    tmpPlayer.move(50, 80);
    tmpPlayer.size(32, 32);
    tmpPlayer.id = id; //ugh, adding id property to sprite illegaly
    players.add(tmpPlayer);
    tmpPlayer.update();
    console.log("I haz " + players.length + " playerz now");
  };

  // msg is a hash of {i: id, x: x, y: y}
  this.updatePlayer = function(msg){
    var player;
    while (player = players.iterate()) {
      if(msg.i == player.id){
        player.setX(msg.x)
        player.setY(msg.y);
        player.setAngle(ANGLES[msg.a]);
        player.update();
      };
    };
  };

  this.removePlayer = function(id){
    var player;
    while (player = players.iterate()) {
    if(player.id == id){
      //player.remove();
      players.remove(player);
      break;
    };
    console.log("I haz " + players.lenght + " players now");
  };
  };
  var ticker = this.scene.Ticker(35, paint);
  ticker.run();
};
<|endoftext|>


<commit_before>var todoList = document.getElementById("todo-list");
var todoListPlaceholder = document.getElementById("todo-list-placeholder");
var form = document.getElementById("todo-form");
var todoTitle = document.getElementById("new-todo");
var error = document.getElementById("error");

form.onsubmit = function(event) {
    var title = todoTitle.value;
    createTodo(title, function() {
        reloadTodoList();
    });
    todoTitle.value = "";
    event.preventDefault();
};

function createTodo(title, callback) {
    var createRequest = new XMLHttpRequest();
    createRequest.open("POST", "/api/todo");
    createRequest.setRequestHeader("Content-type", "application/json");
    createRequest.send(JSON.stringify({
        title: title
    }));
    createRequest.onload = function() {
        if (this.status === 201) {
            callback();
        } else {
            error.textContent = "Failed to create item. Server returned " + this.status + " - " + this.responseText;
        }
    };
}

function getTodoList(callback) {
    var createRequest = new XMLHttpRequest();
    createRequest.open("GET", "/api/todo");
    createRequest.onload = function() {
        if (this.status === 200) {
            callback(JSON.parse(this.responseText));
        } else {
            error.textContent = "Failed to get list. Server returned " + this.status + " - " + this.responseText;
        }
    };
    createRequest.send();
}

function reloadTodoList() {
    while (todoList.firstChild) {
        todoList.removeChild(todoList.firstChild);
    }
    todoListPlaceholder.style.display = "block";
    getTodoList(function(todos) {
        todoListPlaceholder.style.display = "none";
        todos.forEach(function(todo) {
            var listItem = document.createElement("li");
            listItem.textContent = todo.title;
            todoList.appendChild(listItem);
        });
    });
}

reloadTodoList();
<commit_msg>Added delete button index.html works<commit_after>var todoList = document.getElementById("todo-list");
var todoListPlaceholder = document.getElementById("todo-list-placeholder");
var form = document.getElementById("todo-form");
var todoTitle = document.getElementById("new-todo");
var error = document.getElementById("error");

form.onsubmit = function(event) {
    var title = todoTitle.value;
    createTodo(title, function() {
        reloadTodoList();
    });
    todoTitle.value = "";
    event.preventDefault();
};

function createTodo(title, callback) {
    var createRequest = new XMLHttpRequest();
    createRequest.open("POST", "/api/todo");
    createRequest.setRequestHeader("Content-type", "application/json");
    createRequest.send(JSON.stringify({
        title: title
    }));
    createRequest.onload = function() {
        if (this.status === 201) {
            callback();
        } else {
            error.textContent = "Failed to create item. Server returned " + this.status + " - " + this.responseText;
        }
    };
}

function getTodoList(callback) {
    var createRequest = new XMLHttpRequest();
    createRequest.open("GET", "/api/todo");
    createRequest.onload = function() {
        if (this.status === 200) {
            callback(JSON.parse(this.responseText));
        } else {
            error.textContent = "Failed to get list. Server returned " + this.status + " - " + this.responseText;
        }
    };
    createRequest.send();
}

function reloadTodoList() {
    while (todoList.firstChild) {
        todoList.removeChild(todoList.firstChild);
    }
    todoListPlaceholder.style.display = "block";
    getTodoList(function(todos) {
        todoListPlaceholder.style.display = "none";
        todos.forEach(function(todo) {
            var listItem = document.createElement("li");
            listItem.textContent = todo.title;
            var deleteButton = document.createElement("button")

            deleteButton.setAttribute("onClick","deleteTodo(" + todo.id + ", reloadTodoList)");
            deleteButton.textContent = "X";
            deleteButton.className  = " deleteButton";
            listItem.appendChild(deleteButton);
            todoList.appendChild(listItem);
        });
    });
}

function deleteTodo(todoId, callback){
    var deleteRequest = new XMLHttpRequest();
    deleteRequest.open("DELETE", "/api/todo/" + todoId);
    deleteRequest.onload = function(){
         if (this.status === 200) {
            callback();
        } else {
            error.textContent = "Failed to delete item. Server returned " + this.status + " - " + this.responseText;
        }
    }
    deleteRequest.send();
}

reloadTodoList();
<|endoftext|>


<commit_before>// jQuery
var $renderPort = $('#renderPort');

// SocketIO
var socket = io();
var connected = false;

// Phone variables
var vX = 0, vY = 0, vZ = 0,
  sX = 0, sY = 0, sZ = 0,
  alpha = 0, beta = 0, gamma = 0;

// 3D Scene variables
var scene, camera, renderer, cube;

// Setup 3D scene
function setupScene() {
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera( 75, $renderPort.width()/$renderPort.height(), 0.1, 1000);
  renderer = new THREE.WebGLRenderer();
  renderer.setSize( $renderPort.width(), $renderPort.height() );
  $renderPort.append( renderer.domElement );
  camera.position.z = 300;
}

function addCube() {
  var geometry = new THREE.BoxGeometry( 100,100,100 );
  var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 });
  cube = new THREE.Mesh( geometry, material );
  scene.add( cube );
}

var render = function () {
  requestAnimationFrame( render );
  cube.rotation.x = alpha/100;
  cube.rotation.y = beta/100;
  cube.rotation.z = gamma/100;
  // cube.position.x = sX/100;
  // cube.position.y = sY/100;
  // cube.position.z = sZ/100;

  renderer.render( scene, camera );
}

// Kickstart
setupScene();
addCube();
render();

// Check connection
socket.on('connection', function() {
  connected = true;
});

// If client has accelerometer and gyro data
if (window.DeviceMotionEvent) {
  window.addEventListener('devicemotion', function (data) {
    var acc = data.acceleration;
    // vel and displacement yet
    var phoneData = {
      accelerometer: acc,
      velocity: {},
      displacement: {},
      rotationRate: data.rotationRate,
      interval: data.interval
    };
    socket.emit('phone-data', phoneData);
  }, false);
}

socket.on('phone-data', function (data) {
  if (Math.abs(data.accelerometer.x) > 0.5 || Math.abs(data.accelerometer.y) > 0.5 || Math.abs(data.accelerometer.z) > 0.5) {
    // Update velocity
    vX = data.velocity.vX;
    vY = data.velocity.vY;
    vZ = data.velocity.vZ;

    // Update displacement
    sX = data.displacement.sX;
    sY = data.displacement.sY;
    sZ = data.displacement.sZ;

    // Update rotationRate
    alpha = data.rotationRate.alpha;
    beta = data.rotationRate.beta;
    gamma = data.rotationRate.gamma;
  } else {
    sX = sY = sZ = vX= vY = vZ = 0;
  }
});<commit_msg>Figuring out parameters some more. Difficult.<commit_after>// jQuery
var $renderPort = $('#renderPort');

// SocketIO
var socket = io();
var connected = false;

// Phone variables
var vX = 0, vY = 0, vZ = 0,
  sX = 0, sY = 0, sZ = 0,
  alpha = 0, beta = 0, gamma = 0;

// 3D Scene variables
var scene, camera, renderer, cube;

// Setup 3D scene
function setupScene() {
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera( 75, $renderPort.width()/$renderPort.height(), 0.1, 1000);
  renderer = new THREE.WebGLRenderer();
  renderer.setSize( $renderPort.width(), $renderPort.height() );
  $renderPort.append( renderer.domElement );
  camera.position.z = 300;
}

function addCube() {
  var geometry = new THREE.BoxGeometry( 100,100,100 );
  var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 });
  cube = new THREE.Mesh( geometry, material );
  scene.add( cube );
}

var render = function () {
  requestAnimationFrame( render );
  cube.rotation.x = alpha/100;
  cube.rotation.y = beta/100;
  cube.rotation.z = gamma/100;
  cube.position.x = sX/100;
  cube.position.y = sY/100;
  cube.position.z = sZ/100;

  renderer.render( scene, camera );
}

// Kickstart
setupScene();
addCube();
render();

// Check connection
socket.on('connection', function() {
  connected = true;
});

// If client has accelerometer and gyro data
if (window.DeviceMotionEvent) {
  window.addEventListener('devicemotion', function (data) {
    var acc = data.acceleration;
    // vel and displacement yet
    var phoneData = {
      accelerometer: acc,
      velocity: {},
      displacement: {},
      rotationRate: data.rotationRate,
      interval: data.interval
    };
    socket.emit('phone-data', phoneData);
  }, false);
}

socket.on('phone-data', function (data) {
  if (Math.abs(data.accelerometer.x) > 0.5 || Math.abs(data.accelerometer.y) > 0.5 || Math.abs(data.accelerometer.z) > 0.5) {
    // Update velocity
    vX = data.velocity.vX;
    vY = data.velocity.vY;
    vZ = data.velocity.vZ;

    // Update displacement
    sX = data.displacement.sX;
    sY = data.displacement.sY;
    sZ = data.displacement.sZ;

    // Update rotationRate
    alpha = data.rotationRate.alpha;
    beta = data.rotationRate.beta;
    gamma = data.rotationRate.gamma;
  } else {
    sX = sY = sZ = vX= vY = vZ = 0;
  }
});<|endoftext|>


<commit_before>/*
    Date: 2016-01-05
*/
var app = {
    self : {},

    onDeviceReady : function () {
        $('#appState').html('deviceready');
        console.log("device ready.");
        //alert("device ready.");
        if (device.platform === "iOS") {
            $('#appState').html('iOS');
            // hide Exit button. They don't have one on iOS devices.
            // http://www.mzcart.com/javascript-how-to-addremove-css-class-from-a-dom-element/
            document.getElementById('exitApp').classList.add("hidden");
            // deals with post-iOS-7 change that covers the status bar
            // http://coenraets.org/blog/2013/09/phonegap-and-cordova-with-ios-7/
            document.body.style.marginTop = "20px";
            // hide the Splash Screen for iOS only
            navigator.splashscreen.hide();
        } else if (device.platform == 'Android') {
            $('#appState').html('Android');
            // Get rid of 300ms delay
            document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false);
            // trap the [back button]
            document.addEventListener("backbutton", app.onBackButton, false);
            // exit app on [exit button]
            document.getElementById('exitApp').addEventListener('click', function() { app.exit(); });
        } else if (device.platform == 'browser') {
            document.getElementById('exitApp').addEventListener('click', function() { alert('app.exit'); });
        }
        /////////////////////////////////////////////////////////
        // Trap the pause/resume event
        document.addEventListener("pause",  app.onPause, false);
        document.addEventListener("resume", app.onResume, false);
        // Write device information to screen
        // document.getElementById('cordova').innerHTML = device.cordova;
        document.getElementById('model').innerHTML      = device.model;
        document.getElementById('version').innerHTML    = device.version;
        /////////////////////////////////////////////////////////
        // Initialize the app module
        app.init();
        // Test the localStore and report to 'id=storeavailable'
        if (localStore.test('#storeavailable')) {
            localStore.clear();
            localStore.put('0','https://cordova.apache.org/feed.xml');
            localStore.put('1','http://feeds.feedburner.com/RaymondCamdensBlog?format=xml');
            localStore.put('2','http://devgirl.org/feed/');
            localStore.put('3','https://iphonedevlog.wordpress.com/feed/');
            localStore.put('4','http://feeds.feedburner.com/AndrewMcgivery?format=xml');
            $('#Cordova').html(localStore.get('0'));
        }
        // Initialize the Reader
        readerApp.init();
        // setup dynamic button linker
        buttons.init({
            list:    '.contentLink',
            story:   '#toggleStory',
            browser: '#readMore'
        });
        // reset the need for a Feed
        readerApp.needFeed = true;
        // get the first RSS feed on startup
        $('#getData').trigger('click');
        $('#appState').html('deviceready done.');
    },
    init : function () {
        console.log('app.init');
        $('#appState').html('app.init');
    },
    onPause : function () {
        console.log('app.onPause');
        $('#appState').html('app.onPause');
    },
    onResume : function () {
        console.log('app.onResume');
        $('#appState').html('app.onResume');
    },
    onBackButton : function () {
        // Don't do anything. Ingore button, for now.
        $('#appState').html('app.onBackButton');
    },
    exit : function () {
        console.log('Called app.exit()');
        $('#appState').html('app.exit');
        if ('app' in navigator) {
            navigator.app.exitApp();
        } else {
            alert('exit button hit.');
            // This is here to deal with a bug on LG Leon - which I own.
            navigator.app.exitApp();
        }
    }
};

// This is to have the 'deviceready' code from firing in a webbrowser.
var device = {platform:'browser'};

document.getElementById('appState').innerHTML = "dom loaded";
// Thanks http://www.quirksmode.org/js/detect.html
if ('mozApps' in navigator) {
    document.addEventListener("DOMContentLoaded", app.onDeviceReady, false);
    document.getElementById("product").innerHTML = "got mozApps";
} else {
    document.addEventListener("deviceready", app.onDeviceReady, false);
    document.getElementById("product").innerHTML  = JSON.stringify(navigator);
    document.getElementById('appState').innerHTML = "addEventListener - deviceready";
}
<commit_msg>update<commit_after>/*
    Date: 2016-01-05
*/
var app = {
    self : {},

    onDeviceReady : function () {
        $('#appState').html('deviceready');
        console.log("device ready.");
        //alert("device ready.");
        if (device.platform === "iOS") {
            $('#appState').html('iOS');
            // hide Exit button. They don't have one on iOS devices.
            // http://www.mzcart.com/javascript-how-to-addremove-css-class-from-a-dom-element/
            document.getElementById('exitApp').classList.add("hidden");
            // deals with post-iOS-7 change that covers the status bar
            // http://coenraets.org/blog/2013/09/phonegap-and-cordova-with-ios-7/
            document.body.style.marginTop = "20px";
            // hide the Splash Screen for iOS only
            navigator.splashscreen.hide();
        } else if (device.platform == 'Android') {
            $('#appState').html('Android');
            // Get rid of 300ms delay
            document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false);
            // trap the [back button]
            document.addEventListener("backbutton", app.onBackButton, false);
            // exit app on [exit button]
            document.getElementById('exitApp').addEventListener('click', function() { app.exit(); });
        } else if (device.platform == 'browser') {
            document.getElementById('exitApp').addEventListener('click', function() { alert('app.exit'); });
        }
        /////////////////////////////////////////////////////////
        // Trap the pause/resume event
        document.addEventListener("pause",  app.onPause, false);
        document.addEventListener("resume", app.onResume, false);
        // Write device information to screen
        // document.getElementById('cordova').innerHTML = device.cordova;
        document.getElementById('model').innerHTML      = device.model;
        document.getElementById('version').innerHTML    = device.version;
        /////////////////////////////////////////////////////////
        // Initialize the app module
        app.init();
        // Test the localStore and report to 'id=storeavailable'
        if (localStore.test('#storeavailable')) {
            localStore.clear();
            localStore.put('0','https://cordova.apache.org/feed.xml');
            localStore.put('1','http://feeds.feedburner.com/RaymondCamdensBlog?format=xml');
            localStore.put('2','http://devgirl.org/feed/');
            localStore.put('3','https://iphonedevlog.wordpress.com/feed/');
            localStore.put('4','http://feeds.feedburner.com/AndrewMcgivery?format=xml');
            $('#Cordova').html(localStore.get('0'));
        }
        // Initialize the Reader
        readerApp.init();
        // setup dynamic button linker
        buttons.init({
            list:    '.contentLink',
            story:   '#toggleStory',
            browser: '#readMore'
        });
        // reset the need for a Feed
        readerApp.needFeed = true;
        // get the first RSS feed on startup
        setTimeout (function () {
            $('#getData').trigger('click');
        },2000);
        $('#appState').html('deviceready done.');
    },
    init : function () {
        console.log('app.init');
        $('#appState').html('app.init');
    },
    onPause : function () {
        console.log('app.onPause');
        $('#appState').html('app.onPause');
    },
    onResume : function () {
        console.log('app.onResume');
        $('#appState').html('app.onResume');
    },
    onBackButton : function () {
        // Don't do anything. Ingore button, for now.
        $('#appState').html('app.onBackButton');
    },
    exit : function () {
        console.log('Called app.exit()');
        $('#appState').html('app.exit');
        if ('app' in navigator) {
            navigator.app.exitApp();
        } else {
            alert('exit button hit.');
            // This is here to deal with a bug on LG Leon - which I own.
            navigator.app.exitApp();
        }
    }
};

// This is to have the 'deviceready' code from firing in a webbrowser.
var device = {platform:'browser'};

document.getElementById('appState').innerHTML = "dom loaded";
// Thanks http://www.quirksmode.org/js/detect.html
if ('mozApps' in navigator) {
    document.addEventListener("DOMContentLoaded", app.onDeviceReady, false);
    document.getElementById("product").innerHTML = "got mozApps";
} else {
    document.addEventListener("deviceready", app.onDeviceReady, false);
    document.getElementById("product").innerHTML  = JSON.stringify(navigator);
    document.getElementById('appState').innerHTML = "addEventListener - deviceready";
}
<|endoftext|>


<commit_before>window.IgvView = Backbone.View.extend({

    className: 'igv-container',

    initialize: function (options) {
        this.individuals = options.individuals;

        var tracks = [];
        for (var i = 0; i < this.individuals.length; i += 1) {
            var indiv = this.individuals[i];
            if (!indiv.read_data_is_available) {
                continue;
            }

            var alignmentTrack = {
                url: "/project/" + indiv.project_id + "/igv-track/" + indiv.indiv_id,
                type: 'bam',
                indexed: true,
                alignmentShading: 'strand',
                name: ' ' + indiv.indiv_id,
                height: 300,
                minHeight: 300,
                autoHeight: false,
            }

            if (indiv.read_data_format == 'cram') {
                alignmentTrack.sourceType = 'pysam'
                alignmentTrack.url = "/project/" + indiv.project_id + "/igv-track/" + indiv.indiv_id
                alignmentTrack.alignmentFile = alignmentTrack.url
                alignmentTrack.referenceFile = alignmentTrack.url
                options.genome = "hg38" //this is a temporary hack - TODO add explicit support for grch38
            }

            tracks.push(alignmentTrack);
        }

        //initialize IGV.js browser
        if (options.genome == "hg38" || options.genome == "GRCh38") {
            if (!options.gencodeUrl) {
                options.gencodeVersion = "gencode GRCh38v27";
                options.gencodeUrl = 'https://storage.googleapis.com/seqr-reference-data/GRCh37/gencode/gencode.v27.annotation.sorted.gtf.gz';
            }
        } else {
            if (!options.genome) {
                options.genome = "hg19"
            }
            if (!options.gencodeUrl) {
                options.gencodeVersion = "gencode GRCh37/v27";
                options.gencodeUrl = 'https://storage.googleapis.com/seqr-reference-data/GRCh37/gencode/gencode.v27lift37.annotation.sorted.gtf.gz';
            }
        }

        tracks.push({
            url: options.gencodeUrl,
            name: options.gencodeVersion,
            //displayMode: "EXPANDED",
            displayMode: "SQUISHED",
        });

        this.options = {
            showCommandBar: true,
            genome: options.genome,
            locus: options.locus,
            showKaryo: false,
            tracks: tracks,
            showCenterGuide: true,
            showCursorTrackingGuide: true,
        };

        igv.createBrowser(this.el, this.options);
        igv.CoverageMap.threshold = 0.1;
        igv.browser.pixelPerBasepairThreshold = function () {
            return 28.0;  //allow zooming in further - default is currently 14.0
        };

    },

    jump_to_locus: function (locus) {
        //locus must be a string like : 'chr1:12345-54321'
        igv.browser.search(locus);
    }
});
<commit_msg>Fixed gencode path for grch38<commit_after>window.IgvView = Backbone.View.extend({

    className: 'igv-container',

    initialize: function (options) {
        this.individuals = options.individuals;

        var tracks = [];
        for (var i = 0; i < this.individuals.length; i += 1) {
            var indiv = this.individuals[i];
            if (!indiv.read_data_is_available) {
                continue;
            }

            var alignmentTrack = {
                url: "/project/" + indiv.project_id + "/igv-track/" + indiv.indiv_id,
                type: 'bam',
                indexed: true,
                alignmentShading: 'strand',
                name: ' ' + indiv.indiv_id,
                height: 300,
                minHeight: 300,
                autoHeight: false,
            }

            if (indiv.read_data_format == 'cram') {
                alignmentTrack.sourceType = 'pysam'
                alignmentTrack.url = "/project/" + indiv.project_id + "/igv-track/" + indiv.indiv_id
                alignmentTrack.alignmentFile = alignmentTrack.url
                alignmentTrack.referenceFile = alignmentTrack.url
                options.genome = "hg38" //this is a temporary hack - TODO add explicit support for grch38
            }

            tracks.push(alignmentTrack);
        }

        //initialize IGV.js browser
        if (options.genome == "hg38" || options.genome == "GRCh38") {
            if (!options.gencodeUrl) {
                options.gencodeVersion = "gencode GRCh38v27";
                options.gencodeUrl = 'https://storage.googleapis.com/seqr-reference-data/GRCh38/gencode/gencode.v27.annotation.sorted.gtf.gz';
            }
        } else {
            if (!options.genome) {
                options.genome = "hg19"
            }
            if (!options.gencodeUrl) {
                options.gencodeVersion = "gencode GRCh37/v27";
                options.gencodeUrl = 'https://storage.googleapis.com/seqr-reference-data/GRCh37/gencode/gencode.v27lift37.annotation.sorted.gtf.gz';
            }
        }

        tracks.push({
            url: options.gencodeUrl,
            name: options.gencodeVersion,
            //displayMode: "EXPANDED",
            displayMode: "SQUISHED",
        });

        this.options = {
            showCommandBar: true,
            genome: options.genome,
            locus: options.locus,
            showKaryo: false,
            tracks: tracks,
            showCenterGuide: true,
            showCursorTrackingGuide: true,
        };

        igv.createBrowser(this.el, this.options);
        igv.CoverageMap.threshold = 0.1;
        igv.browser.pixelPerBasepairThreshold = function () {
            return 28.0;  //allow zooming in further - default is currently 14.0
        };

    },

    jump_to_locus: function (locus) {
        //locus must be a string like : 'chr1:12345-54321'
        igv.browser.search(locus);
    }
});
<|endoftext|>