<commit_before>'use strict'

var Args = require('args-js')
var events = require('events')
var myUtils = require('./utils')
var Packet = require('./packet')
var Q = require('q')
var UdpTransport = require('./transports/udp')
var util = require('util')
var winston = require('winston-debug')
var winstonWrapper = require('winston-meta-wrapper')

var MAX_RETRANSMISSIONS = 5

// Create client
var StunComm = function () {
  // logging
  this._log = winstonWrapper(winston)
  this._log.addMeta({
    module: 'stun:client'
  })
  // event emitter
  events.EventEmitter.call(this)
  // parse args
  var functionArgs = new Args([
    { stunHost: Args.STRING | Args.Required },
    { stunPort: Args.INT | Args.Required },
    { transport: Args.OBJECT | Args.Optional }
  ], arguments)
  // init
  this._stunHost = functionArgs.stunHost
  this._stunPort = functionArgs.stunPort
  this._transport = functionArgs.transport
  if (this._transport === undefined) {
    this._transport = new UdpTransport()
  }
  this._unackedSendOperations = {}
  this._decoders = []
  this._decoders.push({
    decoder: Packet.decode,
    listener: this.dispatchStunPacket.bind(this)
  })
  this._availableBytes = new Buffer(0)
  // register _error handler
  myUtils.mixinEventEmitterErrorFunction(this)
}

// Inherit EventEmitter
util.inherits(StunComm, events.EventEmitter)

StunComm.prototype.init = function (onReady) {
  var self = this
  this._transport.init(
    self._stunHost,
    self._stunPort,
    onReady,
    self.onIncomingData(),
    self.onFailure()
  )
}

StunComm.prototype.initP = function () {
  var deferred = Q.defer()
  this.init(
    function () { // on success
      deferred.resolve()
    }
  )
  return deferred.promise
}

// Close client
StunComm.prototype.close = function (done) {
  this._log.debug('closing client')
  this._transport.close(done)
}

StunComm.prototype.closeP = function () {
  this._log.debug('closing client')
  return this._transport.closeP()
}

/** STUN communication */

// Send STUN request
StunComm.prototype.sendStunRequest = function (bytes, onResponse, onFailure) {
  // get tid
  var tid = bytes.readUInt32BE(16)
  this._log.debug('sending stun request with TID ' + tid)
  // store response handlers for this tid
  if (this._unackedSendOperations[tid] === undefined) {
    this._unackedSendOperations[tid] = {
      onResponse: onResponse,
      onFailure: onFailure
    }
  }
  // send bytes
  this._transport.send(
    bytes,
    function () { // on success
      // do nothing
    },
    function (error) { // on failure
      onFailure(error)
    }
  )
  var self = this
  // when stun transport is unreliable
  if (!this._transport.isReliable()) {
    // set # of retransmissions if undefined
    if (this._unackedSendOperations[tid].remainingRetransmissionAttempts === undefined) {
      this._unackedSendOperations[tid].remainingRetransmissionAttempts = MAX_RETRANSMISSIONS
    }
    // start retransmission timer
    var timeout = setTimeout(
      function () {
        if (self._unackedSendOperations[tid].remainingRetransmissionAttempts === 0) {
          // stopping retransmission
          var errorMsg = 'giving up, no more retransmission attempts left'
          self._log.error(errorMsg)
          self._error(errorMsg, onFailure)
          delete self._unackedSendOperations[tid]
        } else {
          self._unackedSendOperations[tid].remainingRetransmissionAttempts--
          self.sendStunRequest(bytes, onResponse, onFailure)
        }
      },
      self._transport.getTimeoutDelay()
    )
    self._unackedSendOperations[tid].retransmissionTimeout = timeout
  }
}

StunComm.prototype.sendStunRequestP = function (bytes) {
  var deferred = Q.defer()
  this.sendStunRequest(
    bytes,
    function (stunResponse) { // on response
      deferred.resolve(stunResponse)
    },
    function (error) { // on failure
      deferred.reject(error)
    }
  )
  return deferred.promise
}

// Send STUN indication
StunComm.prototype.sendStunIndicationP = function (bytes) {
  return this._transport.sendP(bytes)
}

StunComm.prototype.sendStunIndication = function (bytes, onSuccess, onFailure) {
  if (onSuccess === undefined || onFailure === undefined) {
    var errorMsg = 'send stun indication callback handlers are undefined'
    this._log.error(errorMsg)
    throw new Error(errorMsg)
  }
  this._transport.send(bytes, onSuccess, onFailure)
}

// Incoming data handler
StunComm.prototype.onIncomingData = function () {
  var self = this
  return function (bytes, rinfo, isFrame) {
    self._log.debug('receiving data from ' + JSON.stringify(rinfo))
    self._availableBytes = Buffer.concat([self._availableBytes, bytes])
    self.parseIncomingData(rinfo, isFrame)
  }
}

StunComm.prototype.parseIncomingData = function (rinfo, isFrame) {
  var self = this
  // iterate over registered decoders
  for (var i in this._decoders) {
    var decoder = this._decoders[i].decoder
    var listener = this._decoders[i].listener
    // execute decoder
    var decoding = decoder(self._availableBytes, isFrame)
    // if decoding was successful
    if (decoding) {
      // store remaining bytes (if any) for later use
      this._availableBytes = decoding.remainingBytes
      // dispatch packet
      listener(decoding.packet, rinfo)
      // if there are remaining bytes, then trigger new parsing round
      if (this._availableBytes.length !== 0) {
        this.parseIncomingData(rinfo, isFrame)
      }
      // and break
      break
    }
  }
}

StunComm.prototype.dispatchStunPacket = function (stunPacket, rinfo) {
  switch (stunPacket.type) {
    case Packet.TYPE.SUCCESS_RESPONSE:
      this._log.debug('incoming STUN success response with tid ' + stunPacket.tid)
      this.onIncomingStunResponse(stunPacket)
      break
    case Packet.TYPE.ERROR_RESPONSE:
      this._log.debug('incoming STUN error response with tid ' + stunPacket.tid)
      this.onIncomingStunResponse(stunPacket)
      break
    case Packet.TYPE.INDICATION:
      this._log.debug('incoming STUN indication')
      this.onIncomingStunIndication(stunPacket, rinfo)
      break
    default:
      var errorMsg = "don't know how to process incoming STUN message -- dropping it on the floor"
      this._log.error(errorMsg)
      throw new Error(errorMsg)
  }
}

// Incoming STUN reply
StunComm.prototype.onIncomingStunResponse = function (stunPacket) {
  var sendOperation = this._unackedSendOperations[stunPacket.tid]
  if (sendOperation === undefined) {
    var noSendOperationFoundMessage = 'cannot find associated STUN request for TID ' + stunPacket.tid + ' -- ignoring request'
    this._log.error(noSendOperationFoundMessage)
    return
  }
  // stop retransmission timer (if present)
  var timeout = this._unackedSendOperations[stunPacket.tid].retransmissionTimeout
  if (timeout) {
    clearTimeout(timeout)
  }
  // this is a stun reply
  var onResponseCallback = this._unackedSendOperations[stunPacket.tid].onResponse
  if (onResponseCallback) {
    onResponseCallback(stunPacket)
    delete this._unackedSendOperations[stunPacket.tid]
  } else {
    var errorMsg = 'no handler available to process response with tid ' + stunPacket.tid
    this._log.error(errorMsg)
    throw new Error(errorMsg)
  }
}

// Incoming STUN indication
StunComm.prototype.onIncomingStunIndication = function (stunPacket, rinfo) {
  this.emit('indication', stunPacket, rinfo)
}

// Error handler
StunComm.prototype.onFailure = function () {
  var self = this
  return function (error) {
    var errorMsg = 'client error: ' + error
    self._log.error(errorMsg)
    throw new Error(errorMsg)
  }
}

module.exports = StunComm
<commit_msg>minor update<commit_after>'use strict'

var Args = require('args-js')
var events = require('events')
var myUtils = require('./utils')
var Packet = require('./packet')
var Q = require('q')
var UdpTransport = require('./transports/udp')
var util = require('util')
var winston = require('winston-debug')
var winstonWrapper = require('winston-meta-wrapper')

var MAX_RETRANSMISSIONS = 5

// Create client
var StunComm = function () {
  // logging
  this._log = winstonWrapper(winston)
  this._log.addMeta({
    module: 'stun:client'
  })
  // event emitter
  events.EventEmitter.call(this)
  // parse args
  var functionArgs = new Args([
    { stunHost: Args.STRING | Args.Required },
    { stunPort: Args.INT | Args.Required },
    { transport: Args.OBJECT | Args.Optional }
  ], arguments)
  // init
  this._stunHost = functionArgs.stunHost
  this._stunPort = functionArgs.stunPort
  this._transport = functionArgs.transport
  if (this._transport === undefined) {
    this._transport = new UdpTransport()
  }
  this._unackedSendOperations = {}
  this._decoders = []
  this._decoders.push({
    decoder: Packet.decode,
    listener: this.dispatchStunPacket.bind(this)
  })
  this._availableBytes = new Buffer(0)
  // register _error handler
  myUtils.mixinEventEmitterErrorFunction(this)
}

// Inherit EventEmitter
util.inherits(StunComm, events.EventEmitter)

StunComm.prototype.init = function (onReady) {
  var self = this
  this._transport.init(
    self._stunHost,
    self._stunPort,
    onReady,
    self.onIncomingData(),
    self.onFailure()
  )
}

StunComm.prototype.initP = function () {
  var deferred = Q.defer()
  this.init(
    function () { // on success
      deferred.resolve()
    }
  )
  return deferred.promise
}

// Close client
StunComm.prototype.close = function (done) {
  this._log.debug('closing client')
  this._transport.close(done)
}

StunComm.prototype.closeP = function () {
  this._log.debug('closing client')
  return this._transport.closeP()
}

/** STUN communication */

// Send STUN request
StunComm.prototype.sendStunRequest = function (bytes, onResponse, onFailure) {
  // get tid
  var tid = bytes.readUInt32BE(16)
  this._log.debug('sending stun request with TID ' + tid)
  // store response handlers for this tid
  if (this._unackedSendOperations[tid] === undefined) {
    this._unackedSendOperations[tid] = {
      onResponse: onResponse,
      onFailure: onFailure
    }
  }
  // send bytes
  this._transport.send(
    bytes,
    function () { // on success
      // do nothing
    },
    function (error) { // on failure
      onFailure(error)
    }
  )
  var self = this
  // when stun transport is unreliable
  if (!this._transport.isReliable()) {
    // set # of retransmissions if undefined
    if (this._unackedSendOperations[tid].remainingRetransmissionAttempts === undefined) {
      this._unackedSendOperations[tid].remainingRetransmissionAttempts = MAX_RETRANSMISSIONS
    }
    // start retransmission timer
    var timeout = setTimeout(
      function () {
        if (self._unackedSendOperations[tid].remainingRetransmissionAttempts === 0) {
          // stopping retransmission
          var errorMsg = 'giving up, no more retransmission attempts left'
          self._log.error(errorMsg)
          self._error(errorMsg, onFailure)
          delete self._unackedSendOperations[tid]
        } else {
          self._unackedSendOperations[tid].remainingRetransmissionAttempts--
          self.sendStunRequest(bytes, onResponse, onFailure)
        }
      },
      self._transport.getTimeoutDelay()
    )
    self._unackedSendOperations[tid].retransmissionTimeout = timeout
  }
}

StunComm.prototype.sendStunRequestP = function (bytes) {
  var deferred = Q.defer()
  this.sendStunRequest(
    bytes,
    function (stunResponse) { // on response
      deferred.resolve(stunResponse)
    },
    function (error) { // on failure
      deferred.reject(error)
    }
  )
  return deferred.promise
}

// Send STUN indication
StunComm.prototype.sendStunIndicationP = function (bytes) {
  return this._transport.sendP(bytes)
}

StunComm.prototype.sendStunIndication = function (bytes, onSuccess, onFailure) {
  if (onSuccess === undefined || onFailure === undefined) {
    var errorMsg = 'send stun indication callback handlers are undefined'
    this._log.error(errorMsg)
    throw new Error(errorMsg)
  }
  this._transport.send(bytes, onSuccess, onFailure)
}

// Incoming data handler
StunComm.prototype.onIncomingData = function () {
  var self = this
  return function (bytes, rinfo, isFrame) {
    self._log.debug('receiving data from ' + JSON.stringify(rinfo))
    self._availableBytes = Buffer.concat([self._availableBytes, bytes])
    self.parseIncomingData(rinfo, isFrame)
  }
}

StunComm.prototype.parseIncomingData = function (rinfo, isFrame) {
  // iterate over registered decoders
  for (var i in this._decoders) {
    var decoder = this._decoders[i].decoder
    var listener = this._decoders[i].listener
    // execute decoder
    var decoding = decoder(this._availableBytes, isFrame)
    // if decoding was successful
    if (decoding) {
      // store remaining bytes (if any) for later use
      this._availableBytes = decoding.remainingBytes
      // dispatch packet
      listener(decoding.packet, rinfo)
      // if there are remaining bytes, then trigger new parsing round
      if (this._availableBytes.length !== 0) {
        this.parseIncomingData(rinfo, isFrame)
      }
      // and break
      break
    }
  }
}

StunComm.prototype.dispatchStunPacket = function (stunPacket, rinfo) {
  switch (stunPacket.type) {
    case Packet.TYPE.SUCCESS_RESPONSE:
      this._log.debug('incoming STUN success response with tid ' + stunPacket.tid)
      this.onIncomingStunResponse(stunPacket)
      break
    case Packet.TYPE.ERROR_RESPONSE:
      this._log.debug('incoming STUN error response with tid ' + stunPacket.tid)
      this.onIncomingStunResponse(stunPacket)
      break
    case Packet.TYPE.INDICATION:
      this._log.debug('incoming STUN indication')
      this.onIncomingStunIndication(stunPacket, rinfo)
      break
    default:
      var errorMsg = "don't know how to process incoming STUN message -- dropping it on the floor"
      this._log.error(errorMsg)
      throw new Error(errorMsg)
  }
}

// Incoming STUN reply
StunComm.prototype.onIncomingStunResponse = function (stunPacket) {
  var sendOperation = this._unackedSendOperations[stunPacket.tid]
  if (sendOperation === undefined) {
    var noSendOperationFoundMessage = 'cannot find associated STUN request for TID ' + stunPacket.tid + ' -- ignoring request'
    this._log.error(noSendOperationFoundMessage)
    return
  }
  // stop retransmission timer (if present)
  var timeout = this._unackedSendOperations[stunPacket.tid].retransmissionTimeout
  if (timeout) {
    clearTimeout(timeout)
  }
  // this is a stun reply
  var onResponseCallback = this._unackedSendOperations[stunPacket.tid].onResponse
  if (onResponseCallback) {
    onResponseCallback(stunPacket)
    delete this._unackedSendOperations[stunPacket.tid]
  } else {
    var errorMsg = 'no handler available to process response with tid ' + stunPacket.tid
    this._log.error(errorMsg)
    throw new Error(errorMsg)
  }
}

// Incoming STUN indication
StunComm.prototype.onIncomingStunIndication = function (stunPacket, rinfo) {
  this.emit('indication', stunPacket, rinfo)
}

// Error handler
StunComm.prototype.onFailure = function () {
  var self = this
  return function (error) {
    var errorMsg = 'client error: ' + error
    self._log.error(errorMsg)
    throw new Error(errorMsg)
  }
}

module.exports = StunComm
<|endoftext|>


<commit_before>var HTMLMapContainer = require("./html_map_container");
var ScreenPointMappingModule = require("./screen_point_mapping_module");
var ThemesModule = require("./themes_module");
var IndoorsModule = require("./indoors_module");
var PrecacheModule = require("./precache_module");
var CameraModule = require("./camera_module");
var PolygonModule = require("./polygon_module");

var IndoorEntranceMarkerUpdater = require("./indoor_entrance_marker_updater");

var EegeoLeafletMap = require("./eegeo_leaflet_map");

var EegeoMapController = function(mapId, emscriptenApi, domElement, apiKey, options) {

    var _mapId = mapId;
    var _emscriptenApi = emscriptenApi;

    var _screenPointMappingModule = new ScreenPointMappingModule(emscriptenApi);
    var _themesModule = new ThemesModule(emscriptenApi);
    var _indoorsModule = new IndoorsModule(emscriptenApi);
    var _precacheModule = new PrecacheModule(emscriptenApi);
    var _cameraModule = new CameraModule(emscriptenApi);
    var _polygonModule = new PolygonModule(emscriptenApi);

    var _modules = [
        _screenPointMappingModule,
        _themesModule,
        _indoorsModule,
        _precacheModule,
        _cameraModule,
        _polygonModule
    ];

    var _canvasId = options["canvasId"] || "canvas";
    var _canvasWidth = options["width"] || domElement.clientWidth;
    var _canvasHeight = options["height"] || domElement.clientHeight;

    var _mapContainer = new HTMLMapContainer(domElement, _canvasId, _canvasWidth, _canvasHeight);

    var _canvas = _mapContainer.canvas;

    var _Module = window.Module;
    _Module["canvas"] = _canvas;

    var defaultCenter = [37.7858, -122.401];
    var defaultZoom = 12;

    options.center = options.center || defaultCenter;
    options.zoom = options.zoom || defaultZoom;

    var centerLatLng = L.latLng(options.center);
    var distance = _cameraModule.zoomLevelToDistance(options.zoom);

    var indoorsEnabled = !!options["indoorsEnabled"];
    var indoorsEnabledArg = (indoorsEnabled) ? "1" : "0";

    _Module["arguments"] = [
        _canvasId,
        _mapId.toString(),
        _canvasWidth.toString(),
        _canvasHeight.toString(),
        apiKey,
        centerLatLng.lat.toString(),
        centerLatLng.lng.toString(),
        distance.toString(),
        indoorsEnabledArg
        ];

    options.zoomControl = false;

    this.leafletMap = new EegeoLeafletMap(_mapContainer.overlay, options, _cameraModule, _screenPointMappingModule, _precacheModule, _themesModule, _indoorsModule, _polygonModule);

    var displayEntranceMarkers = !!options["displayEntranceMarkers"];

    this._indoorEntranceMarkerUpdater = null;

    if (displayEntranceMarkers) {
        this._indoorEntranceMarkerUpdater = new IndoorEntranceMarkerUpdater(this.leafletMap, _indoorsModule);
    }

    var _resizeCanvas = null;

    var _updateCanvasSize = function() {
        var newWidth = _mapContainer.width();
        var newHeight = _mapContainer.height();

        if (newWidth !== _canvasWidth || newHeight !== _canvasHeight) {
            _resizeCanvas(newWidth, newHeight);
            _canvasWidth = newWidth;
            _canvasHeight = newHeight;
        }
    };

    this.onInitialized = function(apiPointer) {
        _mapContainer.onInitialized();
        _resizeCanvas = _Module.cwrap("resizeCanvas", null, ["number", "number"]);
        _emscriptenApi.onInitialized(apiPointer, _onUpdate, _onDraw, _onInitialStreamingCompleted);
        _modules.forEach(function(module) {
            module.onInitialized();
        });
        this.leafletMap.onInitialized(_emscriptenApi);
    };

    var _this = this;

    var _onUpdate = function(deltaSeconds) {
        _updateCanvasSize();

        _modules.forEach(function(module) {
            module.onUpdate(deltaSeconds);
        });
    };

    var _onDraw = function(deltaSeconds) {
        _modules.forEach(function(module) {
            module.onDraw(deltaSeconds);
        });

        _this.leafletMap.update();
    };

    var _onInitialStreamingCompleted = function() {
        _modules.forEach(function(module) {
            module.onInitialStreamingCompleted();
        });
    };
};

module.exports = EegeoMapController;<commit_msg>Flipping displayEntranceMarkers flag so that it's true by default (if not defined, for example). Buddy: Paul H<commit_after>var HTMLMapContainer = require("./html_map_container");
var ScreenPointMappingModule = require("./screen_point_mapping_module");
var ThemesModule = require("./themes_module");
var IndoorsModule = require("./indoors_module");
var PrecacheModule = require("./precache_module");
var CameraModule = require("./camera_module");
var PolygonModule = require("./polygon_module");

var IndoorEntranceMarkerUpdater = require("./indoor_entrance_marker_updater");

var EegeoLeafletMap = require("./eegeo_leaflet_map");

var EegeoMapController = function(mapId, emscriptenApi, domElement, apiKey, options) {

    var _mapId = mapId;
    var _emscriptenApi = emscriptenApi;

    var _screenPointMappingModule = new ScreenPointMappingModule(emscriptenApi);
    var _themesModule = new ThemesModule(emscriptenApi);
    var _indoorsModule = new IndoorsModule(emscriptenApi);
    var _precacheModule = new PrecacheModule(emscriptenApi);
    var _cameraModule = new CameraModule(emscriptenApi);
    var _polygonModule = new PolygonModule(emscriptenApi);

    var _modules = [
        _screenPointMappingModule,
        _themesModule,
        _indoorsModule,
        _precacheModule,
        _cameraModule,
        _polygonModule
    ];

    var _canvasId = options["canvasId"] || "canvas";
    var _canvasWidth = options["width"] || domElement.clientWidth;
    var _canvasHeight = options["height"] || domElement.clientHeight;

    var _mapContainer = new HTMLMapContainer(domElement, _canvasId, _canvasWidth, _canvasHeight);

    var _canvas = _mapContainer.canvas;

    var _Module = window.Module;
    _Module["canvas"] = _canvas;

    var defaultCenter = [37.7858, -122.401];
    var defaultZoom = 12;

    options.center = options.center || defaultCenter;
    options.zoom = options.zoom || defaultZoom;

    var centerLatLng = L.latLng(options.center);
    var distance = _cameraModule.zoomLevelToDistance(options.zoom);

    var indoorsEnabled = !!options["indoorsEnabled"];
    var indoorsEnabledArg = (indoorsEnabled) ? "1" : "0";

    _Module["arguments"] = [
        _canvasId,
        _mapId.toString(),
        _canvasWidth.toString(),
        _canvasHeight.toString(),
        apiKey,
        centerLatLng.lat.toString(),
        centerLatLng.lng.toString(),
        distance.toString(),
        indoorsEnabledArg
        ];

    options.zoomControl = false;

    this.leafletMap = new EegeoLeafletMap(_mapContainer.overlay, options, _cameraModule, _screenPointMappingModule, _precacheModule, _themesModule, _indoorsModule, _polygonModule);

    var displayEntranceMarkers = !!options["displayEntranceMarkers"] || !("displayEntranceMarkers" in options);

    this._indoorEntranceMarkerUpdater = null;

    if (displayEntranceMarkers) {
        this._indoorEntranceMarkerUpdater = new IndoorEntranceMarkerUpdater(this.leafletMap, _indoorsModule);
    }

    var _resizeCanvas = null;

    var _updateCanvasSize = function() {
        var newWidth = _mapContainer.width();
        var newHeight = _mapContainer.height();

        if (newWidth !== _canvasWidth || newHeight !== _canvasHeight) {
            _resizeCanvas(newWidth, newHeight);
            _canvasWidth = newWidth;
            _canvasHeight = newHeight;
        }
    };

    this.onInitialized = function(apiPointer) {
        _mapContainer.onInitialized();
        _resizeCanvas = _Module.cwrap("resizeCanvas", null, ["number", "number"]);
        _emscriptenApi.onInitialized(apiPointer, _onUpdate, _onDraw, _onInitialStreamingCompleted);
        _modules.forEach(function(module) {
            module.onInitialized();
        });
        this.leafletMap.onInitialized(_emscriptenApi);
    };

    var _this = this;

    var _onUpdate = function(deltaSeconds) {
        _updateCanvasSize();

        _modules.forEach(function(module) {
            module.onUpdate(deltaSeconds);
        });
    };

    var _onDraw = function(deltaSeconds) {
        _modules.forEach(function(module) {
            module.onDraw(deltaSeconds);
        });

        _this.leafletMap.update();
    };

    var _onInitialStreamingCompleted = function() {
        _modules.forEach(function(module) {
            module.onInitialStreamingCompleted();
        });
    };
};

module.exports = EegeoMapController;<|endoftext|>


<commit_before>/*
    JQuery-esque selector for DOM elements

    usage:

       let elements = selector('.my-selector');

       elements.css({
         'background-color': 'red',
         fontSize: '30px'
       });

       elements.each((element) => {
         // do stuff with element
       });

============================================================================ */

function selector(selectors, parent = document) {

    let singleNode = false;
    let nodes;

    /*
       Node
    ------------------------------------ */

    function ifNode(node) {
       return (
         typeof HTMLElement === "object" ?
          node instanceof HTMLElement : //DOM2
          node && typeof node === "object" && node !== null && node.nodeType === 1 && typeof node.nodeName==="string"
       )
    }

    function getNodes() {
       if (ifNode(selectors)) {
         singleNode = true
         nodes = selectors
       } else {
         nodes = parent.querySelectorAll(selectors);
       }
    }

    function eachNode(callback) {
       if (!singleNode) {
         let i = 0;
         for (let i = 0; i < nodes.length; i++) {
          callback(nodes[i])
         }
       } else {
         callback(nodes)
       }

       return this;
    }

    /*
       Css
    ------------------------------------ */

    function changeNodeCss(css) {
       for (const key of Object.keys(css)) {
         eachNode(node => {
          node.style[key] = css[key]; // eslint-disable-line
         });
       }

       return this;
    }

    /*
       Classes
    ------------------------------------ */

    function addClass(classes) {
       eachNode(element => element.classList.add(classes));

       return this;
    }

    function removeClass(classes) {
       eachNode(element => element.classList.remove(classes));

       return this;
    }

    function toggleClass(classes) {
       eachNode(element => element.classList.toggle(classes));

       return this;
    }

    /*
       Events
    ------------------------------------ */

    function addEvents(eventNames, callback) {
       eachNode(element => {
         eventNames.split(' ').map(eventName => {
          if (eventName) {
              return element.addEventListener(eventName, callback);
          }

          return false
         });
       });

       return this;
    }

    function removeEvents(eventNames, callback) {
       eachNode(element => {
         eventNames.split(' ').map(eventName => {
          element.removeEventListener(eventName, callback);
         });
       });

       return this;
    }

    /*
       initialize
    ------------------------------------ */

    function init() {
       getNodes();
    }

    init();

    return {
       nodes,
       addClass,
       removeClass,
       toggleClass,
       on: addEvents,
       off: removeEvents,
       css: changeNodeCss,
       each: eachNode,
    };
}

export default selector;
<commit_msg>adjust indentions<commit_after>/*
    JQuery-esque selector for DOM elements

    usage:

       let elements = selector('.my-selector');

       elements.css({
         'background-color': 'red',
         fontSize: '30px'
       });

       elements.each((element) => {
         // do stuff with element
       });

============================================================================ */

function selector(selectors, parent = document) {

    let singleNode = false;
    let nodes;

    /*
       Node
    ------------------------------------ */

    function ifNode(node) {
        return (
            typeof HTMLElement === "object" ?
            node instanceof HTMLElement : //DOM2
            node && typeof node === "object" && node !== null && node.nodeType === 1 && typeof node.nodeName==="string"
        )
    }

    function getNodes() {
        if (ifNode(selectors)) {
            singleNode = true
            nodes = selectors
        } else {
            nodes = parent.querySelectorAll(selectors);
        }
    }

    function eachNode(callback) {
        if (!singleNode) {
            let i = 0;
            for (let i = 0; i < nodes.length; i++) {
                callback(nodes[i])
            }
        } else {
            callback(nodes)
        }

        return this;
    }

    /*
       Css
    ------------------------------------ */

    function changeNodeCss(css) {
        for (const key of Object.keys(css)) {
            eachNode(node => {
                node.style[key] = css[key]; // eslint-disable-line
            });
        }

        return this;
    }

    /*
       Classes
    ------------------------------------ */

    function addClass(classes) {
        eachNode(element => element.classList.add(classes));

        return this;
    }

    function removeClass(classes) {
        eachNode(element => element.classList.remove(classes));

        return this;
    }

    function toggleClass(classes) {
        eachNode(element => element.classList.toggle(classes));

        return this;
    }

    /*
       Events
    ------------------------------------ */

    function addEvents(eventNames, callback) {
        eachNode(element => {
            eventNames.split(' ').map(eventName => {
                if (eventName) {
                    return element.addEventListener(eventName, callback);
                }

                return false
            });
        });

        return this;
    }

    function removeEvents(eventNames, callback) {
        eachNode(element => {
            eventNames.split(' ').map(eventName => {
                element.removeEventListener(eventName, callback);
            });
        });

        return this;
    }

    /*
       initialize
    ------------------------------------ */

    function init() {
        getNodes();
    }

    init();

    return {
        nodes,
        addClass,
        removeClass,
        toggleClass,
        on: addEvents,
        off: removeEvents,
        css: changeNodeCss,
        each: eachNode,
    };
}

export default selector;
<|endoftext|>


<commit_before>var name = 'For loop iterates over dynamic array: '
var desc = 'The number of \'for\' loop iterations depends on dynamic array\'s size'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')

function forLoopIteratesOverDynamicArray () {
  this.relevantNodes = []
}

forLoopIteratesOverDynamicArray.prototype.visit = function (node) {
    if (common.isForLoop(node) &&
    node.children[1].children[1].attributes.member_name === 'length' &&
    node.children[1].children[1].children[0].attributes.type.indexOf('[]') != -1) {
      this.relevantNodes.push(node)
    }
}

forLoopIteratesOverDynamicArray.prototype.report = function (compilationResults) {
  return this.relevantNodes.map((node) => {
    return {
      warning: 'Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully: Due to the block gas limit, transactions can only consume a certain amount of gas. The number of iterations in a loop can grow beyond the block gas limit which can cause the complete contract to be stalled at a certain point. Additionally, using unbounded loops incurs in a lot of avoidable gas costs. Carefully test how many items at maximum you can pass to such functions to make it successful.',
      location: node.src,
      more: 'http://solidity.readthedocs.io/en/v0.4.24/security-considerations.html#gas-limit-and-loops'
    }
  })
}

module.exports = {
  name: name,
  description: desc,
  category: categories.GAS,
  Module: forLoopIteratesOverDynamicArray
}
<commit_msg>Static analysis: Update module for loop iteration over dynamic array<commit_after>var name = 'For loop iterates over dynamic array: '
var desc = 'The number of \'for\' loop iterations depends on dynamic array\'s size'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')

function forLoopIteratesOverDynamicArray () {
  this.relevantNodes = []
}

forLoopIteratesOverDynamicArray.prototype.visit = function (node) {
	if (common.isForLoop(node) &&
	node.children[1].children[1].attributes.member_name === 'length' &&
	node.children[1].children[1].children[0].attributes.type.indexOf('[]') !== -1) {
		this.relevantNodes.push(node)
	}
}

forLoopIteratesOverDynamicArray.prototype.report = function (compilationResults) {
  return this.relevantNodes.map((node) => {
    return {
      warning: 'Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully: Due to the block gas limit, transactions can only consume a certain amount of gas. The number of iterations in a loop can grow beyond the block gas limit which can cause the complete contract to be stalled at a certain point. Additionally, using unbounded loops incurs in a lot of avoidable gas costs. Carefully test how many items at maximum you can pass to such functions to make it successful.',
      location: node.src,
      more: 'http://solidity.readthedocs.io/en/v0.4.24/security-considerations.html#gas-limit-and-loops'
    }
  })
}

module.exports = {
  name: name,
  description: desc,
  category: categories.GAS,
  Module: forLoopIteratesOverDynamicArray
}
<|endoftext|>


<commit_before>/**
 * Created by simon on 25.03.17.
 */

var fps = 0;
var lastRun;
var canvas = document.getElementById('breakoutCanvas');
var Colors = Object.freeze({"fallableBlock":'#f33', "fallingBlock": '#222', "defaultBlock": '#0095dd'});
resizeCanvas();
var ctx = canvas.getContext('2d');
var game = {speed: 2, paused: false, level: 0, lives: 3};
var levels = [{speed: 2},{speed: 3},{speed:  4},{speed: 5},{speed: 6}, {speed: 7}, {speed: 8}];
var ball = {x: canvas.width / 2, y: canvas.height - 30, radius:10, color: "#0095DD", dx: 2, dy: -2};
var block = { columns: 6, rows: 5,  space: 8 };
block.width = (canvas.width - (block.columns * block.space + block.space)) / (block.columns);
block.height = (canvas.height - (block.rows * block.space + block.space)) / (block.rows * 2);
game.blocks = block.columns * block.rows;
var blocks = [];
var racket = {width: canvas.width / 10, height: 5, x: canvas.width / 2, y: canvas.height - 5, speed: 7};
racket.validate = function(move) {
    return !(((racket.x - racket.width / 2) + move < 0) || ((racket.x + racket.width / 2) + move) > canvas.width);
};
var breakingNotification;

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
document.addEventListener("touchmove", touchMoveHandler, false);

// sets coords and direction to initial values
function initialBall() {
    ball.x = canvas.width / 2;
    ball.y = canvas.height - 30;
    ball.dx = game.speed;
    ball.dy = -game.speed;
}

// sets coords to initial values
function initialRacket() {
    racket.x = canvas.width / 2;
    racket.y = canvas.height - 5;
}

function keyDownHandler(e) {
    if (e.keyCode === 39) {
        racket.rightPressed = true;
    } else if (e.keyCode === 37) {
        racket.leftPressed = true;
    } else if (e.keyCode === 32) {
        game.paused = !game.paused;
        if (!game.paused) {
            showHelp();
        }
        if (game.lives < 1) {
            initializeGame(0);
        }
        if (breakingNotification) {
            hideBreakingNotification();
        }
    } else if (e.keyCode === 38) {
        racket.speed = racket.speed + 1;
        updateInfo();
    } else if (e.keyCode === 40) {
        racket.speed = racket.speed - 1;
        updateInfo();
    } else if (e.keyCode === 72) {
        game.paused = !game.paused;
        showHelp();
    }
}

function keyUpHandler(e) {
    if (e.keyCode === 39) {
        racket.rightPressed = false;
    } else if (e.keyCode === 37) {
        racket.leftPressed = false;
    }
}

function mouseMoveHandler(e) {
    var move = e.clientX - canvas.offsetLeft;
    if ((move-racket.width)+3 > 0 && move < canvas.width+3) {
        racket.x = move - racket.width / 2;
    }
}

function touchMoveHandler(e) {
    e.preventDefault();
    var touch = e.touches[0].pageX || e.changedTouches[0].pageX;
    var move = touch - canvas.offsetLeft;
        if (move > 0 && move < canvas.width) {
            racket.x = move - racket.width / 2;
        }
}

function createBlocks() {
    for (var i = 0; i < block.columns; i++) {
        blocks[i] = [];
        for (var j = 0; j < block.rows; j++) {
            fallable = false;
            if (Math.random() >= 0.7) {
                fallable = true;
            }
            blocks[i][j] = {x: i * block.width + i * block.space + block.space, y: j * block.height + j * block.space, w: block.width, h: block.height, destroyed: false, fallable: fallable };
        }
    }
}

function drawBlocks() {
    blocks.map(function(blockColumn) {
        blockColumn.map(drawBlock);
    });
}

function drawBlock(b) {
    ctx.beginPath();
    if(!b.destroyed) {
        if (b.fallable) {
            ctx.strokeStyle = Colors.fallableBlock;
        } else {
            ctx.strokeStyle = Colors.defaultBlock;
        }
        b.destroyed = hitDetection(b, ball);
        ctx.moveTo(b.x,b.y+b.h/2);
        ctx.lineTo(b.x+b.w,b.y+b.h/2);
        ctx.lineWidth = b.h;
        ctx.stroke();
    } else if (b.destroyed && b.fallable) {
        b.y = b.y + 2;
        ctx.strokeStyle = Colors.fallingBlock;
        ctx.moveTo(b.x,b.y+b.h/2);
        ctx.lineTo(b.x+b.w,b.y+b.h/2);
        ctx.lineWidth = b.h;
    }
     //if (b.y >= canvas.height) {
    if (hitDetectionBlockRacket(b,racket)) {
        game.lives = game.lives - 1;
        game.paused = true;
        showBreakingNotification('FAIL
'+game.lives+' Lives left
Press Space to continue','FAIL');
        initialBall();
        initialRacket();
        updateInfo();
    }
    ctx.stroke();
}

function hitDetectionBlockRacket(b, r) {
    leftRacket = r.x - (r.width/2);
    rightRacket = r.x + (r.width/2);
    topRacket = r.y;
    bottomRacket = r.y + r.height;

    leftBlock = b.x;
    rightBlock = b.x + b.w;
    topBlock = b.y;
    bottomBlock = b.y + (b.h);

    maxLeft = Math.max(leftRacket,leftBlock);
    minRight = Math.min(rightRacket,rightBlock);
    minBot = Math.min(bottomRacket,bottomBlock);
    maxTop = Math.max(topRacket,topBlock);
    return (minBot >= maxTop) && (minRight > maxLeft)
}

function drawRacket() {
    if (racket.rightPressed && racket.validate(racket.speed)) {
        racket.x += racket.speed;
    } else if (racket.leftPressed && racket.validate(-racket.speed)) {
        racket.x -= racket.speed;
    }
    ctx.fillRect(racket.x - (racket.width /2), racket.y, racket.width, racket.height);
}

function drawBall() {
    ctx.beginPath();
    ctx.arc(ball.x, ball.y, ball.radius/2, 0, Math.PI * 2);
    ctx.strokeStyle = ball.color;
    ctx.lineWidth = ball.radius;
    ctx.stroke();
    ball.x += ball.dx;
    ball.y += ball.dy;

    var rab = {x: racket.width / 2, y: 0};
    var rba = {x: -racket.width / 2, y:0};
    var raz = {x: ball.x - (racket.x - racket.width/2), y: ball.y - racket.y};
    var rbz = {x: ball.x - (racket.x + racket.width/2), y: ball.y - racket.y};

    if (ball.x >= canvas.width - ball.radius || ball.x <= ball.radius) {
        ball.dx = ball.dx * -1;
    }

    if (ball.y <= ball.radius) {
        ball.dy = ball.dy * -1;
    } else if (helpDetection(rab,raz,rba,rbz)) {
            ball.dy = ball.dy *-1;

    } else if (ball.y >= canvas.height - ball.radius) {
        game.lives = game.lives - 1;
        game.paused = true;
        if (game.lives < 1) {
            showBreakingNotification('GAME OVER
Press Space to start new game','FAIL');
        } else {
            showBreakingNotification('FAIL
'+game.lives+' Lives left
Press Space to continue','FAIL');
            initialBall();
            initialRacket();
            updateInfo();
        }
    }
}

// text: Text to show in the notification
// type: Type of the notification: FAIL, INFO, SUCCESS
function showBreakingNotification(text,type) {
    switch (type) {
        case 'FAIL':
            document.getElementById('breakingNotificationText').className = 'fail';
            break;
        case 'SUCCESS':
            document.getElementById('breakingNotificationText').className = 'success';
            break;
        default:
            document.getElementById('breakingNotificationText').className = 'info';
            break;
    }
    game.paused = true;
    breakingNotification = true;
    document.getElementById('breakingNotificationBG').className = 'show';
    document.getElementById('breakingNotificationText').innerHTML = text;
}

function hideBreakingNotification() {
    breakingNotification = false;
    document.getElementById('breakingNotificationBG').className = '';
}

function hitDetection(block, ball) {
    // Set edge above (AB)
    var ab = {x: block.w, y: 0};
    var ba = {x: -block.w, y: 0};

    // Set edge below (CD)
    var cd = ab;
    var dc = ba;

    // Set edge left
    var ac = {x: 0, y: block.h};
    var ca = {x: 0, y: -block.h};

    // Above edge right
    var bd = ac;
    var db = ca;

    // Set edge to ball
    var az = {x: ball.x - block.x, y: ball.y - block.y};
    var bz = {x: ball.x - (block.x + block.w), y: ball.y - block.y};
    var cz = {x: ball.x - block.x, y: ball.y - (block.y + block.h)};
    var dz = {x: ball.x - (block.x + block.w), y: ball.y - (block.y + block.h)};

    if (helpDetection(cd,cz,dc,dz) || helpDetection(ab,az,ba,bz)) {
        ball.dy = -ball.dy;
        game.blocks -= 1;
        return true;
    } else if (helpDetection(ac,az,ca,cz) || helpDetection(bd,bz,db,dz)) {
        ball.dx = -ball.dx;
        game.blocks -= 1;
        return true;
    }
    return false;
}

function helpDetection(ab,az,ba,bz) {
    var normalLength = Math.sqrt(Math.pow(ab.x,2)+Math.pow(ab.y,2));
    var distance = Math.abs((az.x*ab.y-az.y*ab.x)/normalLength);

    if (distance < ball.radius) {
        // Calculate angle
        var skalarproduct1 = ab.x * az.x + ab.y * az.y;
        if (skalarproduct1 >= 0) {
            var skalarproduct2 = ba.x * bz.x + ba.y * bz.y;
            if (skalarproduct2 >= 0) {
                return true;
            }
        }
    }
    return false;
}

function resizeCanvas() {
    console.log("resizing Canvas");
    var fullWidth = window.innerWidth && document.documentElement.clientWidth ?
        Math.min(window.innerWidth, document.documentElement.clientWidth) :
        window.innerWidth ||
        document.documentElement.clientWidth ||
        document.getElementsByTagName('body')[0].clientWidth;
    var fullHeight = window.innerHeight && document.documentElement.clientHeight ?
        Math.min(window.innerHeight, document.documentElement.clientHeight) :
        window.innerHeight ||
        document.documentElement.clientHeight ||
        document.getElementsByTagName('body')[0].clientHeight;
    var gameWidth = Math.round(fullWidth * 0.8);
    var gameHeight = Math.round(fullHeight * 0.8);
    canvas.width = gameWidth;
    canvas.height = gameHeight;
    document.getElementById('game').style.width = gameWidth+'px';
    document.getElementById('game').style.height = gameHeight+'px';
}

function showFPS() {
    ctx.fillStyle = "Black";
    ctx.font      = "normal 14pt Arial";
    ctx.fillText(fps + " fps", 5, canvas.height - 10);
}

function updateInfo() {
    //console.log(document.getElementById('lives'));
    document.getElementById('lives').innerHTML = game.lives;
    document.getElementById('level').innerHTML = game.level;
    document.getElementById('racketspeed').innerHTML = racket.speed;
}

/* only shows the help if the game has been paused */
function showHelp() {
    if (game.paused) {
        document.getElementById('helpInfo').style.display = 'inline';
        document.getElementById('helpText').style.display = 'block';
    } else {
        document.getElementById('helpInfo').style.display = 'none';
        document.getElementById('helpText').style.display = 'none';
    }
}

function initializeGame(level) {
    game.paused = true;
    if (level === 0) {
        showHelp();
    }
    if (game.lives === 0 && level === 0) {
        game.lives = 3;
    }
    game.level = level;
    game.speed = levels[game.level].speed;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    createBlocks();
    initialBall();
    initialRacket();
    updateInfo();
    ball.dx = game.speed;
    ball.dy = -game.speed;
    game.blocks = block.columns * block.rows;
}

function draw() {
    if (game.blocks === 0) {
        game.paused = true;
        initializeGame(game.level+1);
        showBreakingNotification('CONGRATS
You reached level '+game.level,'SUCCESS');
    }

    if (!game.paused) {
        var delta = (new Date().getTime() - lastRun)/1000;
        lastRun = new Date().getTime();
        fps = (1/delta).toFixed();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawBlocks();
        drawRacket();
        drawBall();
        showFPS();
    }
    requestAnimationFrame(draw);
}
/*
updateInfo();
createBlocks();*/
initializeGame(0);
requestAnimationFrame(draw);<commit_msg>refactor<commit_after>/**
 * Created by simon on 25.03.17.
 */

var fps = 0;
var lastRun;
var canvas = document.getElementById('breakoutCanvas');
resizeCanvas();
var ctx = canvas.getContext('2d');
var game = {speed: 2, paused: false, level: 0, lives: 3};
var levels = [{speed: 2},{speed: 3},{speed:  4},{speed: 5},{speed: 6}, {speed: 7}, {speed: 8}];
var ball = {x: canvas.width / 2, y: canvas.height - 30, radius:10, color: "#0095DD", dx: 2, dy: -2};
var block = { columns: 6, rows: 5,  space: 8 };
block.width = (canvas.width - (block.columns * block.space + block.space)) / (block.columns);
block.height = (canvas.height - (block.rows * block.space + block.space)) / (block.rows * 2);
var blocks = [];
var racket = {width: canvas.width / 10, height: 5, x: canvas.width / 2, y: canvas.height - 5, speed: 7};
racket.validate = function(move) {
    return !(((racket.x - racket.width / 2) + move < 0) || ((racket.x + racket.width / 2) + move) > canvas.width);
};
var breakingNotification;

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
document.addEventListener("touchmove", touchMoveHandler, false);

// sets coords and direction to initial values
function initialBall() {
    ball.x = canvas.width / 2;
    ball.y = canvas.height - 30;
    ball.dx = game.speed;
    ball.dy = -game.speed;
}

function Block(x, y, destroyed = false, fallable = false, w = block.width, h = block.height) {
    this.id = Math.random().toString(16).slice(2);
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.destroyed = destroyed;
    this.fallable = fallable;
    this.color = (function() {
        if (this.fallable) {
            return '#f33';
        } else {
            return '#0095dd';
        }
    })();
    this.destroy = function() {
        if (this.fallable) {
            this.color = '#222';
        }
        this.destroyed = true;
        var index = blocks.map(x => x.id).indexOf(this.id);
        if (index > -1) {
            blocks.splice(index,1);
        }
    };
    this.draw = function() {
        ctx.beginPath();
        if (this.destroyed && !this.fallable) {

        } else {
            if (hitDetection(this, ball)) {
                this.destroy();
            }
            if (this.destroyed && this.fallable) {
                this.y = this.y + 2;
            }
            ctx.strokeStyle = this.color;
            ctx.moveTo(this.x, this.y + this.h / 2);
            ctx.lineTo(this.x + this.w, this.y + this.h / 2);
            ctx.lineWidth = this.h;
        }
        if (hitDetectionBlockRacket(this,racket)) {
            game.lives = game.lives - 1;
            game.paused = true;
            showBreakingNotification('FAIL
'+game.lives+' Lives left
Press Space to continue','FAIL');
            initialBall();
            initialRacket();
            updateInfo();
        }
        ctx.stroke();
    }
}

// sets coords to initial values
function initialRacket() {
    racket.x = canvas.width / 2;
    racket.y = canvas.height - 5;
}

function keyDownHandler(e) {
    if (e.keyCode === 39) {
        racket.rightPressed = true;
    } else if (e.keyCode === 37) {
        racket.leftPressed = true;
    } else if (e.keyCode === 32) {
        game.paused = !game.paused;
        if (!game.paused) {
            showHelp();
        }
        if (game.lives < 1) {
            initializeGame(0);
        }
        if (breakingNotification) {
            hideBreakingNotification();
        }
    } else if (e.keyCode === 38) {
        racket.speed = racket.speed + 1;
        updateInfo();
    } else if (e.keyCode === 40) {
        racket.speed = racket.speed - 1;
        updateInfo();
    } else if (e.keyCode === 72) {
        game.paused = !game.paused;
        showHelp();
    }
}

function keyUpHandler(e) {
    if (e.keyCode === 39) {
        racket.rightPressed = false;
    } else if (e.keyCode === 37) {
        racket.leftPressed = false;
    }
}

function mouseMoveHandler(e) {
    var move = e.clientX - canvas.offsetLeft;
    if ((move-racket.width)+3 > 0 && move < canvas.width+3) {
        racket.x = move - racket.width / 2;
    }
}

function touchMoveHandler(e) {
    e.preventDefault();
    var touch = e.touches[0].pageX || e.changedTouches[0].pageX;
    var move = touch - canvas.offsetLeft;
        if (move > 0 && move < canvas.width) {
            racket.x = move - racket.width / 2;
        }
}

function createBlocks() {
    for (var i = 0; i < block.columns; i++) {
        for (var j = 0; j < block.rows; j++) {
            fallable = false;
            if (Math.random() >= 0.7) {
                fallable = true;
            }
            blocks.push(new Block( i * block.width + i * block.space + block.space,j * block.height + j * block.space,false,fallable));
        }
    }
}

function countBlocks() {
    return blocks.length;
}

function drawBlocks() {
    blocks.map(function(b) {
        b.draw();
    });
}

function hitDetectionBlockRacket(b, r) {
    leftRacket = r.x - (r.width/2);
    rightRacket = r.x + (r.width/2);
    topRacket = r.y;
    bottomRacket = r.y + r.height;

    leftBlock = b.x;
    rightBlock = b.x + b.w;
    topBlock = b.y;
    bottomBlock = b.y + (b.h);

    maxLeft = Math.max(leftRacket,leftBlock);
    minRight = Math.min(rightRacket,rightBlock);
    minBot = Math.min(bottomRacket,bottomBlock);
    maxTop = Math.max(topRacket,topBlock);
    return (minBot >= maxTop) && (minRight > maxLeft)
}

function drawRacket() {
    if (racket.rightPressed && racket.validate(racket.speed)) {
        racket.x += racket.speed;
    } else if (racket.leftPressed && racket.validate(-racket.speed)) {
        racket.x -= racket.speed;
    }
    ctx.fillRect(racket.x - (racket.width /2), racket.y, racket.width, racket.height);
}

function drawBall() {
    ctx.beginPath();
    ctx.arc(ball.x, ball.y, ball.radius/2, 0, Math.PI * 2);
    ctx.strokeStyle = ball.color;
    ctx.lineWidth = ball.radius;
    ctx.stroke();
    ball.x += ball.dx;
    ball.y += ball.dy;

    var rab = {x: racket.width / 2, y: 0};
    var rba = {x: -racket.width / 2, y:0};
    var raz = {x: ball.x - (racket.x - racket.width/2), y: ball.y - racket.y};
    var rbz = {x: ball.x - (racket.x + racket.width/2), y: ball.y - racket.y};

    if (ball.x >= canvas.width - ball.radius || ball.x <= ball.radius) {
        ball.dx = ball.dx * -1;
    }

    if (ball.y <= ball.radius) {
        ball.dy = ball.dy * -1;
    } else if (helpDetection(rab,raz,rba,rbz)) {
            ball.dy = ball.dy *-1;

    } else if (ball.y >= canvas.height - ball.radius) {
        game.lives = game.lives - 1;
        game.paused = true;
        if (game.lives < 1) {
            showBreakingNotification('GAME OVER
Press Space to start new game','FAIL');
        } else {
            showBreakingNotification('FAIL
'+game.lives+' Lives left
Press Space to continue','FAIL');
            initialBall();
            initialRacket();
            updateInfo();
        }
    }
}

// text: Text to show in the notification
// type: Type of the notification: FAIL, INFO, SUCCESS
function showBreakingNotification(text,type) {
    switch (type) {
        case 'FAIL':
            document.getElementById('breakingNotificationText').className = 'fail';
            break;
        case 'SUCCESS':
            document.getElementById('breakingNotificationText').className = 'success';
            break;
        default:
            document.getElementById('breakingNotificationText').className = 'info';
            break;
    }
    game.paused = true;
    breakingNotification = true;
    document.getElementById('breakingNotificationBG').className = 'show';
    document.getElementById('breakingNotificationText').innerHTML = text;
}

function hideBreakingNotification() {
    breakingNotification = false;
    document.getElementById('breakingNotificationBG').className = '';
}

function hitDetection(block, ball) {
    // Set edge above (AB)
    var ab = {x: block.w, y: 0};
    var ba = {x: -block.w, y: 0};

    // Set edge below (CD)
    var cd = ab;
    var dc = ba;

    // Set edge left
    var ac = {x: 0, y: block.h};
    var ca = {x: 0, y: -block.h};

    // Above edge right
    var bd = ac;
    var db = ca;

    // Set edge to ball
    var az = {x: ball.x - block.x, y: ball.y - block.y};
    var bz = {x: ball.x - (block.x + block.w), y: ball.y - block.y};
    var cz = {x: ball.x - block.x, y: ball.y - (block.y + block.h)};
    var dz = {x: ball.x - (block.x + block.w), y: ball.y - (block.y + block.h)};

    if (helpDetection(cd,cz,dc,dz) || helpDetection(ab,az,ba,bz)) {
        ball.dy = -ball.dy;
        return true;
    } else if (helpDetection(ac,az,ca,cz) || helpDetection(bd,bz,db,dz)) {
        ball.dx = -ball.dx;
        return true;
    }
    return false;
}

function helpDetection(ab,az,ba,bz) {
    var normalLength = Math.sqrt(Math.pow(ab.x,2)+Math.pow(ab.y,2));
    var distance = Math.abs((az.x*ab.y-az.y*ab.x)/normalLength);

    if (distance < ball.radius) {
        // Calculate angle
        var skalarproduct1 = ab.x * az.x + ab.y * az.y;
        if (skalarproduct1 >= 0) {
            var skalarproduct2 = ba.x * bz.x + ba.y * bz.y;
            if (skalarproduct2 >= 0) {
                return true;
            }
        }
    }
    return false;
}

function resizeCanvas() {
    var fullWidth = window.innerWidth && document.documentElement.clientWidth ?
        Math.min(window.innerWidth, document.documentElement.clientWidth) :
        window.innerWidth ||
        document.documentElement.clientWidth ||
        document.getElementsByTagName('body')[0].clientWidth;
    var fullHeight = window.innerHeight && document.documentElement.clientHeight ?
        Math.min(window.innerHeight, document.documentElement.clientHeight) :
        window.innerHeight ||
        document.documentElement.clientHeight ||
        document.getElementsByTagName('body')[0].clientHeight;
    var gameWidth = Math.round(fullWidth * 0.8);
    var gameHeight = Math.round(fullHeight * 0.8);
    canvas.width = gameWidth;
    canvas.height = gameHeight;
    document.getElementById('game').style.width = gameWidth+'px';
    document.getElementById('game').style.height = gameHeight+'px';
}

function showFPS() {
    ctx.fillStyle = "Black";
    ctx.font      = "normal 14pt Arial";
    ctx.fillText(fps + " fps", 5, canvas.height - 10);
}

function updateInfo() {
    document.getElementById('lives').innerHTML = game.lives;
    document.getElementById('level').innerHTML = game.level;
    document.getElementById('racketspeed').innerHTML = racket.speed;
}

/* only shows the help if the game has been paused */
function showHelp() {
    if (game.paused) {
        document.getElementById('helpInfo').style.display = 'inline';
        document.getElementById('helpText').style.display = 'block';
    } else {
        document.getElementById('helpInfo').style.display = 'none';
        document.getElementById('helpText').style.display = 'none';
    }
}

function initializeGame(level) {
    game.paused = true;
    if (level === 0) {
        showHelp();
    }
    if (game.lives === 0 && level === 0) {
        game.lives = 3;
    }
    game.level = level;
    game.speed = levels[game.level].speed;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    createBlocks();
    initialBall();
    initialRacket();
    updateInfo();
    ball.dx = game.speed;
    ball.dy = -game.speed;
}

function draw() {
    if (countBlocks() === 0) {
        game.paused = true;
        initializeGame(game.level+1);
        showBreakingNotification('CONGRATS
You reached level '+game.level,'SUCCESS');
    }
    if (!game.paused) {
        var delta = (new Date().getTime() - lastRun)/1000;
        lastRun = new Date().getTime();
        fps = (1/delta).toFixed();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawBlocks();
        drawRacket();
        drawBall();
        showFPS();
    }
    requestAnimationFrame(draw);
}
/*
updateInfo();
createBlocks();*/
initializeGame(0);
requestAnimationFrame(draw);<|endoftext|>


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

goog.provide('unisubs.translate.TranslationWidget');

/**
 * @constructor
 * @param {Object.<string, *>} subtitle Base language subtitle in json format
 * @param {unisubs.subtitle.EditableCaption} translation
 */
unisubs.translate.TranslationWidget = function(originalNode, translationCaption, dialog, dfxpWrapper) {
    goog.ui.Component.call(this);
    this.originalNode_ = originalNode;
    this.dialog_ = dialog;
    this.videoURL_ = this.dialog_.getVideoPlayerInternal().videoSource_.videoURL_ || '';

    /**
     * @type {unisubs.subtitle.EditableCaption}
     */
    this.translationCaption_ = translationCaption;
    this.dfxpWrapper_ = dfxpWrapper;
};

goog.inherits(unisubs.translate.TranslationWidget, goog.ui.Component);

unisubs.translate.TranslationWidget.prototype.getSubtitle = function(){
    return this.originalNode_;
};
unisubs.translate.TranslationWidget.prototype.getOriginalValue = function(){
    return this.dfxpWrapper_['content'](this.originalNode_);
};

unisubs.translate.TranslationWidget.prototype.createDom = function() {

    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());

    // If we're reviewing or approving a translation, we need to display the timing
    // from the *translation*, not the original.
    var timingToDisplay;
    if (this.dialog_.reviewOrApprovalType_) {
        timingToDisplay = this.translationCaption_.getStartTime();
    } else {
        timingToDisplay = this.dfxpWrapper_['startTime'](this.originalNode_);
    }

    this.setElementInternal(
        $d('li', null,
           $d('div', null,
              $d('span', {'className': 'unisubs-timestamp-time-fixed'},
                         unisubs.formatTime(timingToDisplay)),
              this.originalTitleWidgetThing_ = $d('span', 'unisubs-title unisubs-title-notime', ''),
              this.loadingIndicator_ = $d('span', 'unisubs-loading-indicator', 'loading...')
           ),
           this.translateInput_ = $d('textarea', 'unisubs-translateField')
        )
    );

    this.originalTitleWidgetThing_.innerHTML = this.dfxpWrapper_['markdownToHTML'](this.getOriginalValue());

    this.getHandler()
        .listen(
            this.translateInput_, goog.events.EventType.KEYUP,
            goog.bind(this.inputKeyUp_, this, true))
        .listen(
            this.translateInput_, goog.events.EventType.BLUR,
            goog.bind(this.inputLostFocus_, this, true))
        .listen(
            this.translateInput_, goog.events.EventType.FOCUS,
            this.inputGainedFocus_);
    this.translateInput_.value = this.translationCaption_ ? this.translationCaption_.getText() : '';
};
unisubs.translate.TranslationWidget.prototype.inputGainedFocus_ = function(event) {
    this.onFocusText_ = this.translateInput_.value;
    this.dialog_.getVideoPlayerInternal().showCaptionText(this.onFocusText_ || this.getOriginalValue());
};
unisubs.translate.TranslationWidget.prototype.inputKeyUp_ = function(track) {
    this.onKeyUpText_ = this.translateInput_.value;
    this.dialog_.getVideoPlayerInternal().showCaptionText(this.onKeyUpText_ || this.getOriginalValue());
};
unisubs.translate.TranslationWidget.prototype.inputLostFocus_ = function(track) {
    var value = goog.string.trim(this.translateInput_.value);
    var edited = value != this.onFocusText_;
    if (track && edited) {
        if (this.onFocusText_ == "")
            unisubs.SubTracker.getInstance().trackAdd(this.translationCaption_.getCaptionIndex());
    }
    this.translationCaption_.setText(value);
    this.dialog_.getVideoPlayerInternal().showCaptionText('');
};
unisubs.translate.TranslationWidget.prototype.setTranslationContent = function(value){
    this.translateInput_.value = value;
    this.inputLostFocus_(false);
};
unisubs.translate.TranslationWidget.prototype.setEnabled = function(enabled) {
    this.translateInput_.disabled = !enabled;
    if (!enabled)
        this.translateInput_.value = '';
};
unisubs.translate.TranslationWidget.prototype.getCaptionID = function() {
    return this.dfxpWrapper_['getSubtitleIndex'](this.originalNode_);
};

/**
 * Return if translate input has some value
 * @return {boolean}
 */
unisubs.translate.TranslationWidget.prototype.isEmpty = function(){
    return ! goog.string.trim(this.translateInput_.value);
};

unisubs.translate.TranslationWidget.prototype.showLoadingIndicator = function(){
    unisubs.style.showElement(this.loadingIndicator_, true);
};
unisubs.translate.TranslationWidget.prototype.hideLoadingIndicator = function(){
    unisubs.style.showElement(this.loadingIndicator_, false);
};
<commit_msg>2372: Changing the timing on the source languae should not change the timming on the translation. This was already true for uploads and api calls, however, the translation dialog copy the timming from the source (unless on review or approval, go figure)<commit_after>// Amara, universalsubtitles.org
//
// Copyright (C) 2013 Participatory Culture Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see
// http://www.gnu.org/licenses/agpl-3.0.html.

goog.provide('unisubs.translate.TranslationWidget');

/**
 * @constructor
 * @param {Object.<string, *>} subtitle Base language subtitle in json format
 * @param {unisubs.subtitle.EditableCaption} translation
 */
unisubs.translate.TranslationWidget = function(originalNode, translationCaption, dialog, dfxpWrapper) {
    goog.ui.Component.call(this);
    this.originalNode_ = originalNode;
    this.dialog_ = dialog;
    this.videoURL_ = this.dialog_.getVideoPlayerInternal().videoSource_.videoURL_ || '';

    /**
     * @type {unisubs.subtitle.EditableCaption}
     */
    this.translationCaption_ = translationCaption;
    this.dfxpWrapper_ = dfxpWrapper;
};

goog.inherits(unisubs.translate.TranslationWidget, goog.ui.Component);

unisubs.translate.TranslationWidget.prototype.getSubtitle = function(){
    return this.originalNode_;
};
unisubs.translate.TranslationWidget.prototype.getOriginalValue = function(){
    return this.dfxpWrapper_['content'](this.originalNode_);
};

unisubs.translate.TranslationWidget.prototype.createDom = function() {

    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());

    var timingToDisplay = this.translationCaption_.getStartTime();

    this.setElementInternal(
        $d('li', null,
           $d('div', null,
              $d('span', {'className': 'unisubs-timestamp-time-fixed'},
                         unisubs.formatTime(timingToDisplay)),
              this.originalTitleWidgetThing_ = $d('span', 'unisubs-title unisubs-title-notime', ''),
              this.loadingIndicator_ = $d('span', 'unisubs-loading-indicator', 'loading...')
           ),
           this.translateInput_ = $d('textarea', 'unisubs-translateField')
        )
    );

    this.originalTitleWidgetThing_.innerHTML = this.dfxpWrapper_['markdownToHTML'](this.getOriginalValue());

    this.getHandler()
        .listen(
            this.translateInput_, goog.events.EventType.KEYUP,
            goog.bind(this.inputKeyUp_, this, true))
        .listen(
            this.translateInput_, goog.events.EventType.BLUR,
            goog.bind(this.inputLostFocus_, this, true))
        .listen(
            this.translateInput_, goog.events.EventType.FOCUS,
            this.inputGainedFocus_);
    this.translateInput_.value = this.translationCaption_ ? this.translationCaption_.getText() : '';
};
unisubs.translate.TranslationWidget.prototype.inputGainedFocus_ = function(event) {
    this.onFocusText_ = this.translateInput_.value;
    this.dialog_.getVideoPlayerInternal().showCaptionText(this.onFocusText_ || this.getOriginalValue());
};
unisubs.translate.TranslationWidget.prototype.inputKeyUp_ = function(track) {
    this.onKeyUpText_ = this.translateInput_.value;
    this.dialog_.getVideoPlayerInternal().showCaptionText(this.onKeyUpText_ || this.getOriginalValue());
};
unisubs.translate.TranslationWidget.prototype.inputLostFocus_ = function(track) {
    var value = goog.string.trim(this.translateInput_.value);
    var edited = value != this.onFocusText_;
    if (track && edited) {
        if (this.onFocusText_ == "")
            unisubs.SubTracker.getInstance().trackAdd(this.translationCaption_.getCaptionIndex());
    }
    this.translationCaption_.setText(value);
    this.dialog_.getVideoPlayerInternal().showCaptionText('');
};
unisubs.translate.TranslationWidget.prototype.setTranslationContent = function(value){
    this.translateInput_.value = value;
    this.inputLostFocus_(false);
};
unisubs.translate.TranslationWidget.prototype.setEnabled = function(enabled) {
    this.translateInput_.disabled = !enabled;
    if (!enabled)
        this.translateInput_.value = '';
};
unisubs.translate.TranslationWidget.prototype.getCaptionID = function() {
    return this.dfxpWrapper_['getSubtitleIndex'](this.originalNode_);
};

/**
 * Return if translate input has some value
 * @return {boolean}
 */
unisubs.translate.TranslationWidget.prototype.isEmpty = function(){
    return ! goog.string.trim(this.translateInput_.value);
};

unisubs.translate.TranslationWidget.prototype.showLoadingIndicator = function(){
    unisubs.style.showElement(this.loadingIndicator_, true);
};
unisubs.translate.TranslationWidget.prototype.hideLoadingIndicator = function(){
    unisubs.style.showElement(this.loadingIndicator_, false);
};
<|endoftext|>


<commit_before>// all sample files should not be minified or bundled because it messes up
// how they are shown in the browser, and thus how they are shown in the demo
// but we still want to bundle files that are not "sample" files
var nonSampleBundle = [
  "[shared/*.js]",
  "[*.js]",
  "*.html!text",
  "shared/*.html!text",
  "[installation/*.js]",
  "installation/*.html!text",
  "[about/*.js]",
  "about/*.html!text",
  "[theme-selector/*.js]",
  "theme-selector/*.html!text"
];

var aureliaBundle = [
  "aurelia-framework",
  "aurelia-bootstrapper",
  "aurelia-router",
  "aurelia-templating-binding",
  "aurelia-templating-resources",
  "aurelia-templating-router",
  "aurelia-loader-default",
  "aurelia-history-browser",
  "aurelia-logging-console"
];

var pluginsBundle = [
  "[aurelia-kendoui-plugin]",
  "[aurelia-kendoui-plugin/**/*]",
  "aurelia-kendoui-plugin/**/*.html!text",
  "showdown",
  "prism",
  "jquery",
  "css",
  "text",
  "core-js",
  "json",
  "core-js/library/**/*",
  "babel",
  'showdown-prettify',
  // "core-js/client/**/*",
  // "babel",
  // "babel/browser/**/*",
  // "babel-runtime/helpers/**/*",
  // "babel-runtime/core-js/**/*",
  "bootstrap",
  "bootstrap/css/bootstrap.css!text"
];

// concatenate all bundle definitions
var bundle = nonSampleBundle.concat(aureliaBundle, pluginsBundle);

module.exports = {
  "bundles": {
    "src/app-build": {
      "includes": bundle,
      "options": {
        "inject": true,
        "minify": true,
        "rev": true
      }
    },
    "src/kendo-build": {
      "includes": ["kendo-ui/js/*"],
      "excludes": [
        "[kendo-ui/js/angular.min.js]",
        "[kendo-ui/js/jquery.min.js]",
        "[kendo-ui/js/kendo.angular.min.js]",
        "[kendo-ui/js/kendo.angular2.min.js]",
        "[kendo-ui/js/kendo.spreadsheet.min.js]",
        "[kendo-ui/js/kendo.all.min.js]",
        "[kendo-ui/js/kendo.web.min.js]",
        "[kendo-ui/js/kendo.dataviz.min.js]",
        "[kendo-ui/js/kendo.dataviz.mobile.min.js]",
        "[kendo-ui/js/kendo.mobile.min.js]"
      ],
      "options": {
        "inject": true,
        "minify": true,
        "rev": false
      }
    }
  }
}
<commit_msg>bundle config<commit_after>// all sample files should not be minified or bundled because it messes up
// how they are shown in the browser, and thus how they are shown in the demo
// but we still want to bundle files that are not "sample" files
var nonSampleBundle = [
  "[shared/*.js]",
  "[*.js]",
  "*.html!text",
  "shared/*.html!text",
  "[installation/*.js]",
  "installation/*.html!text",
  "[about/*.js]",
  "about/*.html!text",
  "[theme-selector/*.js]",
  "theme-selector/*.html!text"
];

var aureliaBundle = [
  "aurelia-framework",
  "aurelia-bootstrapper",
  "aurelia-router",
  "aurelia-templating-binding",
  "aurelia-templating-resources",
  "aurelia-templating-router",
  "aurelia-loader-default",
  "aurelia-history-browser",
  "aurelia-logging-console"
];

var pluginsBundle = [
  "[aurelia-kendoui-bridge]",
  "[aurelia-kendoui-bridge/**/*]",
  "aurelia-kendoui-bridge/**/*.html!text",
  "showdown",
  "prism",
  "jquery",
  "css",
  "text",
  "core-js",
  "json",
  "core-js/library/**/*",
  "babel",
  'showdown-prettify',
  // "core-js/client/**/*",
  // "babel",
  // "babel/browser/**/*",
  // "babel-runtime/helpers/**/*",
  // "babel-runtime/core-js/**/*",
  "bootstrap",
  "bootstrap/css/bootstrap.css!text"
];

// concatenate all bundle definitions
var bundle = nonSampleBundle.concat(aureliaBundle, pluginsBundle);

module.exports = {
  "bundles": {
    "src/app-build": {
      "includes": bundle,
      "options": {
        "inject": true,
        "minify": true,
        "rev": true
      }
    },
    "src/kendo-build": {
      "includes": ["kendo-ui/js/*"],
      "excludes": [
        "[kendo-ui/js/angular.min.js]",
        "[kendo-ui/js/jquery.min.js]",
        "[kendo-ui/js/kendo.angular.min.js]",
        "[kendo-ui/js/kendo.angular2.min.js]",
        "[kendo-ui/js/kendo.spreadsheet.min.js]",
        "[kendo-ui/js/kendo.all.min.js]",
        "[kendo-ui/js/kendo.web.min.js]",
        "[kendo-ui/js/kendo.dataviz.min.js]",
        "[kendo-ui/js/kendo.dataviz.mobile.min.js]",
        "[kendo-ui/js/kendo.mobile.min.js]"
      ],
      "options": {
        "inject": true,
        "minify": true,
        "rev": false
      }
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

angular.module('responymous')
  .factory('Firebase', function(CONFIG){
    return new Firebase(CONFIG.Firebase.baseUrl);
  })
  .factory('Auth', function(Firebase, $firebaseAuth, $firebase){
    var auth = $firebaseAuth(Firebase);

    return {
      /**
      * Wrapper for `$firebaseAuth.$onAuth()` that filters the `auth` object
      * through the `updateUser()` function
      */
      onAuth: function(cb){
        auth.$onAuth(function(data){
          cb(updateUser(data));
        });
      },
      getUser: function(){
        return auth.$getCurrentUser();
      },
      /**
      * Wrapper for `$firebaseAuth.$authWithOAuthPopup()` that invokes the
      * correct provider code.
      */
      login: function(){
        return auth.$authWithOAuthRedirect('github');
      },
      /**
      * Wrapper for `$firebaseAuth.$unauth()`
      */
      logout: function(){
        auth.$unauth();
      }
    }; // END service

    /**
    * Tranform the `authdUser` object from `$firebaseAuth` into a full User
    * record in the `/users` collection.
    *
    * @param {Object} authdUser from $firebaseAuth.getAuth()
    * @return {Object} from $firebase.$asObject()
    */
    function updateUser(authdUser){
      if ( authdUser === null ){
        return null;
      }

      var user = $firebase(Firebase
        .child('users')
        .child( authdUser.github.id )
      ).$asObject();

      angular.extend(user, {
        access_token: authdUser.github.accessToken,
        email: authdUser.github.email,
        name: authdUser.github.displayName,
        last_vote: 5,
        current_class: "Q42014FEEORL",
        student: true
      });

      Firebase.child('userClasses')
        .child( authdUser.github.id )
        .set('Q42014FEEORL');

      // Testing code for $asObject and $asArray
      /*var list = $firebase(Firebase
        .child('users')
      ).$asObject();
      console.log(list);*/

      user.$save();

      return user;
    } // END updateUser
  }) // END factory(Auth)

  .controller('MainCtrl', function(Auth,$location) {

    var self = this;

    this.login = Auth.login;
    this.logout = Auth.logout;

    console.log(Auth.getUser);

    Auth.onAuth(function(user){
      self.user = user;
      //$location.path('/student');
    });
  })
;
<commit_msg>inserting code David came up with...which is akin to what I originally had in mind but it still presents the problem of barfing on the user when starting from the beginning, before logging in and auth'ing for the first time. We need a logged-out state?<commit_after>'use strict';

angular.module('responymous')
  .factory('Firebase', function(CONFIG){
    return new Firebase(CONFIG.Firebase.baseUrl);
  })
  .factory('Auth', function(Firebase, $firebaseAuth, $firebase){
    var auth = $firebaseAuth(Firebase);

    return {
      /**
      * Wrapper for `$firebaseAuth.$onAuth()` that filters the `auth` object
      * through the `updateUser()` function
      */
      onAuth: function(cb){
        auth.$onAuth(function(data){
          cb(updateUser(data));
        });
      },
      getUser: function(){
        return auth.$getCurrentUser();
      },
      /**
      * Wrapper for `$firebaseAuth.$authWithOAuthPopup()` that invokes the
      * correct provider code.
      */
      login: function(){
        return auth.$authWithOAuthRedirect('github');
      },
      /**
      * Wrapper for `$firebaseAuth.$unauth()`
      */
      logout: function(){
        auth.$unauth();
      }
    }; // END service

    /**
    * Tranform the `authdUser` object from `$firebaseAuth` into a full User
    * record in the `/users` collection.
    *
    * @param {Object} authdUser from $firebaseAuth.getAuth()
    * @return {Object} from $firebase.$asObject()
    */
    function updateUser(authdUser){
      if ( authdUser === null ){
        return null;
      }

      var user = $firebase(Firebase
        .child('users')
        .child( authdUser.github.id )
      ).$asObject();

      angular.extend(user, {
        access_token: authdUser.github.accessToken,
        email: authdUser.github.email,
        name: authdUser.github.displayName,
        last_vote: 5,
        current_class: "Q42014FEEORL",
        student: true
      });

      Firebase.child('userClasses')
        .child( authdUser.github.id )
        .set('Q42014FEEORL');

      // Testing code for $asObject and $asArray
      /*var list = $firebase(Firebase
        .child('users')
      ).$asObject();
      console.log(list);*/

      user.$save();

      return user;
    } // END updateUser
  }) // END factory(Auth)

  .controller('MainCtrl', function(Auth,$location,$state) {

    var self = this;

    this.login = Auth.login;
    this.logout = Auth.logout;

    // console.log(Auth.getUser);

    Auth.onAuth(function(user){
      self.user = user;

      if(user.current_class == "Q42014FEEORL"){
        if(user.student){
          $state.go('student');
        }else{
          $state.go('instructor')
        }
      }

      //$location.path('/student')
    });
  })
;
<|endoftext|>


<commit_before>'use strict';

let Q = require('q');
let mongoose = require('mongoose');
let guitarSchema = new mongoose.Schema({
    serialNumber: String,
    make: String,
    model: String,
    year: Number,
    factory: String
});

let Guitar = mongoose.model('Guitar', guitarSchema);

class GuitarStore {

    add(serialNumber, make, model, year, factory) {
        let guitarDeferred = Q.defer();
        let guitar = new Guitar({
            serialNumber: serialNumber,
            make: make,
            model: model,
            year: year,
            factory: factory
        });

        guitar.save(function(err, guitar) {
            if (err) {
                guitarDeferred.reject(err);
            } else {
                guitarDeferred.resolve(guitar);
            }
        });
        return guitarDeferred.promise;
    }

    findBySerialNumber(serialNumber) {
        let guitarDeferred = Q.defer();
        Guitar.findOne({ serialNumber: serialNumber }, function(err, guitar) {
            if (err) {
                guitarDeferred.reject(err);
            } else {
                guitarDeferred.resolve(guitar);
            }
        });
        return guitarDeferred.promise;
    }

}

module.exports = GuitarStore;<commit_msg>Small cleanup<commit_after>'use strict';

let Q = require('q');
let mongoose = require('mongoose');
let guitarSchema = new mongoose.Schema({
    serialNumber: String,
    make: String,
    model: String,
    year: Number,
    factory: String
});

let Guitar = mongoose.model('Guitar', guitarSchema);

class GuitarStore {

    add(serialNumber, make, model, year, factory) {
        let guitarDeferred = Q.defer();
        let guitar = new Guitar({serialNumber, make, model, year, factory});

        guitar.save((err, guitar) => {
            if (err) {
                guitarDeferred.reject(err);
            } else {
                guitarDeferred.resolve(guitar);
            }
        });
        return guitarDeferred.promise;
    }

    findBySerialNumber(serialNumber) {
        let guitarDeferred = Q.defer();
        Guitar.findOne({ serialNumber }, (err, guitar) => {
            if (err) {
                guitarDeferred.reject(err);
            } else {
                guitarDeferred.resolve(guitar);
            }
        });
        return guitarDeferred.promise;
    }

}

module.exports = GuitarStore;<|endoftext|>


<commit_before>import React from "react";
import PropTypes from "prop-types";
import BodyClassName from "react-body-classname";
import Helmet from "react-helmet";

import { siteMetadata as config } from "../gatsby-config";

const HTML = ({ color, favicon, body, headComponents, postBodyComponents }) => {
  let head = Helmet.rewind();

  if (!color) {
    color = BodyClassName.rewind() || "green";
  }

  let cssLink;
  if (process.env.NODE_ENV === "production") {
    cssLink = <link rel="stylesheet" href={"/styles.css"} />;
  }
  // Sorry, this is gross.
  let analytics =
    "!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error('Segment snippet included twice.');else{analytics.invoked=!0;analytics.methods=['trackSubmit','trackClick','trackLink','trackForm','pageview','identify','reset','group','track','ready','alias','page','once','off','on'];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement('script');e.type='text/javascript';e.async=!0;e.src=('https:'===document.location.protocol?'https://':'http://')+'cdn.segment.com/analytics.js/v1/'+t+'/analytics.min.js';var n=document.getElementsByTagName('script')[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION='3.1.0';";
  analytics += `analytics.load("${config.segment}");`;
  analytics += "}}();";
  const htmlAttrs = head.htmlAttributes.toComponent();

  return (
    <html {...htmlAttrs}>
      <head>
        <meta charSet="utf-8" />
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0 maximum-scale=1.0, viewport-fit=cover"
        />
        {headComponents}
        {head.meta.toComponent()}
        {head.title.toComponent()}
        <link rel="shortcut icon" href={favicon} />
        <script dangerouslySetInnerHTML={{ __html: analytics }} />
        {cssLink}
      </head>
      <body className={color}>
        <div
          id="___gatsby"
          className="page-wrapper"
          dangerouslySetInnerHTML={{ __html: body }}
        />
        {postBodyComponents}
      </body>
    </html>
  );
};

HTML.propTypes = {
  body: PropTypes.any,
  color: PropTypes.string,
  favicon: PropTypes.string,
  headComponents: PropTypes.any,
  postBodyComponents: PropTypes.any
};

export default HTML;
<commit_msg>Comment out segment so I don't get a million rollbar errors<commit_after>import React from "react";
import PropTypes from "prop-types";
import BodyClassName from "react-body-classname";
import Helmet from "react-helmet";

import { siteMetadata as config } from "../gatsby-config";

const HTML = ({ color, favicon, body, headComponents, postBodyComponents }) => {
  let head = Helmet.rewind();

  if (!color) {
    color = BodyClassName.rewind() || "green";
  }

  let cssLink;
  if (process.env.NODE_ENV === "production") {
    cssLink = <link rel="stylesheet" href={"/styles.css"} />;
  }
  // Sorry, this is gross.
  let analytics =
    "!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error('Segment snippet included twice.');else{analytics.invoked=!0;analytics.methods=['trackSubmit','trackClick','trackLink','trackForm','pageview','identify','reset','group','track','ready','alias','page','once','off','on'];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement('script');e.type='text/javascript';e.async=!0;e.src=('https:'===document.location.protocol?'https://':'http://')+'cdn.segment.com/analytics.js/v1/'+t+'/analytics.min.js';var n=document.getElementsByTagName('script')[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION='3.1.0';";
  analytics += `analytics.load("${config.segment}");`;
  analytics += "}}();";
  const htmlAttrs = head.htmlAttributes.toComponent();

  return (
    <html {...htmlAttrs}>
      <head>
        <meta charSet="utf-8" />
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0 maximum-scale=1.0, viewport-fit=cover"
        />
        {headComponents}
        {head.meta.toComponent()}
        {head.title.toComponent()}
        <link rel="shortcut icon" href={favicon} />
        {/*
        <script dangerouslySetInnerHTML={{ __html: analytics }} />
        */}
        {cssLink}
      </head>
      <body className={color}>
        <div
          id="___gatsby"
          className="page-wrapper"
          dangerouslySetInnerHTML={{ __html: body }}
        />
        {postBodyComponents}
      </body>
    </html>
  );
};

HTML.propTypes = {
  body: PropTypes.any,
  color: PropTypes.string,
  favicon: PropTypes.string,
  headComponents: PropTypes.any,
  postBodyComponents: PropTypes.any
};

export default HTML;
<|endoftext|>


<commit_before>import React from 'react'
import Button from 'material-ui/FloatingActionButton'
import UpdateIcon from 'material-ui/svg-icons/action/update'

function Sakura({doFetchSakuraData, sakuraLists}) {
  sakuraLists.map(list => list.discs).forEach(discs => {
    discs.sort((a, b) => a.this_rank - b.this_rank)
  })
  const style = {
    position: 'fixed',
    bottom: '30px',
    right: '10px'
  }
  return (

      <Button style={style} onTouchTap={doFetchSakuraData}>
        <UpdateIcon/>
      </Button>
      {sakuraLists.map(sakuraList => (

{sakuraList.title}

            rank
            prev
            title

          {sakuraList.discs.map(disc => (

              {disc.this_rank}
              {disc.prev_rank}
              {disc.title}

          ))}

      ))}

  )
}

export default Sakura
<commit_msg>fix: change sakura element id<commit_after>import React from 'react'
import Button from 'material-ui/FloatingActionButton'
import UpdateIcon from 'material-ui/svg-icons/action/update'

function Sakura({doFetchSakuraData, sakuraLists}) {
  sakuraLists.map(list => list.discs).forEach(discs => {
    discs.sort((a, b) => a.this_rank - b.this_rank)
  })
  const style = {
    position: 'fixed',
    bottom: '30px',
    right: '10px'
  }
  return (

      <Button style={style} onTouchTap={doFetchSakuraData}>
        <UpdateIcon/>
      </Button>
      {sakuraLists.map(sakuraList => (

{sakuraList.title}

            rank
            prev
            title

          {sakuraList.discs.map(disc => (

              {disc.this_rank}
              {disc.prev_rank}
              {disc.title}

          ))}

      ))}

  )
}

export default Sakura
<|endoftext|>