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

b3p.GPSControl = function(options) {
	initOptions(this,options);

	var me = this;
	var toggle = function(e){
        e = e || window.event;
		me.toggle();
        e.preventDefault();
	};
	var button = document.createElement('button');
	button.addEventListener('click', toggle, false);
	button.addEventListener('touchstart', toggle, false);

	this.element = document.createElement('div');
	this.element.className = 'ol-gps gps-inactive ol-unselectable ol-control';
	this.element.appendChild(button);

	ol.control.Control.call(this, {
		element: this.element,
		target: options.target
	});

	this.tracking = options.tracking ? options.tracking : false;
	if(this.tracking){
		this.toggleStyle();
	}
	this.geolocation = new ol.Geolocation({
		projection: this.map.getView().getProjection(),
		tracking: this.tracking
	});

	this.positionFeature = new ol.Feature();
	this.positionFeature.setStyle(new ol.style.Style({
		image: new ol.style.Circle({
			radius: 6,
			stroke: new ol.style.Stroke({
				color: '#f00',
				width: 2
			}),
			fill: new ol.style.Fill({
              color: '#3399CC'
            })
		}),

	}));

	var me = this;
	this.geolocation.on('change:position', function(event) {
		var coordinates = event.target.getPosition();
		if(me.geolocation.getTracking() && coordinates){
			me.positionFeature.setGeometry( new ol.geom.Point(coordinates));
			me.map.getView().setCenter(coordinates);
			me.map.getView().setZoom(12);
		}
	});

	this.vectorLayer = new ol.layer.Vector({
		map: this.map,
		source: new ol.source.Vector({
			features: [this.positionFeature]
		})
	});

};
ol.inherits(b3p.GPSControl, ol.control.Control);

b3p.GPSControl.prototype.getLocation = function(returnFunction){
	var loc = this.geolocation.getPosition();
	if(loc === undefined){
		if(!this.tracking){
			this.toggle();
		}
		var f = function(event){
		    returnFunction(event.target.getPosition());
		};
		this.geolocation.once('change:position',f);
	}else{
		returnFunction(loc);
	}
}

b3p.GPSControl.prototype.toggle = function() {
	if(this.tracking){
		this.vectorLayer.getSource().clear();
	}else{
		if(this.vectorLayer.getSource().getFeatures().length === 0){
			this.vectorLayer.getSource().addFeature(this.positionFeature);
		}
	}
	this.tracking = !this.tracking;
	this.toggleStyle();
	this.geolocation.setTracking(this.tracking);
};

b3p.GPSControl.prototype.toggleStyle = function() {
	if(!this.tracking){
		this.element.className = this.element.className.replace(/\bgps-active\b/,'gps-inactive');
	}else{
		this.element.className = this.element.className.replace(/\bgps-inactive\b/,'gps-active');
	}
};<commit_msg>Disable after retrieving gps coordinate<commit_after>/*
 * Copyright (C) 2015-2016 B3Partners B.V.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

b3p.GPSControl = function(options) {
	initOptions(this,options);

	var me = this;
	var toggle = function(e){
        e = e || window.event;
		me.toggle();
        e.preventDefault();
	};
	var button = document.createElement('button');
	button.addEventListener('click', toggle, false);
	button.addEventListener('touchstart', toggle, false);

	this.element = document.createElement('div');
	this.element.className = 'ol-gps gps-inactive ol-unselectable ol-control';
	this.element.appendChild(button);

	ol.control.Control.call(this, {
		element: this.element,
		target: options.target
	});

	this.tracking = options.tracking ? options.tracking : false;
	if(this.tracking){
		this.toggleStyle();
	}
	this.geolocation = new ol.Geolocation({
		projection: this.map.getView().getProjection(),
		tracking: this.tracking
	});

	this.positionFeature = new ol.Feature();
	this.positionFeature.setStyle(new ol.style.Style({
		image: new ol.style.Circle({
			radius: 6,
			stroke: new ol.style.Stroke({
				color: '#f00',
				width: 2
			}),
			fill: new ol.style.Fill({
              color: '#3399CC'
            })
		}),

	}));

	var me = this;
	this.geolocation.on('change:position', function(event) {
		var coordinates = event.target.getPosition();
		if(me.geolocation.getTracking() && coordinates){
			me.positionFeature.setGeometry( new ol.geom.Point(coordinates));
			me.map.getView().setCenter(coordinates);
			me.map.getView().setZoom(12);
		}
	});

	this.vectorLayer = new ol.layer.Vector({
		map: this.map,
		source: new ol.source.Vector({
			features: [this.positionFeature]
		})
	});

};
ol.inherits(b3p.GPSControl, ol.control.Control);

b3p.GPSControl.prototype.getLocation = function(returnFunction){
	var loc = this.geolocation.getPosition();
	if(loc === undefined){
		var me = this;
		if(!this.tracking){
			this.toggle();
		}
		var f = function(event){
			me.toggle();
		    returnFunction(event.target.getPosition());
		};
		this.geolocation.once('change:position',f);
	}else{
		returnFunction(loc);
	}
}

b3p.GPSControl.prototype.toggle = function() {
	if(this.tracking){
		this.vectorLayer.getSource().clear();
	}else{
		if(this.vectorLayer.getSource().getFeatures().length === 0){
			this.vectorLayer.getSource().addFeature(this.positionFeature);
		}
	}
	this.tracking = !this.tracking;
	this.toggleStyle();
	this.geolocation.setTracking(this.tracking);
};

b3p.GPSControl.prototype.toggleStyle = function() {
	if(!this.tracking){
		this.element.className = this.element.className.replace(/\bgps-active\b/,'gps-inactive');
	}else{
		this.element.className = this.element.className.replace(/\bgps-inactive\b/,'gps-active');
	}
};<|endoftext|>


<commit_before>var _ = require('underscore');

var DEFAULT_DISPLAY_INTERVAL = 100;

function QueryStats(name, opts) {
  this.name    = name;
  this.by_client = [];
  this.by_server = [];
  this.queries = 0;
  this.options = opts;
  this.start_time   = null;
  if (!('interval' in this.options))
    this.options.interval = DEFAULT_DISPLAY_INTERVAL;
}

QueryStats.prototype.start = function(id) {
  if (this.start_time === null)
    this.start_time = new Date();
}

QueryStats.prototype.prune_old = function(recs) {
  var now = new Date();
  while ((now - recs[0].end) > this.options.timeout)
    recs.shift(1);
}

QueryStats.prototype.done = function(id, start, server_time) {
  var now = new Date();
  var rec = {
    id: id,
    time: now - start,
    start: start,
    end: now,
  };
  this.by_client.push(rec);
  rec = {
    id: id,
    time: server_time,
    start: start,
    end: now,
  };
  this.by_server.push(rec);
  this.queries++;

  if (this.options.timeout) {
    this.prune_old(this.by_client);
    this.prune_old(this.by_server);
  }

  return (this.queries % this.options.interval) === 0;
}

QueryStats.prototype.get_percentile = function (records, out) {
  var qs = _(records).sortBy(
    function (r) {
      return r.time;
    });

  [50, 90, 95, 99].forEach(
    function (n) {
      out[n] = qs[Math.floor(n/100 * qs.length)].time;
    });
}

QueryStats.prototype.stats = function() {

  var stats = {percentile: {},
               srv_percentile: {}};

  this.get_percentile(this.by_client, stats.percentile);
  this.get_percentile(this.by_server, stats.srv_percentile);

  stats.qps = 1000 * this.queries / (new Date() - this.start_time);

  return stats;
}

module.exports = QueryStats;
<commit_msg>Tweak and improve query-stats logic.<commit_after>var _ = require('underscore');

var DEFAULT_DISPLAY_INTERVAL = 100;

function QueryStats(name, opts) {
  this.name    = name;
  this.records = [];
  this.queries = 0;
  this.options = opts;
  this.start_time   = null;
  if (!('interval' in this.options))
    this.options.interval = DEFAULT_DISPLAY_INTERVAL;
}

QueryStats.prototype.start = function(id) {
  if (this.start_time === null)
    this.start_time = new Date();
}

QueryStats.prototype.prune_old = function(recs) {
  var now = new Date();
  while ((now - recs[0].end) > this.options.timeout)
    recs.shift(1);
}

QueryStats.prototype.done = function(id, start, server_time) {
  var now = new Date();
  var rec = {
    id: id,
    time: now - start,
    server_time: server_time,
    start: start,
    end: now,
  };
  this.records.push(rec);
  this.queries++;

  if (this.options.timeout) {
    this.prune_old(this.records);
  }

  return (this.queries % this.options.interval) === 0;
}

QueryStats.prototype.get_percentile = function (field, out) {
  var qs = _(this.records).sortBy(
    function (r) {
      return r[field];
    });

  [50, 90, 95, 99].forEach(
    function (n) {
      out[n] = qs[Math.floor(n/100 * qs.length)][field];
    });
}

QueryStats.prototype.stats = function() {
  var stats = {percentile: {},
               srv_percentile: {}};

  this.get_percentile('time', stats.percentile);
  this.get_percentile('server_time', stats.srv_percentile);

  stats.queries = this.queries;

  var start = this.start_time;
  if (this.options.timeout) {
    start = Math.max(this.start_time, new Date() - this.options.timeout);
  }

  stats.qps = 1000 * this.records.length / (new Date() - start);

  return stats;
}

module.exports = QueryStats;
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Resin.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/**
 * @module Etcher.drive-scanner
 */

const angular = require('angular');
const _ = require('lodash');
const EventEmitter = require('events').EventEmitter;
const electron = require('electron');

if (window.mocha) {
  var path = require('path');
  var srcPath = path.join(__dirname, '..', '..', 'src');
  var drives = electron.remote.require(path.join(srcPath, 'drives'));
  var dialog = electron.remote.require(path.join(srcPath, 'dialog'));
} else {
  var drives = electron.remote.require('./src/drives');
  var dialog = electron.remote.require('./src/dialog');
}

const driveScanner = angular.module('Etcher.drive-scanner', []);

driveScanner.service('DriveScannerService', function($q, $interval, $timeout) {
  let self = this;
  let interval = null;

  /**
   * @summary List of available drives
   * @type {Object[]}
   * @public
   */
  this.drives = [];

  /**
   * @summary Check if there are available drives
   * @function
   * @public
   *
   * @returns {Boolean} whether there are available drives
   *
   * @example
   * if (DriveScannerService.hasAvailableDrives()) {
   *   console.log('There are available drives!');
   * }
   */
  this.hasAvailableDrives = function() {
    return !_.isEmpty(self.drives);
  };

  /**
   * @summary Set the list of drives
   * @function
   * @public
   *
   * @param {Object[]} drives - drives
   *
   * @example
   * DriveScannerService.scan().then(function(drives) {
   *   DriveScannerService.setDrives(drives);
   * });
   */
  this.setDrives = function(drives) {

    // Only update if something has changed
    // to avoid unnecessary DOM manipulations
    // angular.equals ignores $$hashKey by default
    if (!angular.equals(self.drives, drives)) {
      self.drives = drives;
    }
  };

  /**
   * @summary Get available drives
   * @function
   * @public
   *
   * @fulfil {Object[]} - drives
   * @returns {Promise}
   *
   * @example
   * DriveScannerService.scan().then(function(drives) {
   *   console.log(drives);
   * });
   */
  this.scan = function() {
    return $q.when(drives.listRemovable()).catch(dialog.showError);
  };

  /**
   * @summary Scan drives and populate `.drives`
   * @function
   * @public
   *
   * @description
   * This function returns an event emitter instance
   * that emits a `scan` event everything it scans
   * the drives successfully.
   *
   * @param {Number} ms - interval milliseconds
   * @returns {EventEmitter} event emitter instance
   *
   * @example
   * const emitter = DriveScannerService.start(2000);
   *
   * emitter.on('scan', function(drives) {
   *   console.log(drives);
   * });
   */
  this.start = function(ms) {
    let emitter = new EventEmitter();

    const fn = function() {
      return self.scan().then(function(drives) {
        emitter.emit('scan', drives);
        self.setDrives(drives);
      });
    };

    // Call fn after in the next process tick
    // to be able to capture the first run
    // in unit tests.
    $timeout(function() {
      fn();
      interval = $interval(fn, ms);
    });

    return emitter;
  };

  /**
   * @summary Stop scanning drives
   * @function
   * @public
   *
   * @example
   * DriveScannerService.stop();
   */
  this.stop = function() {
    $interval.cancel(interval);
  };

});
<commit_msg>Stop scanner interval before starting a new one<commit_after>/*
 * Copyright 2016 Resin.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/**
 * @module Etcher.drive-scanner
 */

const angular = require('angular');
const _ = require('lodash');
const EventEmitter = require('events').EventEmitter;
const electron = require('electron');

if (window.mocha) {
  var path = require('path');
  var srcPath = path.join(__dirname, '..', '..', 'src');
  var drives = electron.remote.require(path.join(srcPath, 'drives'));
  var dialog = electron.remote.require(path.join(srcPath, 'dialog'));
} else {
  var drives = electron.remote.require('./src/drives');
  var dialog = electron.remote.require('./src/dialog');
}

const driveScanner = angular.module('Etcher.drive-scanner', []);

driveScanner.service('DriveScannerService', function($q, $interval, $timeout) {
  let self = this;
  let interval = null;

  /**
   * @summary List of available drives
   * @type {Object[]}
   * @public
   */
  this.drives = [];

  /**
   * @summary Check if there are available drives
   * @function
   * @public
   *
   * @returns {Boolean} whether there are available drives
   *
   * @example
   * if (DriveScannerService.hasAvailableDrives()) {
   *   console.log('There are available drives!');
   * }
   */
  this.hasAvailableDrives = function() {
    return !_.isEmpty(self.drives);
  };

  /**
   * @summary Set the list of drives
   * @function
   * @public
   *
   * @param {Object[]} drives - drives
   *
   * @example
   * DriveScannerService.scan().then(function(drives) {
   *   DriveScannerService.setDrives(drives);
   * });
   */
  this.setDrives = function(drives) {

    // Only update if something has changed
    // to avoid unnecessary DOM manipulations
    // angular.equals ignores $$hashKey by default
    if (!angular.equals(self.drives, drives)) {
      self.drives = drives;
    }
  };

  /**
   * @summary Get available drives
   * @function
   * @public
   *
   * @fulfil {Object[]} - drives
   * @returns {Promise}
   *
   * @example
   * DriveScannerService.scan().then(function(drives) {
   *   console.log(drives);
   * });
   */
  this.scan = function() {
    return $q.when(drives.listRemovable()).catch(dialog.showError);
  };

  /**
   * @summary Scan drives and populate `.drives`
   * @function
   * @public
   *
   * @description
   * This function returns an event emitter instance
   * that emits a `scan` event everything it scans
   * the drives successfully.
   *
   * @param {Number} ms - interval milliseconds
   * @returns {EventEmitter} event emitter instance
   *
   * @example
   * const emitter = DriveScannerService.start(2000);
   *
   * emitter.on('scan', function(drives) {
   *   console.log(drives);
   * });
   */
  this.start = function(ms) {
    let emitter = new EventEmitter();

    const fn = function() {
      return self.scan().then(function(drives) {
        emitter.emit('scan', drives);
        self.setDrives(drives);
      });
    };

    // Make sure any pending interval is cancelled
    // to avoid potential memory leaks.
    self.stop();

    // Call fn after in the next process tick
    // to be able to capture the first run
    // in unit tests.
    $timeout(function() {
      fn();
      interval = $interval(fn, ms);
    });

    return emitter;
  };

  /**
   * @summary Stop scanning drives
   * @function
   * @public
   *
   * @example
   * DriveScannerService.stop();
   */
  this.stop = function() {
    $interval.cancel(interval);
  };

});
<|endoftext|>


<commit_before>var LocationMap = function() {
  var map = new google.maps.Map(document.getElementById("map_canvas"));
  var drawingManager = new google.maps.drawing.DrawingManager({
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_LEFT,
      drawingModes: [google.maps.drawing.OverlayType.RECTANGLE]
    },
    map: map
  });

  var saveLocation = function(rectangle, method, locationId) {
    var location = {
      id: locationId,
      zoom: map.getZoom(),
      sw_lat: rectangle.getBounds().getSouthWest().lat(),
      sw_lng: rectangle.getBounds().getSouthWest().lng(),
      ne_lat: rectangle.getBounds().getNorthEast().lat(),
      ne_lng: rectangle.getBounds().getNorthEast().lng()
    };
    if (method == 'POST') {
      if (map.getZoom() < 15) {
        alert("Please zoom in a bit further before creating a location.");
        rectangle.setMap(null);
        return;
      }
      location['label'] = prompt("What do you want to call this location?");
      if (!location['label']) {
        rectangle.setMap(null);
        return;
      }
    }
    var opts = {
      lines: 12, // The number of lines to draw
		  length: 7, // The length of each line
		  width: 5, // The line thickness
		  radius: 10, // The radius of the inner circle
		  color: '#fff', // #rbg or #rrggbb
		  speed: 1, // Rounds per second
		  trail: 66, // Afterglow percentage
		  shadow: true // Whether to render a shadow
    };
    var spinner = new Spinner(opts).spin();
    $('#spinner').show().append(spinner.el);

    $.ajax({
      url: "/locations" + (locationId ? "/" + locationId : ""),
      dataType: 'json',
      type: method,
      data: {
        location: location
      },
      success: function(response) {
        spinner.stop();
        $('#spinner').hide();
        var location = response;
        rectangle.setOptions({
          editable: true
        });
        if (method == 'POST') {
          $('#location').append('<option value="' + location.id + '">' + location.label + '</option>');
        }
      }
    });
  };

  google.maps.event.addListener(drawingManager, 'rectanglecomplete', function(rectangle) {
    saveLocation(rectangle, 'POST');
  });

  return {
    blank: function() {
      map.setOptions({
        // The center is in St. Paul at the moment.
        center: new google.maps.LatLng(45.954215, -93.089819),
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      });
    },

    center: function(locationId) {
      $.ajax({
        url: "/locations/" + locationId,
        dataType: 'json',
        success: function(response) {
          var location = response;

          map.setOptions({
            center: new google.maps.LatLng(location.center_lat, location.center_lng),
            zoom: location.zoom || 16,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          });
        }
      });
    },

    draw: function(locationId) {
      $.ajax({
        url: "/locations/" + locationId,
        dataType: 'json',
        success: function(response) {
          var location = response;

          var rectangle = new google.maps.Rectangle();
          rectangle.setOptions({
            editable: true,
            map: map,
            center: new google.maps.LatLng(location.center_lat, location.center_lng),
            bounds: new google.maps.LatLngBounds(
              new google.maps.LatLng(location.sw_lat, location.sw_lng),
              new google.maps.LatLng(location.ne_lat, location.ne_lng)
            )
          });

          google.maps.event.addListener(rectangle, 'bounds_changed', function() {
            saveLocation(rectangle, 'PUT', locationId);
          });
        }
      });
    }
  };
};<commit_msg>Better messaging on zoom levels for location creation<commit_after>var LocationMap = function() {
  var map = new google.maps.Map(document.getElementById("map_canvas"));
  var drawingManager = new google.maps.drawing.DrawingManager({
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_LEFT,
      drawingModes: [google.maps.drawing.OverlayType.RECTANGLE]
    },
    map: map
  });

  var saveLocation = function(rectangle, method, locationId) {
    var location = {
      id: locationId,
      zoom: map.getZoom(),
      sw_lat: rectangle.getBounds().getSouthWest().lat(),
      sw_lng: rectangle.getBounds().getSouthWest().lng(),
      ne_lat: rectangle.getBounds().getNorthEast().lat(),
      ne_lng: rectangle.getBounds().getNorthEast().lng()
    };
    if (method == 'POST') {
      if (map.getZoom() < 15) {
        alert("Please zoom in at least " + (15 - map.getZoom()) + " more time(s) to create a location.");
        rectangle.setMap(null);
        return;
      }
      location['label'] = prompt("What do you want to call this location?");
      if (!location['label']) {
        rectangle.setMap(null);
        return;
      }
    }
    var opts = {
      lines: 12, // The number of lines to draw
		  length: 7, // The length of each line
		  width: 5, // The line thickness
		  radius: 10, // The radius of the inner circle
		  color: '#fff', // #rbg or #rrggbb
		  speed: 1, // Rounds per second
		  trail: 66, // Afterglow percentage
		  shadow: true // Whether to render a shadow
    };
    var spinner = new Spinner(opts).spin();
    $('#spinner').show().append(spinner.el);

    $.ajax({
      url: "/locations" + (locationId ? "/" + locationId : ""),
      dataType: 'json',
      type: method,
      data: {
        location: location
      },
      success: function(response) {
        spinner.stop();
        $('#spinner').hide();
        var location = response;
        rectangle.setOptions({
          editable: true
        });
        if (method == 'POST') {
          $('#location').append('<option value="' + location.id + '">' + location.label + '</option>');
        }
      }
    });
  };

  google.maps.event.addListener(drawingManager, 'rectanglecomplete', function(rectangle) {
    saveLocation(rectangle, 'POST');
  });

  return {
    blank: function() {
      map.setOptions({
        // The center is in St. Paul at the moment.
        center: new google.maps.LatLng(45.954215, -93.089819),
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      });
    },

    center: function(locationId) {
      $.ajax({
        url: "/locations/" + locationId,
        dataType: 'json',
        success: function(response) {
          var location = response;

          map.setOptions({
            center: new google.maps.LatLng(location.center_lat, location.center_lng),
            zoom: location.zoom || 16,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          });
        }
      });
    },

    draw: function(locationId) {
      $.ajax({
        url: "/locations/" + locationId,
        dataType: 'json',
        success: function(response) {
          var location = response;

          var rectangle = new google.maps.Rectangle();
          rectangle.setOptions({
            editable: true,
            map: map,
            center: new google.maps.LatLng(location.center_lat, location.center_lng),
            bounds: new google.maps.LatLngBounds(
              new google.maps.LatLng(location.sw_lat, location.sw_lng),
              new google.maps.LatLng(location.ne_lat, location.ne_lng)
            )
          });

          google.maps.event.addListener(rectangle, 'bounds_changed', function() {
            saveLocation(rectangle, 'PUT', locationId);
          });
        }
      });
    }
  };
};<|endoftext|>


<commit_before>/**
 * @author Filipe Caixeta / http://filipecaixeta.com.br
 *
 * Description: A THREE loader for PCD ascii and binary files.
 *
 * Limitations: Compressed binary files are not supported.
 *
 */

THREE.PCDLoader = function ( manager ) {

	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
	this.littleEndian = true;

};

THREE.PCDLoader.prototype = {

	constructor: THREE.PCDLoader,

	load: function ( url, onLoad, onProgress, onError ) {

		var scope = this;

		var loader = new THREE.FileLoader( scope.manager );
		loader.setResponseType( 'arraybuffer' );
		loader.load( url, function ( data ) {

			onLoad( scope.parse( data, url ) );

		}, onProgress, onError );

	},

	binarryToStr: function ( data ) {

		var charArray = new Uint8Array( data );

		if ( window.TextDecoder !== undefined ) {

			return new TextDecoder().decode( charArray );

		}

		var text = "";
		for ( var i = 0, il = data.byteLength; i < il; i ++ ) {

			text += String.fromCharCode( charArray[ i ] );

		}
		return text;

	},

	parseHeader: function ( data ) {

		var PCDheader = {};
		var result1 = data.search( /[\r\n]DATA\s(\S*)\s/i );
		var result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.substr( result1 - 1 ) );
		PCDheader.data = result2[ 1 ];
		PCDheader.headerLen = result2[ 0 ].length + result1;
		PCDheader.str = data.substr( 0, PCDheader.headerLen );
		// Remove comments
		PCDheader.str = PCDheader.str.replace( /\#.*/gi, "" );
		PCDheader.version = /VERSION (.*)/i.exec( PCDheader.str );
		if ( PCDheader.version != null )
			PCDheader.version = parseFloat( PCDheader.version[ 1 ] );
		PCDheader.fields = /FIELDS (.*)/i.exec( PCDheader.str );
		if ( PCDheader.fields != null )
			PCDheader.fields = PCDheader.fields[ 1 ].split( " " );
		PCDheader.size = /SIZE (.*)/i.exec( PCDheader.str );
		if ( PCDheader.size != null )
			PCDheader.size = PCDheader.size[ 1 ].split( " " ).map( function ( x ) {

				return parseInt( x, 10 );

			} );
		PCDheader.type = /TYPE (.*)/i.exec( PCDheader.str );
		if ( PCDheader.type != null )
			PCDheader.type = PCDheader.type[ 1 ].split( " " );
		PCDheader.count = /COUNT (.*)/i.exec( PCDheader.str );
		if ( PCDheader.count != null )
			PCDheader.count = PCDheader.count[ 1 ].split( " " ).map( function ( x ) {

				return parseInt( x, 10 );

			} );
		PCDheader.width = /WIDTH (.*)/i.exec( PCDheader.str );
		if ( PCDheader.width != null )
			PCDheader.width = parseInt( PCDheader.width[ 1 ] );
		PCDheader.height = /HEIGHT (.*)/i.exec( PCDheader.str );
		if ( PCDheader.height != null )
			PCDheader.height = parseInt( PCDheader.height[ 1 ] );
		PCDheader.viewpoint = /VIEWPOINT (.*)/i.exec( PCDheader.str );
		if ( PCDheader.viewpoint != null )
			PCDheader.viewpoint = PCDheader.viewpoint[ 1 ];
		PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str );
		if ( PCDheader.points != null )
			PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 );
		if ( PCDheader.points == null )
			PCDheader.points = PCDheader.width * PCDheader.height;

		if ( PCDheader.count == null ) {

			PCDheader.count = [];
			for ( var i = 0; i < PCDheader.fields; i ++ )
				PCDheader.count.push( 1 );

		}

		PCDheader.offset = {};
		var sizeSum = 0;
		for ( var i = 0; i < PCDheader.fields.length; i ++ ) {

			if ( PCDheader.data == "ascii" ) {

				PCDheader.offset[ PCDheader.fields[ i ] ] = i;

			} else {

				PCDheader.offset[ PCDheader.fields[ i ] ] = sizeSum;
				sizeSum += PCDheader.size[ i ];

			}

		}
		// For binary only
		PCDheader.rowSize = sizeSum;

		return PCDheader;

	},

	parse: function ( data, url ) {

		var textData = this.binarryToStr( data );

		// Parse the header
		// Header is always ascii format
		var PCDheader = this.parseHeader( textData );

		// Parse the data
		var position = false;
		if ( PCDheader.offset.x != undefined )
			position = new Float32Array( PCDheader.points * 3 );
		var color = false;
		if ( PCDheader.offset.rgb != undefined )
			color = new Float32Array( PCDheader.points * 3 );
		var normal = false;
		if ( PCDheader.offset.normal_x != undefined )
			normal = new Float32Array( PCDheader.points * 3 );

		if ( PCDheader.data == "ascii" ) {

			var offset = PCDheader.offset;
			var pcdData = textData.substr( PCDheader.headerLen );
			var lines = pcdData.split( '\n' );
			var i3 = 0;
			for ( var i = 0; i < lines.length; i ++, i3 += 3 ) {

				var line = lines[ i ].split( " " );
				if ( offset.x != undefined ) {

					position[ i3 + 0 ] = parseFloat( line[ offset.x ] );
					position[ i3 + 1 ] = parseFloat( line[ offset.y ] );
					position[ i3 + 2 ] = parseFloat( line[ offset.z ] );

				}
				if ( offset.rgb != undefined ) {

					var c = new Float32Array( [ parseFloat( line[ offset.rgb ] ) ] );
					var dataview = new DataView( c.buffer, 0 );
					color[ i3 + 0 ] = dataview.getUint8( 0 ) / 255.0;
					color[ i3 + 1 ] = dataview.getUint8( 1 ) / 255.0;
					color[ i3 + 2 ] = dataview.getUint8( 2 ) / 255.0;

				}
				if ( offset.normal_x != undefined ) {

					normal[ i3 + 0 ] = parseFloat( line[ offset.normal_x ] );
					normal[ i3 + 1 ] = parseFloat( line[ offset.normal_y ] );
					normal[ i3 + 2 ] = parseFloat( line[ offset.normal_z ] );

				}

			}

		}

		if ( PCDheader.data == "binary_compressed" ) {

			console.error( 'THREE.PCDLoader: binary_compressed files are not supported' );
			return;

		}

		if ( PCDheader.data == "binary" ) {

			var row = 0;
			var dataview = new DataView( data, PCDheader.headerLen );
			var i = 0;
			var offset = PCDheader.offset;
			for ( var i3 = 0; i < PCDheader.points; i3 += 3, row += PCDheader.rowSize, i ++ ) {

				if ( offset.x != undefined ) {

					position[ i3 + 0 ] = dataview.getFloat32( row + offset.x, this.littleEndian );
					position[ i3 + 1 ] = dataview.getFloat32( row + offset.y, this.littleEndian );
					position[ i3 + 2 ] = dataview.getFloat32( row + offset.z, this.littleEndian );

				}
				if ( offset.rgb != undefined ) {

					color[ i3 + 0 ] = dataview.getUint8( row + offset.rgb + 0 ) / 255.0;
					color[ i3 + 1 ] = dataview.getUint8( row + offset.rgb + 1 ) / 255.0;
					color[ i3 + 2 ] = dataview.getUint8( row + offset.rgb + 2 ) / 255.0;

				}
				if ( offset.normal_x != undefined ) {

					normal[ i3 + 0 ] = dataview.getFloat32( row + offset.normal_x, this.littleEndian );
					normal[ i3 + 1 ] = dataview.getFloat32( row + offset.normal_y, this.littleEndian );
					normal[ i3 + 2 ] = dataview.getFloat32( row + offset.normal_z, this.littleEndian );

				}

			}

		}

		var geometry = new THREE.BufferGeometry();
		if ( position != false )
			geometry.addAttribute( 'position', new THREE.BufferAttribute( position, 3 ) );
		if ( color != false )
			geometry.addAttribute( 'color', new THREE.BufferAttribute( color, 3 ) );
		if ( normal != false )
			geometry.addAttribute( 'normal', new THREE.BufferAttribute( normal, 3 ) );

		geometry.computeBoundingSphere();

		var material = new THREE.PointsMaterial( { size: 0.005, vertexColors: ! ( color == false ) } );
		if ( color == false )
			material.color.setHex( Math.random() * 0xffffff );

		var mesh = new THREE.Points( geometry, material );
		var name = url.split( '' ).reverse().join( '' );
		name = /([^\/]*)/.exec( name );
		name = name[ 1 ].split( '' ).reverse().join( '' );
		mesh.name = name;
		mesh.PCDheader = PCDheader;

		return mesh;

	}

};
<commit_msg>PCDLoader: Clean up<commit_after>/**
 * @author Filipe Caixeta / http://filipecaixeta.com.br
 *
 * Description: A THREE loader for PCD ascii and binary files.
 *
 * Limitations: Compressed binary files are not supported.
 *
 */

THREE.PCDLoader = function ( manager ) {

	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
	this.littleEndian = true;

};

THREE.PCDLoader.prototype = {

	constructor: THREE.PCDLoader,

	load: function ( url, onLoad, onProgress, onError ) {

		var scope = this;

		var loader = new THREE.FileLoader( scope.manager );
		loader.setResponseType( 'arraybuffer' );
		loader.load( url, function ( data ) {

			onLoad( scope.parse( data, url ) );

		}, onProgress, onError );

	},

	binarryToStr: function ( data ) {

		var charArray = new Uint8Array( data );

		if ( window.TextDecoder !== undefined ) {

			return new TextDecoder().decode( charArray );

		}

		var text = '';
		for ( var i = 0, il = data.byteLength; i < il; i ++ ) {

			text += String.fromCharCode( charArray[ i ] );

		}
		return text;

	},

	parseHeader: function ( data ) {

		var PCDheader = {};
		var result1 = data.search( /[\r\n]DATA\s(\S*)\s/i );
		var result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.substr( result1 - 1 ) );

		var i, l;

		PCDheader.data = result2[ 1 ];
		PCDheader.headerLen = result2[ 0 ].length + result1;
		PCDheader.str = data.substr( 0, PCDheader.headerLen );

		// remove comments

		PCDheader.str = PCDheader.str.replace( /\#.*/gi, '' );

		// parse

		PCDheader.version = /VERSION (.*)/i.exec( PCDheader.str );
		PCDheader.fields = /FIELDS (.*)/i.exec( PCDheader.str );
		PCDheader.size = /SIZE (.*)/i.exec( PCDheader.str );
		PCDheader.type = /TYPE (.*)/i.exec( PCDheader.str );
		PCDheader.count = /COUNT (.*)/i.exec( PCDheader.str );
		PCDheader.width = /WIDTH (.*)/i.exec( PCDheader.str );
		PCDheader.height = /HEIGHT (.*)/i.exec( PCDheader.str );
		PCDheader.viewpoint = /VIEWPOINT (.*)/i.exec( PCDheader.str );
		PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str );

		// evaluate

		if ( PCDheader.version !== null )
			PCDheader.version = parseFloat( PCDheader.version[ 1 ] );

		if ( PCDheader.fields !== null )
			PCDheader.fields = PCDheader.fields[ 1 ].split( ' ' );

		if ( PCDheader.type !== null )
			PCDheader.type = PCDheader.type[ 1 ].split( ' ' );

		if ( PCDheader.width !== null )
			PCDheader.width = parseInt( PCDheader.width[ 1 ] );

		if ( PCDheader.height !== null )
			PCDheader.height = parseInt( PCDheader.height[ 1 ] );

		if ( PCDheader.viewpoint !== null )
			PCDheader.viewpoint = PCDheader.viewpoint[ 1 ];

		if ( PCDheader.points !== null )
			PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 );

		if ( PCDheader.points === null )
			PCDheader.points = PCDheader.width * PCDheader.height;

		if ( PCDheader.size !== null ) {

			PCDheader.size = PCDheader.size[ 1 ].split( ' ' ).map( function ( x ) {

				return parseInt( x, 10 );

			} );

		}

		if ( PCDheader.count !== null ) {

			PCDheader.count = PCDheader.count[ 1 ].split( ' ' ).map( function ( x ) {

				return parseInt( x, 10 );

			} );

		} else {

			PCDheader.count = [];

			for ( i = 0, l = PCDheader.fields.length; i < l; i ++ ) {

				PCDheader.count.push( 1 );

			}

		}

		PCDheader.offset = {};

		var sizeSum = 0;

		for ( i = 0, l = PCDheader.fields.length; i < l; i ++ ) {

			if ( PCDheader.data === 'ascii' ) {

				PCDheader.offset[ PCDheader.fields[ i ] ] = i;

			} else {

				PCDheader.offset[ PCDheader.fields[ i ] ] = sizeSum;
				sizeSum += PCDheader.size[ i ];

			}

		}

		// for binary only

		PCDheader.rowSize = sizeSum;

		return PCDheader;

	},

	parse: function ( data, url ) {

		var dataView, offset;
		var i, l;

		var textData = this.binarryToStr( data );

		// parse header (always ascii format)

		var PCDheader = this.parseHeader( textData );

		// parse data

		var position = [];
		var normal = [];
		var color = [];

		// ascii

		if ( PCDheader.data === 'ascii' ) {

			offset = PCDheader.offset;
			var pcdData = textData.substr( PCDheader.headerLen );
			var lines = pcdData.split( '\n' );

			for ( i = 0, l = lines.length; i < l; i ++ ) {

				var line = lines[ i ].split( ' ' );

				if ( offset.x !== undefined ) {

					position.push( parseFloat( line[ offset.x ] ) );
					position.push( parseFloat( line[ offset.y ] ) );
					position.push( parseFloat( line[ offset.z ] ) );

				}

				if ( offset.rgb !== undefined ) {

					var c = new Float32Array( [ parseFloat( line[ offset.rgb ] ) ] );
					dataview = new DataView( c.buffer, 0 );
					color.push( dataview.getUint8( 0 ) / 255.0 );
					color.push( dataview.getUint8( 1 ) / 255.0 );
					color.push( dataview.getUint8( 2 ) / 255.0 );

				}

				if ( offset.normal_x !== undefined ) {

					normal.push( parseFloat( line[ offset.normal_x ] ) );
					normal.push( parseFloat( line[ offset.normal_y ] ) );
					normal.push( parseFloat( line[ offset.normal_z ] ) );

				}

			}

		}

		// binary

		if ( PCDheader.data === 'binary_compressed' ) {

			console.error( 'THREE.PCDLoader: binary_compressed files are not supported' );
			return;

		}

		if ( PCDheader.data === 'binary' ) {

			dataview = new DataView( data, PCDheader.headerLen );
			offset = PCDheader.offset;

			for ( i = 0, row = 0; i < PCDheader.points; i ++, row += PCDheader.rowSize ) {

				if ( offset.x !== undefined ) {

					position.push( dataview.getFloat32( row + offset.x, this.littleEndian ) );
					position.push( dataview.getFloat32( row + offset.y, this.littleEndian ) );
					position.push( dataview.getFloat32( row + offset.z, this.littleEndian ) );

				}

				if ( offset.rgb !== undefined ) {

					color.push( dataview.getUint8( row + offset.rgb + 0 ) / 255.0 );
					color.push( dataview.getUint8( row + offset.rgb + 1 ) / 255.0 );
					color.push( dataview.getUint8( row + offset.rgb + 2 ) / 255.0 );

				}

				if ( offset.normal_x !== undefined ) {

					normal.push( dataview.getFloat32( row + offset.normal_x, this.littleEndian ) );
					normal.push( dataview.getFloat32( row + offset.normal_y, this.littleEndian ) );
					normal.push( dataview.getFloat32( row + offset.normal_z, this.littleEndian ) );

				}

			}

		}

		// build geometry

		var geometry = new THREE.BufferGeometry();

		if ( position.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );
		if ( normal.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) );
		if ( color.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) );

		geometry.computeBoundingSphere();

		// build material

		var material = new THREE.PointsMaterial( { size: 0.005 } );

		if ( color.length > 0 ) {

			material.vertexColors = true;

		} else {

			material.color.setHex( Math.random() * 0xffffff );

		}

		// build mesh

		var mesh = new THREE.Points( geometry, material );
		var name = url.split( '' ).reverse().join( '' );
		name = /([^\/]*)/.exec( name );
		name = name[ 1 ].split( '' ).reverse().join( '' );
		mesh.name = name;

		return mesh;

	}

};
<|endoftext|>


<commit_before>var Rx = require('rx');
global.Rx = Rx;

var falcor = require('./../../index');
var legacyFalcor = require('./legacy');

var Cache = require('./../../test/data/Cache');
var LocalDataStore = require('./../../test/data/LocalDataSource');
var head = require('./../../lib/internal/head');
var tail = require('./../../lib/internal/tail');
var next = require('./../../lib/internal/next');
var prev = require('./../../lib/internal/prev');

module.exports = function() {

    var mdpModel = legacyFalcor.getMdpModel();
    var emptyModel = new falcor.Model();

    var model = new falcor.Model({cache: Cache()});
    model._root.unsafeMode = true;

    var modelWithSource = new falcor.Model({source: new LocalDataStore(Cache())});
    modelWithSource._root.unsafeMode = true;
    var modelGet = modelWithSource.get.bind(modelWithSource);
    modelWithSource.get = function() {
        modelWithSource._cache = {};
        modelWithSource._root[head] = null;
        modelWithSource._root[tail] = null;
        modelWithSource._root[prev] = null;
        modelWithSource._root[next] = null;
        modelWithSource._root.expired = [];
        return modelGet.apply(modelWithSource, arguments);
    };

    var macroModel = legacyFalcor.getMacroModel();
    macroModel._root.unsafeMode = true;

    return {
        model: model,
        empty: emptyModel,
        macro: macroModel,
        mdp: mdpModel,
        modelWithSource: modelWithSource
    };
};
<commit_msg>found a small issue.<commit_after>var falcor = require('./../../index');
var legacyFalcor = require('./legacy');

var Cache = require('./../../test/data/Cache');
var LocalDataStore = require('./../../test/data/LocalDataSource');
var head = require('./../../lib/internal/head');
var tail = require('./../../lib/internal/tail');
var next = require('./../../lib/internal/next');
var prev = require('./../../lib/internal/prev');

module.exports = function() {

    var emptyModel = new falcor.Model();

    var model = new falcor.Model({cache: Cache()});
    model._root.unsafeMode = true;

    var modelWithSource = new falcor.Model({source: new LocalDataStore(Cache())});
    modelWithSource._root.unsafeMode = true;
    var modelGet = modelWithSource.get.bind(modelWithSource);
    modelWithSource.get = function() {
        modelWithSource._cache = {};
        modelWithSource._root[head] = null;
        modelWithSource._root[tail] = null;
        modelWithSource._root[prev] = null;
        modelWithSource._root[next] = null;
        modelWithSource._root.expired = [];
        return modelGet.apply(modelWithSource, arguments);
    };

    return {
        model: model,
        empty: emptyModel,
        modelWithSource: modelWithSource
    };
};
<|endoftext|>


<commit_before>/**
 * Created by Awesome on 2/21/2016.
 */

// use strict
'use strict';

// require dependencies
var acl        = require ('acl');
var url        = require ('url');
var user       = require ('user');
var local      = require ('passport-local').Strategy;
var crypto     = require ('crypto');
var passport   = require ('passport');
var controller = require ('controller');

// require local dependencies
var config    = require ('app/config');
var aclConfig = require ('app/cache/config.json').acl;

/**
 * create user controller
 */
class main extends controller {
    /**
     * constructor for main controller
     *
     * @param {eden} eden
     */
    constructor (eden) {
        // run super
        super (eden);

        // bind methods
        this.build              = this.build.bind (this);
        this.loginAction        = this.loginAction.bind (this);
        this.logoutAction       = this.logoutAction.bind (this);
        this.registerAction     = this.registerAction.bind (this);
        this.loginFormAction    = this.loginFormAction.bind (this);
        this.registerFormAction = this.registerFormAction.bind (this);

        // bind private methods
        this._acl          = this._acl.bind (this);
        this._user         = this._user.bind (this);
        this._deserialise  = this._deserialise.bind (this);
        this._authenticate = this._authenticate.bind (this);

        // run
        this.build (eden.app);
    }

    /**
     * builds user controller
     */
    build (app) {
        // initialize passport
        app.use (passport.initialize ());
        app.use (passport.session ());

        // create local strategy
        passport.use (new local (this._authenticate));

        // serializes user
        passport.serializeUser ((User, done) => {
            // emit done
            done (null, User.get ('_id').toString ());
        });

        // deserialize user
        passport.deserializeUser (this._deserialise);

        // add user to locals
        app.use (this._user);

        // check acl on run
        app.use (this._acl);
    }

    /**
     * login action
     *
     * @param req
     * @param res
     *
     * @name     LOGIN
     * @route    {get} /login
     * @menu     {MAIN} Login
     * @acl      {test:false,fail:{redirect:"/"}}
     * @priority 2
     */
    loginAction (req, res) {
        // render login page
        res.render ('login', {});
    }

    /**
     * login form action
     *
     * @param req
     * @param res
     *
     * @route {post} /login
     * @acl   {test:false,fail:{redirect:"/"}}
     */
    loginFormAction (req, res, next) {
        // authenticate with passport
        passport.authenticate ('local', (err, User, info) => {
            // check user exists
            if (!User) {
                // render login page
                return res.render ('login', {
                    'error' : info.message,
                    'old'   : req.body
                });
            }

            // do passport login
            req.login (User, {}, (err) => {
                // redirect to home
                res.redirect ('/');
            });
        }) (req, res, next);
    }

    /**
     * logout action
     *
     * @param req
     * @param res
     *
     * @name     LOGOUT
     * @route    {get} /logout
     * @menu     {MAIN} Logout
     * @acl      {test:true,fail:{redirect:"/"}}
     * @priority 2
     */
    logoutAction (req, res) {
        // logout
        req.logout ();
        // redirect to home
        res.redirect ('/');
    }

    /**
     * Register action
     *
     * @param req
     * @param res
     *
     * @route {get} /register
     * @acl   {test:false,fail:{redirect:"/"}}
     */
    registerAction (req, res) {
        // render registration page
        res.render ('register', {});
    }

    /**
     * Register form action
     *
     * @param req
     * @param res
     *
     * @route {post} /register
     * @acl   {test:false,fail:{redirect:"/"}}
     */
    async registerFormAction (req, res) {
        // check username
        if (req.body.username.trim ().length < 5) {
            // render registration page
            return res.render ('register', {
                'error' : 'your username must be at least 5 characters long',
                'old'   : req.body
            });
        }

        // check for user
        var User = await user.where ({
            'username' : req.body.username.toLowerCase ()
        }).findOne ();

        // check if user exists
        if (User) {
            // render registration page
            return res.render ('register', {
                'error' : 'the username "' + req.body.username + '" is already taken',
                'old'   : req.body
            });
        }

        // check password length
        if (req.body.password.trim ().length < 5) {
            // render registration page
            return res.render ('register', {
                'error' : 'your password must be at least 5 characters long',
                'old'   : req.body
            });
        }

        // check passwords match
        if (req.body.password != req.body.passwordb) {
            // render registration page
            return res.render ('register', {
                'error' : 'your passwords do not match',
                'old'   : req.body
            });
        }

        // everything checks out
        var hash = crypto.createHmac ('sha256', config.secret)
            .update (req.body.password)
            .digest ('hex');

        // create user
        User = new user ({
            'username' : req.body.username.toLowerCase (),
            'hash'     : hash
        });

        // save user
        await User.save ();

        // log user in
        req.login (User, (err) => {
            // redirect to home
            res.redirect ('/');
        });
    }

    /**
     * checks route acl
     *
     * @param {Request} req
     * @param {Response} res
     * @param {Function} next
     */
    async _acl (req, res, next) {
        // do route regex
        var rt = '/' + res.locals.route.replace (/^\/|\/$/g, '');

        // check route has acl
        if (!aclConfig[rt] || !aclConfig[rt].length) {
            // return next
            return next ();
        }

        // loop acl for tests
        for (var i = 0; i < aclConfig[rt].length; i ++) {
            // check acl
            var check = acl.acl (res.locals.acl, aclConfig[rt][i], res.locals.user);

            // check if true
            if (check !== true) {
                // check if redirect
                if (check.redirect) {
                    // redirect to fail auth redirect
                    return res.redirect (check.redirect);
                }

                // redirect home
                return res.redirect ('/');
            }
        }

        // do next
        next ();
    }

    /**
     * adds user to locals
     *
     * @param {Request} req
     * @param {Response} res
     * @param {Function} next
     */
    async _user (req, res, next) {
        // get acls
        var aclArr = [];
        var acls   = [];

        // check for req user
        if (req.user) {
            acls = await req.user.model ('acl');
        }

        // loop acls for acl array
        for (var i = 0; i < acls.length; i++) {
            aclArr.push (acls[i].sanitise ());
        }

        // set user locally
        res.locals.acl  = aclArr;
        res.locals.user = req.user ? req.user.sanitise () : false;

        // run next
        next ();
    }

    /**
     * authenticate user function
     *
     * @param {String} username
     * @param {String} password
     * @param {Function} done
     */
    async _authenticate (username, password, done) {
        // find user
        var User = await user.where ({
            'username' : username.toLowerCase ()
        }).limit (1).find ();

        // check user exists
        if (!User || !User.length) {
            return done (null, false, 'User not found');
        }

        // set user
        User = User[0];

        // authenticate
        var result = await User.authenticate (password);

        // check error
        if (result !== true) {
            return done (null, false, result.info);
        }

        // send done
        done (null, User);
    }

    /**
     * deserialize user
     *
     * @param {String} id
     * @param {Function} done
     */
    async _deserialise (id, done) {
        // find user by id
        var User = await user.findById (id);

        // callback done with user
        done (null, User);
    }
}

/**
 * eport user controller
 *
 * @type {main}
 */
module.exports = main;
<commit_msg>amend issues loading user entity in user bundle<commit_after>/**
 * Created by Awesome on 2/21/2016.
 */

// use strict
'use strict';

// require dependencies
var acl        = require ('acl');
var url        = require ('url');
var local      = require ('passport-local').Strategy;
var crypto     = require ('crypto');
var passport   = require ('passport');
var controller = require ('controller');

// require local dependencies
var user      = require ('user/models/user');
var config    = require ('app/config');
var aclConfig = require ('app/cache/config.json').acl;

/**
 * create user controller
 */
class main extends controller {
    /**
     * constructor for main controller
     *
     * @param {eden} eden
     */
    constructor (eden) {
        // run super
        super (eden);

        // bind methods
        this.build              = this.build.bind (this);
        this.loginAction        = this.loginAction.bind (this);
        this.logoutAction       = this.logoutAction.bind (this);
        this.registerAction     = this.registerAction.bind (this);
        this.loginFormAction    = this.loginFormAction.bind (this);
        this.registerFormAction = this.registerFormAction.bind (this);

        // bind private methods
        this._acl          = this._acl.bind (this);
        this._user         = this._user.bind (this);
        this._deserialise  = this._deserialise.bind (this);
        this._authenticate = this._authenticate.bind (this);

        // run
        this.build (eden.app);
    }

    /**
     * builds user controller
     */
    build (app) {
        // initialize passport
        app.use (passport.initialize ());
        app.use (passport.session ());

        // create local strategy
        passport.use (new local (this._authenticate));

        // serializes user
        passport.serializeUser ((User, done) => {
            // emit done
            done (null, User.get ('_id').toString ());
        });

        // deserialize user
        passport.deserializeUser (this._deserialise);

        // add user to locals
        app.use (this._user);

        // check acl on run
        app.use (this._acl);
    }

    /**
     * login action
     *
     * @param req
     * @param res
     *
     * @name     LOGIN
     * @route    {get} /login
     * @menu     {MAIN} Login
     * @acl      {test:false,fail:{redirect:"/"}}
     * @priority 2
     */
    loginAction (req, res) {
        // render login page
        res.render ('login', {});
    }

    /**
     * login form action
     *
     * @param req
     * @param res
     *
     * @route {post} /login
     * @acl   {test:false,fail:{redirect:"/"}}
     */
    loginFormAction (req, res, next) {
        // authenticate with passport
        passport.authenticate ('local', (err, User, info) => {
            // check user exists
            if (!User) {
                // render login page
                return res.render ('login', {
                    'error' : info.message,
                    'old'   : req.body
                });
            }

            // do passport login
            req.login (User, {}, (err) => {
                // redirect to home
                res.redirect ('/');
            });
        }) (req, res, next);
    }

    /**
     * logout action
     *
     * @param req
     * @param res
     *
     * @name     LOGOUT
     * @route    {get} /logout
     * @menu     {MAIN} Logout
     * @acl      {test:true,fail:{redirect:"/"}}
     * @priority 2
     */
    logoutAction (req, res) {
        // logout
        req.logout ();
        // redirect to home
        res.redirect ('/');
    }

    /**
     * Register action
     *
     * @param req
     * @param res
     *
     * @route {get} /register
     * @acl   {test:false,fail:{redirect:"/"}}
     */
    registerAction (req, res) {
        // render registration page
        res.render ('register', {});
    }

    /**
     * Register form action
     *
     * @param req
     * @param res
     *
     * @route {post} /register
     * @acl   {test:false,fail:{redirect:"/"}}
     */
    async registerFormAction (req, res) {
        // check username
        if (req.body.username.trim ().length < 5) {
            // render registration page
            return res.render ('register', {
                'error' : 'your username must be at least 5 characters long',
                'old'   : req.body
            });
        }

        // check for user
        var User = await user.where ({
            'username' : req.body.username.toLowerCase ()
        }).findOne ();

        // check if user exists
        if (User) {
            // render registration page
            return res.render ('register', {
                'error' : 'the username "' + req.body.username + '" is already taken',
                'old'   : req.body
            });
        }

        // check password length
        if (req.body.password.trim ().length < 5) {
            // render registration page
            return res.render ('register', {
                'error' : 'your password must be at least 5 characters long',
                'old'   : req.body
            });
        }

        // check passwords match
        if (req.body.password != req.body.passwordb) {
            // render registration page
            return res.render ('register', {
                'error' : 'your passwords do not match',
                'old'   : req.body
            });
        }

        // everything checks out
        var hash = crypto.createHmac ('sha256', config.secret)
            .update (req.body.password)
            .digest ('hex');

        // create user
        User = new user ({
            'username' : req.body.username.toLowerCase (),
            'hash'     : hash
        });

        // save user
        await User.save ();

        // log user in
        req.login (User, (err) => {
            // redirect to home
            res.redirect ('/');
        });
    }

    /**
     * checks route acl
     *
     * @param {Request} req
     * @param {Response} res
     * @param {Function} next
     */
    async _acl (req, res, next) {
        // do route regex
        var rt = '/' + res.locals.route.replace (/^\/|\/$/g, '');

        // check route has acl
        if (!aclConfig[rt] || !aclConfig[rt].length) {
            // return next
            return next ();
        }

        // loop acl for tests
        for (var i = 0; i < aclConfig[rt].length; i ++) {
            // check acl
            var check = acl.acl (res.locals.acl, aclConfig[rt][i], res.locals.user);

            // check if true
            if (check !== true) {
                // check if redirect
                if (check.redirect) {
                    // redirect to fail auth redirect
                    return res.redirect (check.redirect);
                }

                // redirect home
                return res.redirect ('/');
            }
        }

        // do next
        next ();
    }

    /**
     * adds user to locals
     *
     * @param {Request} req
     * @param {Response} res
     * @param {Function} next
     */
    async _user (req, res, next) {
        // get acls
        var aclArr = [];
        var acls   = [];

        // check for req user
        if (req.user) {
            acls = await req.user.model ('acl');
        }

        // loop acls for acl array
        for (var i = 0; i < acls.length; i++) {
            aclArr.push (acls[i].sanitise ());
        }

        // set user locally
        res.locals.acl  = aclArr;
        res.locals.user = req.user ? req.user.sanitise () : false;

        // run next
        next ();
    }

    /**
     * authenticate user function
     *
     * @param {String} username
     * @param {String} password
     * @param {Function} done
     */
    async _authenticate (username, password, done) {
        // find user
        var User = await user.where ({
            'username' : username.toLowerCase ()
        }).limit (1).find ();

        // check user exists
        if (!User || !User.length) {
            return done (null, false, 'User not found');
        }

        // set user
        User = User[0];

        // authenticate
        var result = await User.authenticate (password);

        // check error
        if (result !== true) {
            return done (null, false, result.info);
        }

        // send done
        done (null, User);
    }

    /**
     * deserialize user
     *
     * @param {String} id
     * @param {Function} done
     */
    async _deserialise (id, done) {
        // find user by id
        var User = await user.findById (id);

        // callback done with user
        done (null, User);
    }
}

/**
 * eport user controller
 *
 * @type {main}
 */
module.exports = main;
<|endoftext|>


<commit_before>
/*-------------------------------------------------------------------------------------*/
$(document).on('page:change', function () {

  // Prepare Queue
  window.ajax_queue = [];
  var interval = 1;
  setInterval(process_ajax_queue, interval);

  // When the user logs in, the window.title becomes number of connections,
  // but when the user logs out, let's set the window.title back to what it was originally
  window.original_title = document.title;

  // Ok sync requests are bad, but just this one time
  window.login_info = get_json('/welcome/check_login');

  display_login_info();

  var e = document.getElementsByClassName('page_change');
  for (var i=0 ; i < e.length; i++)
  switch(e[i].getAttribute('data-run')){

    case 'index':
      page_change_index();
      break;
    case 'competition':
      page_change_competition();
      break;
    case 'poet_lookup':
      page_change_poet_lookup();
      break;
    case 'view_lookup':
      page_change_view_lookup();
      break;
  }
});

/*-------------------------------------------------------------------------------------*/
function page_change_index() {

  var canvas = document.getElementById("dotmatrix_canvas");
  var margin = 0;

  var width = parseInt(window.innerWidth) - margin;
  canvas.style.width = "" + width + "px";

  Strugnell.singleTwitterMatrix();

}
/*-------------------------------------------------------------------------------------*/
function prepare_round(index) {

  var i = index;
  var round_number = i + 1;

  rounds[i].round_js = round_new(rounds[i].num_places, round_number);
  rounds[i].round_js.debug_str = "round " + i;
  rounds[i].names_already_performing = [];

  var prev_round = rounds[i].are_poets_from_previous ? rounds[i-1].round_js : window.invisible_round;
  rounds[i].contenders = contenders_new(rounds[i].round_number, prev_round);

}
/*-------------------------------------------------------------------------------------*/

// Extract the extra round (if there is one, it will be at the end)
// Only call this once!
function extract_extra_round() {

  var div = document.getElementById('extra_round_div');
  //div.className = "visible_when_logged_in";

  var last_round = rounds[rounds.length - 1];

  window.is_there_an_extra_round = false;

  if (last_round.is_extra) {

    $(div).show(); //Not tested -- but this whole thing extra round thing will probably be rewritten/redesigned

    if (!login_info.is_logged_in)
      div.setAttribute('hidden', null);

    window.is_there_an_extra_round = true;
    window.extra_round = last_round;

    rounds.pop();

  }
  else {

    // Hide Extra Round button
    div.setAttribute('hidden', null);
  }
}

/*-------------------------------------------------------------------------------------*/
function prepare_rounds() {

  extract_extra_round();

  window.invisible_round = round_new(0); // we'll keep num_places growing for the invisible round
  window.invisible_round.debug_str = "invisible round"; //debugging

  for (var i=0; i<rounds.length; i++) {
    prepare_round(i);
  }

}
/*-------------------------------------------------------------------------------------*/

function manage_class_visible_when_logged_in() {

  var done_func = function(login) {

    var elements = document.getElementsByClassName('visible_when_logged_in');
    for (var i=0; i < elements.length; i++)
      if (login.is_logged_in)
	elements[i].removeAttribute('hidden')
      else
	elements[i].setAttribute('hidden', null);
  }

  check_login_request(done_func);
}

function page_change_competition() {

  manage_class_visible_when_logged_in();
  prepare_rounds();

  var done_func = function(login) {

    if (login.is_logged_in) {

      var poets_competing = document.getElementById("poets_competing");
      poets_competing.removeAttribute('hidden');
      poets_competing.poet_names = [];

      var temp = do_log_out;
      do_log_out = function () {
	temp();

	document.title = window.original_title;

	document.getElementById("poets_competing").setAttribute("hidden", null);
	document.getElementById("poet_lookup").setAttribute("hidden", null);

	var div = document.getElementById('extra_round_div');
	div.setAttribute('hidden', null);

	// Hide elements that should only be visible when logged in.
	var elements = document.getElementsByClassName('visible_when_logged_in'); // TODO Perhaps this should be default behavior for logging out?
	for (var i=0; i<elements.length; i++)
	  elements[i].setAttribute('hidden', null);

	// Make inputs readonly
	var inputs = document.getElementsByClassName('scorekeeper_input');
	for (var i=0; i<inputs.length; i++)
	  inputs[i].setAttribute('readonly', null);

      };

    }
    else {
      // User is not logged in.
    }
  }

  check_login_request(done_func);

  window.web_sock_id = makeid(20);

  var interval = 1;
  //setInterval(process_ajax_queue, interval);
  slam.local_event_number = 0;
  window.init_web_sock();
  setInterval(handle_unprocessed_events, interval);

  for (var i = 0; i < events.length; i++)
    do_event(events[i]);

  what_did_i_miss_request();
}

/*------------------------------------------------------------------------------------*/
function page_change_poet_lookup() {

  var input = document.getElementById('suggestions_input');
  input.addEventListener('keydown', function(e) {
    if (e.keyCode === 38 || e.keyCode === 40) e.preventDefault();
  }, false);

}
/*-------------------------------------------------------------------------------------*/
function page_change_view_lookup() {

  document.getElementById('poet_lookup').removeAttribute('hidden');
  document.getElementById('poet_lookup_cancel').setAttribute('hidden', null);
  document.getElementById('suggestions_create').setAttribute('hidden', null);
  document.getElementById('suggestions_select').setAttribute('hidden', null);
  document.getElementById('suggestions_message').setAttribute('hidden', null);

}
/*-------------------------------------------------------------------------------------*/

<commit_msg>Fixed bug where dot matrix is running more than once<commit_after>
/*-------------------------------------------------------------------------------------*/
$(document).on('page:change', function () {

  // Prepare Queue
  window.ajax_queue = [];
  var interval = 1;
  setInterval(process_ajax_queue, interval);

  // When the user logs in, the window.title becomes number of connections,
  // but when the user logs out, let's set the window.title back to what it was originally
  window.original_title = document.title;

  // Ok sync requests are bad, but just this one time
  window.login_info = get_json('/welcome/check_login');

  display_login_info();

  var e = document.getElementsByClassName('page_change');
  for (var i=0 ; i < e.length; i++)
  switch(e[i].getAttribute('data-run')){

    case 'index':
      page_change_index();
      break;
    case 'competition':
      page_change_competition();
      break;
    case 'poet_lookup':
      page_change_poet_lookup();
      break;
    case 'view_lookup':
      page_change_view_lookup();
      break;
  }
});

/*-------------------------------------------------------------------------------------*/

var dot_matrix_running = false;
function page_change_index() {

  var canvas = document.getElementById("dotmatrix_canvas");
  var margin = 0;

  var width = parseInt(window.innerWidth) - margin;
  canvas.style.width = "" + width + "px";

  if (!dot_matrix_running) {
    Strugnell.singleTwitterMatrix();
    dot_matrix_running = true;
  }

}
/*-------------------------------------------------------------------------------------*/
function prepare_round(index) {

  var i = index;
  var round_number = i + 1;

  rounds[i].round_js = round_new(rounds[i].num_places, round_number);
  rounds[i].round_js.debug_str = "round " + i;
  rounds[i].names_already_performing = [];

  var prev_round = rounds[i].are_poets_from_previous ? rounds[i-1].round_js : window.invisible_round;
  rounds[i].contenders = contenders_new(rounds[i].round_number, prev_round);

}
/*-------------------------------------------------------------------------------------*/

// Extract the extra round (if there is one, it will be at the end)
// Only call this once!
function extract_extra_round() {

  var div = document.getElementById('extra_round_div');
  //div.className = "visible_when_logged_in";

  var last_round = rounds[rounds.length - 1];

  window.is_there_an_extra_round = false;

  if (last_round.is_extra) {

    $(div).show(); //Not tested -- but this whole thing extra round thing will probably be rewritten/redesigned

    if (!login_info.is_logged_in)
      div.setAttribute('hidden', null);

    window.is_there_an_extra_round = true;
    window.extra_round = last_round;

    rounds.pop();

  }
  else {

    // Hide Extra Round button
    div.setAttribute('hidden', null);
  }
}

/*-------------------------------------------------------------------------------------*/
function prepare_rounds() {

  extract_extra_round();

  window.invisible_round = round_new(0); // we'll keep num_places growing for the invisible round
  window.invisible_round.debug_str = "invisible round"; //debugging

  for (var i=0; i<rounds.length; i++) {
    prepare_round(i);
  }

}
/*-------------------------------------------------------------------------------------*/

function manage_class_visible_when_logged_in() {

  var done_func = function(login) {

    var elements = document.getElementsByClassName('visible_when_logged_in');
    for (var i=0; i < elements.length; i++)
      if (login.is_logged_in)
	elements[i].removeAttribute('hidden')
      else
	elements[i].setAttribute('hidden', null);
  }

  check_login_request(done_func);
}

function page_change_competition() {

  manage_class_visible_when_logged_in();
  prepare_rounds();

  var done_func = function(login) {

    if (login.is_logged_in) {

      var poets_competing = document.getElementById("poets_competing");
      poets_competing.removeAttribute('hidden');
      poets_competing.poet_names = [];

      var temp = do_log_out;
      do_log_out = function () {
	temp();

	document.title = window.original_title;

	document.getElementById("poets_competing").setAttribute("hidden", null);
	document.getElementById("poet_lookup").setAttribute("hidden", null);

	var div = document.getElementById('extra_round_div');
	div.setAttribute('hidden', null);

	// Hide elements that should only be visible when logged in.
	var elements = document.getElementsByClassName('visible_when_logged_in'); // TODO Perhaps this should be default behavior for logging out?
	for (var i=0; i<elements.length; i++)
	  elements[i].setAttribute('hidden', null);

	// Make inputs readonly
	var inputs = document.getElementsByClassName('scorekeeper_input');
	for (var i=0; i<inputs.length; i++)
	  inputs[i].setAttribute('readonly', null);

      };

    }
    else {
      // User is not logged in.
    }
  }

  check_login_request(done_func);

  window.web_sock_id = makeid(20);

  var interval = 1;
  //setInterval(process_ajax_queue, interval);
  slam.local_event_number = 0;
  window.init_web_sock();
  setInterval(handle_unprocessed_events, interval);

  for (var i = 0; i < events.length; i++)
    do_event(events[i]);

  what_did_i_miss_request();
}

/*------------------------------------------------------------------------------------*/
function page_change_poet_lookup() {

  var input = document.getElementById('suggestions_input');
  input.addEventListener('keydown', function(e) {
    if (e.keyCode === 38 || e.keyCode === 40) e.preventDefault();
  }, false);

}
/*-------------------------------------------------------------------------------------*/
function page_change_view_lookup() {

  document.getElementById('poet_lookup').removeAttribute('hidden');
  document.getElementById('poet_lookup_cancel').setAttribute('hidden', null);
  document.getElementById('suggestions_create').setAttribute('hidden', null);
  document.getElementById('suggestions_select').setAttribute('hidden', null);
  document.getElementById('suggestions_message').setAttribute('hidden', null);

}
/*-------------------------------------------------------------------------------------*/

<|endoftext|>


<commit_before>import {error, stringValue} from 'vega-util';

var OUTER = 'outer',
    OUTER_INVALID = ['value', 'update', 'react', 'bind'];

function outerError(prefix, name) {
  error(prefix + ' for "outer" push: ' + stringValue(name));
}

export default function(signal, scope) {
  var name = signal.name;

  if (signal.push === OUTER) {
    // signal must already be defined, raise error if not
    if (!scope.signals[name]) outerError('No prior signal definition', name);
    // signal push must not use properties reserved for standard definition
    OUTER_INVALID.forEach(function(prop) {
      if (signal[prop] !== undefined) outerError('Invalid property ' + stringValue(prop), name);
    });
  } else {
    // define a new signal in the current scope
    var op = scope.addSignal(name, signal.value);
    if (signal.react === false) op.react = false;
    if (signal.bind) scope.addBinding(name, signal.bind);
  }
}
<commit_msg>Adjust outer signal error message.<commit_after>import {error, stringValue} from 'vega-util';

var OUTER = 'outer',
    OUTER_INVALID = ['value', 'update', 'react', 'bind'];

function outerError(prefix, name) {
  error(prefix + ' for "outer" push: ' + stringValue(name));
}

export default function(signal, scope) {
  var name = signal.name;

  if (signal.push === OUTER) {
    // signal must already be defined, raise error if not
    if (!scope.signals[name]) outerError('No prior signal definition', name);
    // signal push must not use properties reserved for standard definition
    OUTER_INVALID.forEach(function(prop) {
      if (signal[prop] !== undefined) outerError('Invalid property ', prop);
    });
  } else {
    // define a new signal in the current scope
    var op = scope.addSignal(name, signal.value);
    if (signal.react === false) op.react = false;
    if (signal.bind) scope.addBinding(name, signal.bind);
  }
}
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 * @author zz85 / http://joshuakoo.com/
 */

THREE.SVGLoader = function ( manager ) {

	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;

};

THREE.SVGLoader.prototype = {

	constructor: THREE.SVGLoader,

	load: function ( url, onLoad, onProgress, onError ) {

		var scope = this;

		var loader = new THREE.FileLoader( scope.manager );
		loader.load( url, function ( text ) {

			onLoad( scope.parse( text ) );

		}, onProgress, onError );

	},

	parse: function ( text ) {

		function parseNode( node, style ) {

			if ( node.nodeType !== 1 ) return;

			switch ( node.nodeName ) {

				case 'svg':
					break;

				case 'g':
					parseStyle( node, style );
					break;

				case 'path':
					parseStyle( node, style );
					paths.push( parsePathNode( node, style ) );
					break;

				case 'rect':
					paths.push( parseRectNode( node, style ) );
					break;

				case 'polygon':
					paths.push( parsePolygonNode( node, style ) );
					break;

				case 'polyline':
					paths.push( parsePolylineNode( node, style ) );
					break;

				case 'circle':
					paths.push( parseCircleNode( node, style ) );
					break;

				case 'ellipse':
					paths.push( parseEllipseNode( node, style ) );
					break;

				case 'line':
					paths.push( parseLineNode( node, style ) );
					break;

				default:
					console.log( node );

			}

			var nodes = node.childNodes;

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

				parseNode( nodes[ i ], style );

			}

		}

		function parsePathNode( node, style ) {

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );

			var point = new THREE.Vector2();
			var control = new THREE.Vector2();

			var d = node.getAttribute( 'd' );

			// console.log( d );

			var commands = d.match( /[a-df-z][^a-df-z]*/ig );

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

				var command = commands[ i ];

				var type = command.charAt( 0 );
				var data = command.substr( 1 ).trim();

				switch ( type ) {

					case 'M':
						var numbers = parseFloats( data );
						point.fromArray( numbers );
						control.x = point.x;
						control.y = point.y;
						path.moveTo( point.x, point.y );
						break;

					case 'H':
						var numbers = parseFloats( data );
						point.x = numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'V':
						var numbers = parseFloats( data );
						point.y = numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'L':
						var numbers = parseFloats( data );
						point.x = numbers[ 0 ];
						point.y = numbers[ 1 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'C':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							numbers[ 0 ],
							numbers[ 1 ],
							numbers[ 2 ],
							numbers[ 3 ],
							numbers[ 4 ],
							numbers[ 5 ]
						);
						control.x = numbers[ 2 ];
						control.y = numbers[ 3 ];
						point.x = numbers[ 4 ];
						point.y = numbers[ 5 ];
						break;

					case 'S':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							getReflection( point.x, control.x ),
							getReflection( point.y, control.y ),
							numbers[ 0 ],
							numbers[ 1 ],
							numbers[ 2 ],
							numbers[ 3 ]
						);
						control.x = numbers[ 0 ];
						control.y = numbers[ 1 ];
						point.x = numbers[ 2 ];
						point.y = numbers[ 3 ];
						break;

					case 'Q':
						var numbers = parseFloats( data );
						path.quadraticCurveTo(
							numbers[ 0 ],
							numbers[ 1 ],
							numbers[ 2 ],
							numbers[ 3 ]
						);
						control.x = numbers[ 0 ];
						control.y = numbers[ 1 ];
						point.x = numbers[ 2 ];
						point.y = numbers[ 3 ];
						break;

					case 'T':
						var numbers = parseFloats( data );
						var rx = getReflection( point.x, control.x );
						var ry = getReflection( point.y, control.y );
						path.quadraticCurveTo(
							rx,
							ry,
							numbers[ 0 ],
							numbers[ 1 ]
						);
						control.x = rx;
						control.y = ry;
						point.x = numbers[ 0 ];
						point.y = numbers[ 1 ];
						break;

					case 'A':
						// TODO:
						break;

					case 'm':
						var numbers = parseFloats( data );
						point.x += numbers[ 0 ];
						point.y += numbers[ 1 ];
						control.x = point.x;
						control.y = point.y;
						path.moveTo( point.x, point.y );
						break;

					case 'h':
						var numbers = parseFloats( data );
						point.x += numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'v':
						var numbers = parseFloats( data );
						point.y += numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'l':
						var numbers = parseFloats( data );
						point.x += numbers[ 0 ];
						point.y += numbers[ 1 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'c':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ],
							point.x + numbers[ 2 ],
							point.y + numbers[ 3 ],
							point.x + numbers[ 4 ],
							point.y + numbers[ 5 ]
						);
						point.x += numbers[ 4 ];
						point.y += numbers[ 5 ];
						break;

					case 's':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							// TODO: Not sure if point needs
							// to be added to reflection...
							getReflection( point.x, control.x ),
							getReflection( point.y, control.y ),
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ],
							point.x + numbers[ 2 ],
							point.y + numbers[ 3 ]
						);
						control.x = point.x + numbers[ 0 ];
						control.y = point.y + numbers[ 1 ];
						point.x += numbers[ 2 ];
						point.y += numbers[ 3 ];
						break;

					case 'q':
						var numbers = parseFloats( data );
						path.quadraticCurveTo(
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ],
							point.x + numbers[ 2 ],
							point.y + numbers[ 3 ]
						);
						control.x = point.x + numbers[ 0 ];
						control.y = point.y + numbers[ 1 ];
						point.x += numbers[ 2 ];
						point.y += numbers[ 3 ];
						break;

					case 't':
						var numbers = parseFloats( data );
						var rx = getReflection( point.x, control.x );
						var ry = getReflection( point.y, control.y );
						path.quadraticCurveTo(
							rx,
							ry,
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ]
						);
						control.x = rx;
						control.y = ry;
						point.x = point.x + numbers[ 0 ];
						point.y = point.y + numbers[ 1 ];
						break;

					case 'a':
						// TODO:
						break;

					case 'Z':
					case 'z':
						path.currentPath.autoClose = true;
						break;

					default:
						console.log( command );

				}

			}

			return path;

		}

		function parseRectNode( node, style ) {

			var x = parseFloat( node.getAttribute( 'x' ) );
			var y = parseFloat( node.getAttribute( 'y' ) );
			var w = parseFloat( node.getAttribute( 'width' ) );
			var h = parseFloat( node.getAttribute( 'height' ) );

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );
			path.moveTo( x, y );
			path.lineTo( x + w, y );
			path.lineTo( x + w, y + h );
			path.lineTo( x, y + h );
			return path;

		}

		function parsePolygonNode( node, style ) {

			function iterator( match, a, b ) {

				var x = parseFloat( a );
				var y = parseFloat( b );

				if ( index === 0 ) {
					path.moveTo( x, y );
				} else {
					path.lineTo( x, y );
				}

				index++;

			}

			var regex = /(-?[\d\.?]+)[,|\s](-?[\d\.?]+)/g;

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );

			var index = 0;

			node.getAttribute( 'points' ).replace(regex, iterator);

			path.currentPath.autoClose = true;

			return path;

		}

		function parsePolylineNode( node, style ) {

			function iterator( match, a, b ) {

				var x = parseFloat( a );
				var y = parseFloat( b );

				if ( index === 0 ) {
					path.moveTo( x, y );
				} else {
					path.lineTo( x, y );
				}

				index++;

			}

			var regex = /(-?[\d\.?]+)[,|\s](-?[\d\.?]+)/g;

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );

			var index = 0;

			node.getAttribute( 'points' ).replace(regex, iterator);

			path.currentPath.autoClose = false;

			return path;

		}

		function parseCircleNode( node, style ) {

			var x = parseFloat( node.getAttribute( 'cx' ) );
			var y = parseFloat( node.getAttribute( 'cy' ) );
			var r = parseFloat( node.getAttribute( 'r' ) );

			var subpath = new THREE.Path();
			subpath.absarc( x, y, r, 0, Math.PI * 2 );

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );
			path.subPaths.push( subpath );

			return path;

		}

		function parseEllipseNode( node, style ) {

			var x = parseFloat( node.getAttribute( 'cx' ) );
			var y = parseFloat( node.getAttribute( 'cy' ) );
			var rx = parseFloat( node.getAttribute( 'rx' ) );
			var ry = parseFloat( node.getAttribute( 'ry' ) );

			var subpath = new THREE.Path();
			subpath.absellipse( x, y, rx, ry, 0, Math.PI * 2 );

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );
			path.subPaths.push( subpath );

			return path;

		}

		function parseLineNode( node, style ) {

			var x1 = parseFloat( node.getAttribute( 'x1' ) );
			var y1 = parseFloat( node.getAttribute( 'y1' ) );
			var x2 = parseFloat( node.getAttribute( 'x2' ) );
			var y2 = parseFloat( node.getAttribute( 'y2' ) );

			var path = new THREE.ShapePath();
			path.moveTo( x1, y1 );
			path.lineTo( x2, y2 );
			path.currentPath.autoClose = false;

			return path;

		}

		//

		function parseStyle( node, style ) {

			if (node.style.fill != '') style.fill = node.style.fill;

		}

		function parseFill( node, style ) {

			if ( node.hasAttribute( 'fill' ) ) {

				return node.getAttribute( 'fill' );

			}

			if ( style.fill !== '' && style.fill !== 'none' ) {

				return style.fill;

			}

			return '#ffffff';

		}

		// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes

		function getReflection( a, b ) {

			return 2 * a - ( b - a );

		}

		function parseFloats( string ) {

			var array = string.split( /[\s,]+|(?=\s?[+\-])/ );

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

				array[ i ] = parseFloat( array[ i ] );

			}

			return array;

		}

		//

		var xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml

		var svg = xml.documentElement;

		var paths = [];

		parseNode( svg, {} );

		return paths;

	}

};
<commit_msg>following PR #13787 syntax modification<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 * @author zz85 / http://joshuakoo.com/
 */

THREE.SVGLoader = function ( manager ) {

	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;

};

THREE.SVGLoader.prototype = {

	constructor: THREE.SVGLoader,

	load: function ( url, onLoad, onProgress, onError ) {

		var scope = this;

		var loader = new THREE.FileLoader( scope.manager );
		loader.load( url, function ( text ) {

			onLoad( scope.parse( text ) );

		}, onProgress, onError );

	},

	parse: function ( text ) {

		function parseNode( node, style ) {

			if ( node.nodeType !== 1 ) return;

			switch ( node.nodeName ) {

				case 'svg':
					break;

				case 'g':
					parseStyle( node, style );
					break;

				case 'path':
					parseStyle( node, style );
					paths.push( parsePathNode( node, style ) );
					break;

				case 'rect':
					paths.push( parseRectNode( node, style ) );
					break;

				case 'polygon':
					paths.push( parsePolygonNode( node, style ) );
					break;

				case 'polyline':
					paths.push( parsePolylineNode( node, style ) );
					break;

				case 'circle':
					paths.push( parseCircleNode( node, style ) );
					break;

				case 'ellipse':
					paths.push( parseEllipseNode( node, style ) );
					break;

				case 'line':
					paths.push( parseLineNode( node, style ) );
					break;

				default:
					console.log( node );

			}

			var nodes = node.childNodes;

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

				parseNode( nodes[ i ], style );

			}

		}

		function parsePathNode( node, style ) {

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );

			var point = new THREE.Vector2();
			var control = new THREE.Vector2();

			var d = node.getAttribute( 'd' );

			// console.log( d );

			var commands = d.match( /[a-df-z][^a-df-z]*/ig );

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

				var command = commands[ i ];

				var type = command.charAt( 0 );
				var data = command.substr( 1 ).trim();

				switch ( type ) {

					case 'M':
						var numbers = parseFloats( data );
						point.fromArray( numbers );
						control.x = point.x;
						control.y = point.y;
						path.moveTo( point.x, point.y );
						break;

					case 'H':
						var numbers = parseFloats( data );
						point.x = numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'V':
						var numbers = parseFloats( data );
						point.y = numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'L':
						var numbers = parseFloats( data );
						point.x = numbers[ 0 ];
						point.y = numbers[ 1 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'C':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							numbers[ 0 ],
							numbers[ 1 ],
							numbers[ 2 ],
							numbers[ 3 ],
							numbers[ 4 ],
							numbers[ 5 ]
						);
						control.x = numbers[ 2 ];
						control.y = numbers[ 3 ];
						point.x = numbers[ 4 ];
						point.y = numbers[ 5 ];
						break;

					case 'S':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							getReflection( point.x, control.x ),
							getReflection( point.y, control.y ),
							numbers[ 0 ],
							numbers[ 1 ],
							numbers[ 2 ],
							numbers[ 3 ]
						);
						control.x = numbers[ 0 ];
						control.y = numbers[ 1 ];
						point.x = numbers[ 2 ];
						point.y = numbers[ 3 ];
						break;

					case 'Q':
						var numbers = parseFloats( data );
						path.quadraticCurveTo(
							numbers[ 0 ],
							numbers[ 1 ],
							numbers[ 2 ],
							numbers[ 3 ]
						);
						control.x = numbers[ 0 ];
						control.y = numbers[ 1 ];
						point.x = numbers[ 2 ];
						point.y = numbers[ 3 ];
						break;

					case 'T':
						var numbers = parseFloats( data );
						var rx = getReflection( point.x, control.x );
						var ry = getReflection( point.y, control.y );
						path.quadraticCurveTo(
							rx,
							ry,
							numbers[ 0 ],
							numbers[ 1 ]
						);
						control.x = rx;
						control.y = ry;
						point.x = numbers[ 0 ];
						point.y = numbers[ 1 ];
						break;

					case 'A':
						// TODO:
						break;

					case 'm':
						var numbers = parseFloats( data );
						point.x += numbers[ 0 ];
						point.y += numbers[ 1 ];
						control.x = point.x;
						control.y = point.y;
						path.moveTo( point.x, point.y );
						break;

					case 'h':
						var numbers = parseFloats( data );
						point.x += numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'v':
						var numbers = parseFloats( data );
						point.y += numbers[ 0 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'l':
						var numbers = parseFloats( data );
						point.x += numbers[ 0 ];
						point.y += numbers[ 1 ];
						control.x = point.x;
						control.y = point.y;
						path.lineTo( point.x, point.y );
						break;

					case 'c':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ],
							point.x + numbers[ 2 ],
							point.y + numbers[ 3 ],
							point.x + numbers[ 4 ],
							point.y + numbers[ 5 ]
						);
						point.x += numbers[ 4 ];
						point.y += numbers[ 5 ];
						break;

					case 's':
						var numbers = parseFloats( data );
						path.bezierCurveTo(
							// TODO: Not sure if point needs
							// to be added to reflection...
							getReflection( point.x, control.x ),
							getReflection( point.y, control.y ),
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ],
							point.x + numbers[ 2 ],
							point.y + numbers[ 3 ]
						);
						control.x = point.x + numbers[ 0 ];
						control.y = point.y + numbers[ 1 ];
						point.x += numbers[ 2 ];
						point.y += numbers[ 3 ];
						break;

					case 'q':
						var numbers = parseFloats( data );
						path.quadraticCurveTo(
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ],
							point.x + numbers[ 2 ],
							point.y + numbers[ 3 ]
						);
						control.x = point.x + numbers[ 0 ];
						control.y = point.y + numbers[ 1 ];
						point.x += numbers[ 2 ];
						point.y += numbers[ 3 ];
						break;

					case 't':
						var numbers = parseFloats( data );
						var rx = getReflection( point.x, control.x );
						var ry = getReflection( point.y, control.y );
						path.quadraticCurveTo(
							rx,
							ry,
							point.x + numbers[ 0 ],
							point.y + numbers[ 1 ]
						);
						control.x = rx;
						control.y = ry;
						point.x = point.x + numbers[ 0 ];
						point.y = point.y + numbers[ 1 ];
						break;

					case 'a':
						// TODO:
						break;

					case 'Z':
					case 'z':
						path.currentPath.autoClose = true;
						break;

					default:
						console.log( command );

				}

			}

			return path;

		}

		function parseRectNode( node, style ) {

			var x = parseFloat( node.getAttribute( 'x' ) );
			var y = parseFloat( node.getAttribute( 'y' ) );
			var w = parseFloat( node.getAttribute( 'width' ) );
			var h = parseFloat( node.getAttribute( 'height' ) );

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );
			path.moveTo( x, y );
			path.lineTo( x + w, y );
			path.lineTo( x + w, y + h );
			path.lineTo( x, y + h );
			return path;

		}

		function parsePolygonNode( node, style ) {

			function iterator( match, a, b ) {

				var x = parseFloat( a );
				var y = parseFloat( b );

				if ( index === 0 ) {
					path.moveTo( x, y );
				} else {
					path.lineTo( x, y );
				}

				index++;

			}

			var regex = /(-?[\d\.?]+)[,|\s](-?[\d\.?]+)/g;

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );

			var index = 0;

			node.getAttribute( 'points' ).replace(regex, iterator);

			path.currentPath.autoClose = true;

			return path;

		}

		function parsePolylineNode( node, style ) {

			function iterator( match, a, b ) {

				var x = parseFloat( a );
				var y = parseFloat( b );

				if ( index === 0 ) {
					path.moveTo( x, y );
				} else {
					path.lineTo( x, y );
				}

				index++;

			}

			var regex = /(-?[\d\.?]+)[,|\s](-?[\d\.?]+)/g;

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );

			var index = 0;

			node.getAttribute( 'points' ).replace(regex, iterator);

			path.currentPath.autoClose = false;

			return path;

		}

		function parseCircleNode( node, style ) {

			var x = parseFloat( node.getAttribute( 'cx' ) );
			var y = parseFloat( node.getAttribute( 'cy' ) );
			var r = parseFloat( node.getAttribute( 'r' ) );

			var subpath = new THREE.Path();
			subpath.absarc( x, y, r, 0, Math.PI * 2 );

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );
			path.subPaths.push( subpath );

			return path;

		}

		function parseEllipseNode( node, style ) {

			var x = parseFloat( node.getAttribute( 'cx' ) );
			var y = parseFloat( node.getAttribute( 'cy' ) );
			var rx = parseFloat( node.getAttribute( 'rx' ) );
			var ry = parseFloat( node.getAttribute( 'ry' ) );

			var subpath = new THREE.Path();
			subpath.absellipse( x, y, rx, ry, 0, Math.PI * 2 );

			var path = new THREE.ShapePath();
			path.color.setStyle( parseFill( node, style ) );
			path.subPaths.push( subpath );

			return path;

		}

		function parseLineNode( node, style ) {

			var x1 = parseFloat( node.getAttribute( 'x1' ) );
			var y1 = parseFloat( node.getAttribute( 'y1' ) );
			var x2 = parseFloat( node.getAttribute( 'x2' ) );
			var y2 = parseFloat( node.getAttribute( 'y2' ) );

			var path = new THREE.ShapePath();
			path.moveTo( x1, y1 );
			path.lineTo( x2, y2 );
			path.currentPath.autoClose = false;

			return path;

		}

		//

		function parseStyle( node, style ) {

			if (node.style.fill !== '') style.fill = node.style.fill;

		}

		function parseFill( node, style ) {

			if ( node.hasAttribute( 'fill' ) ) {

				return node.getAttribute( 'fill' );

			}

			if ( style.fill !== '' && style.fill !== 'none' ) {

				return style.fill;

			}

			return '#ffffff';

		}

		// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes

		function getReflection( a, b ) {

			return 2 * a - ( b - a );

		}

		function parseFloats( string ) {

			var array = string.split( /[\s,]+|(?=\s?[+\-])/ );

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

				array[ i ] = parseFloat( array[ i ] );

			}

			return array;

		}

		//

		var xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml

		var svg = xml.documentElement;

		var paths = [];

		parseNode( svg, {} );

		return paths;

	}

};
<|endoftext|>


<commit_before>/**
 * FIFO Queue
 *
 * var Queue = require('./queue');
 * var queue = new Queue();
 *
 * queue.add(function(next) {
 *   setTimeout(function(){
 *     // do some async work
 *     next();
 *   }, 300);
 * });
 *
 * queue.end(function(error) {
 *   // all done
 * });
 */

/*
 * Helpers
 */

function applyToConstructor(constructor, argArray) {
  var args = [null].concat(argArray);
  var factoryFunction = constructor.bind.apply(constructor, args);
  return new factoryFunction();
}

/**
 * Constructor
 */

function Queue() {
  var args = Array.prototype.slice.call(arguments);
  if (!(this instanceof Queue)) {
    return applyToConstructor(Queue, args);
  }
  this._queue = [];
  this._scope = args;
  return this;
}

/*
 * Add step to a queue
 *
 * @param {Function} fn(next)
 * @return {Queue} self
 */

Queue.prototype.add = function(fn) {
  this._queue.push(fn);
  return this;
}

/*
 * Execute queue
 *
 * @param {Function} callback(error)
 */

Queue.prototype.end = Queue.prototype.done = function(cb) {
  if (!this._queue.length) return cb();

  var queue = this._queue;
  var scope = this._scope;

  var next = function(error) {
    if (error !== void 0) return cb(error);

    var task = queue.shift();

    var s = scope.slice(0);

    if (!task)  {
      s.unshift(null);
      return cb.apply(self, s);
    }

    s.push((function(){
      var executed = false;
      return function(error) {
        if (executed) throw new Error('callback can\'t be executed twice');
        executed = true;
        next(error);
      }
    })());

    task.apply(task, s);
  }
  next();
}

/**
 * Expose
 */

exports = module.exports = Queue;
<commit_msg>FIX: missing var<commit_after>/**
 * FIFO Queue
 *
 * var Queue = require('./queue');
 * var queue = new Queue();
 *
 * queue.add(function(next) {
 *   setTimeout(function(){
 *     // do some async work
 *     next();
 *   }, 300);
 * });
 *
 * queue.end(function(error) {
 *   // all done
 * });
 */

/*
 * Helpers
 */

function applyToConstructor(constructor, argArray) {
  var args = [null].concat(argArray);
  var factoryFunction = constructor.bind.apply(constructor, args);
  return new factoryFunction();
}

/**
 * Constructor
 */

function Queue() {
  var args = Array.prototype.slice.call(arguments);
  if (!(this instanceof Queue)) {
    return applyToConstructor(Queue, args);
  }
  this._queue = [];
  this._scope = args;
  return this;
}

/*
 * Add step to a queue
 *
 * @param {Function} fn(next)
 * @return {Queue} self
 */

Queue.prototype.add = function(fn) {
  this._queue.push(fn);
  return this;
}

/*
 * Execute queue
 *
 * @param {Function} callback(error)
 */

Queue.prototype.end = Queue.prototype.done = function(cb) {
  if (!this._queue.length) return cb();

  var queue = this._queue;
  var scope = this._scope;
  var self = this;

  var next = function(error) {
    if (error !== void 0) return cb(error);

    var task = queue.shift();

    var s = scope.slice(0);

    if (!task)  {
      s.unshift(null);
      return cb.apply(self, s);
    }

    s.push((function(){
      var executed = false;
      return function(error) {
        if (executed) throw new Error('callback can\'t be executed twice');
        executed = true;
        next(error);
      }
    })());

    task.apply(task, s);
  }
  next();
}

/**
 * Expose
 */

exports = module.exports = Queue;
<|endoftext|>