<commit_before>var MapRouter = Backbone.Router.extend({
  routes: {
    "restaurants": "restaurants",
    "computerLabs": "computerLabs",
    "auditoriums": "auditoriums",
    "buildings": "buildings",
    "parkingspaces": "parkingspaces",
    "departments": "departments",
    "*actions": "defaultRoute"
  },

  defaultRoute: function (actions) {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel()
    });
    appView.render();

    $('#page-map').trigger("pagecreate");
  },

  restaurants: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({
        types: ["restaurant"],
        filterByCampus: true
      }),
      title: 'map.titles.restaurants'
    });
    appView.render();
    appView.updateLocations();
  },

  computerLabs: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({ types: ["computer_labs"] }),
      title: 'map.titles.computerlabs'
    });
    appView.render();
    appView.updateLocations();
  },

  auditoriums: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({ types: ["auditorium"] }),
      title: 'map.titles.auditoriums'
      // title: "Hör- & skrivsalar"
    });
    appView.render();
    appView.updateLocations();
  },

  buildings: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({
        menu: true,
        types: ["building", "entrance"],
        nonVisibleTypes: ["entrance"]
      }),
      title: 'map.titles.buildings'
    });
    appView.render();
    appView.updateLocations();
  },

  parkingspaces: function () {
    var appModel = new AppModel({
      filterByCampus: true,
      types: ["parking", "handicap_parking", 'entrance'],
      nonVisibleTypes: ["entrance"],
      zoomSensitive: true
    });

    var appView = new AppView({
      el: $('#page-map'),
      model: appModel,
      title: "map.titles.parking"
    });
    var self = this;
    appModel.locations.on('reset', function () {
      self.handleParkingspaceLocationsReset(appView, appModel)
    });
    appView.on('toggleMarkerVisibility', this.handleParkingspaceMarkerVisibility);
    appView.render();
    appView.updateLocations();
  },

  departments: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({
        types: ["organization"]
      }),
      title: 'map.titles.departments'
    });
    appView.render();
    appView.updateLocations();
  },

  /**
   * Handle visibility of parkingspace markers
   *
   * @param locations collecion of locations
   * @param visible true = set markers visible, false = hide markers
   */
  handleParkingspaceMarkerVisibility: function (locations, visible) {
    locations.each(function (item) {
      if (item.get('type') == 'entrance') {
        if (item.get('handicapAdapted') === true) {
          item.set('visible', visible);
        }
        else {
          item.set('visible', false);
        }
      }
    });
  },

  /**
   * Handler for reset event on locations
   *
   * @param appView the app view
   * @param appModel the app model
   */
  handleParkingspaceLocationsReset: function (appView, appModel) {
    appModel.set('zoomSensitive', true);
    appModel.locations.byType(["parking", "handicap_parking"]).each(function (item) {
      item.on('clicked', function () {
        appModel.set('zoomSensitive', false);
        appView.trigger('toggleMarkerVisibility', appModel.locations, true);
      });
    });
  }
});
<commit_msg>MOB-107 - Removed commented code.<commit_after>var MapRouter = Backbone.Router.extend({
  routes: {
    "restaurants": "restaurants",
    "computerLabs": "computerLabs",
    "auditoriums": "auditoriums",
    "buildings": "buildings",
    "parkingspaces": "parkingspaces",
    "departments": "departments",
    "*actions": "defaultRoute"
  },

  defaultRoute: function (actions) {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel()
    });
    appView.render();

    $('#page-map').trigger("pagecreate");
  },

  restaurants: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({
        types: ["restaurant"],
        filterByCampus: true
      }),
      title: 'map.titles.restaurants'
    });
    appView.render();
    appView.updateLocations();
  },

  computerLabs: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({ types: ["computer_labs"] }),
      title: 'map.titles.computerlabs'
    });
    appView.render();
    appView.updateLocations();
  },

  auditoriums: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({ types: ["auditorium"] }),
      title: 'map.titles.auditoriums'
    });
    appView.render();
    appView.updateLocations();
  },

  buildings: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({
        menu: true,
        types: ["building", "entrance"],
        nonVisibleTypes: ["entrance"]
      }),
      title: 'map.titles.buildings'
    });
    appView.render();
    appView.updateLocations();
  },

  parkingspaces: function () {
    var appModel = new AppModel({
      filterByCampus: true,
      types: ["parking", "handicap_parking", 'entrance'],
      nonVisibleTypes: ["entrance"],
      zoomSensitive: true
    });

    var appView = new AppView({
      el: $('#page-map'),
      model: appModel,
      title: "map.titles.parking"
    });
    var self = this;
    appModel.locations.on('reset', function () {
      self.handleParkingspaceLocationsReset(appView, appModel)
    });
    appView.on('toggleMarkerVisibility', this.handleParkingspaceMarkerVisibility);
    appView.render();
    appView.updateLocations();
  },

  departments: function () {
    var appView = new AppView({
      el: $('#page-map'),
      model: new AppModel({
        types: ["organization"]
      }),
      title: 'map.titles.departments'
    });
    appView.render();
    appView.updateLocations();
  },

  /**
   * Handle visibility of parkingspace markers
   *
   * @param locations collecion of locations
   * @param visible true = set markers visible, false = hide markers
   */
  handleParkingspaceMarkerVisibility: function (locations, visible) {
    locations.each(function (item) {
      if (item.get('type') == 'entrance') {
        if (item.get('handicapAdapted') === true) {
          item.set('visible', visible);
        }
        else {
          item.set('visible', false);
        }
      }
    });
  },

  /**
   * Handler for reset event on locations
   *
   * @param appView the app view
   * @param appModel the app model
   */
  handleParkingspaceLocationsReset: function (appView, appModel) {
    appModel.set('zoomSensitive', true);
    appModel.locations.byType(["parking", "handicap_parking"]).each(function (item) {
      item.on('clicked', function () {
        appModel.set('zoomSensitive', false);
        appView.trigger('toggleMarkerVisibility', appModel.locations, true);
      });
    });
  }
});
<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/DeveloperError',
        '../Core/Event',
        './createPropertyDescriptor',
        './PropertyBag'
    ], function(
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Event,
        createPropertyDescriptor,
        PropertyBag) {
    'use strict';

    /**
     * @alias ParticleSystemGraphics
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     */
    function ParticleSystemGraphics(options) {
        this._show = undefined;
        this._showSubscription = undefined;
        this._image = undefined;
        this._imageSubscription = undefined;
        this._startScale = undefined;
        this._startScaleSubscription = undefined;
        this._endScale = undefined;
        this._endScaleSubscription = undefined;
        this._startColor = undefined;
        this._startColorSubscription = undefined;
        this._endColor = undefined;
        this._endColorSubscription = undefined;
        this._rate = undefined;
        this._rateSubscription = undefined;
        this._minimumWidth = undefined;
        this._minimumWidthSubscription = undefined;
        this._maximumWidth = undefined;
        this._maximumWidthSubscription = undefined;
        this._minimumHeight = undefined;
        this._minimumHeightSubscription = undefined;
        this._maximumHeight = undefined;
        this._maximumHeightSubscription = undefined;
        this._minimumSpeed = undefined;
        this._minimumSpeedSubscription = undefined;
        this._maximumSpeed = undefined;
        this._maximumSpeedSubscription = undefined;
        this._minimumLife = undefined;
        this._minimumLifeSubscription = undefined;
        this._maximumLife = undefined;
        this._maximumLifeSubscription = undefined;
        this._loop = undefined;
        this._loopSubscription = undefined;
        this._lifeTime = undefined;
        this._lifeTimeSubscription = undefined;
        this._emitterModelMatrix = undefined;
        this._emitterModelMatrixSubscription = undefined;
        this._bursts = undefined;
        this._burstsSubscription = undefined;
        this._forces = undefined;
        this.__forcesSubscription = undefined;

        this._definitionChanged = new Event();

        this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
    }

    defineProperties(ParticleSystemGraphics.prototype, {
        /**
         * Gets the event that is raised whenever a property or sub-property is changed or modified.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Event}
         * @readonly
         */
        definitionChanged : {
            get : function() {
                return this._definitionChanged;
            }
        },

        /**
         * Gets or sets the boolean Property specifying the visibility of the model.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default true
         */
        show : createPropertyDescriptor('show'),

        /**
         * The particle emitter for this particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default new CircleEmitter({radius: 0.5});
         */
        emitter : createPropertyDescriptor('emitter'),

        /**
         * Gets or sets the Property specifying the Image, URI, or Canvas to use for the particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         */
        image : createPropertyDescriptor('image'),

        /**
         * The scale of a particle at the beginning of its lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 1.0
         */
        startScale: createPropertyDescriptor('startScale'),

        /**
         * The scale of a particle at the end of it's lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 1.0
         */
        endScale: createPropertyDescriptor('endScale'),

        /**
         * The color of a particle at the beginning of it's lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Color.WHITE
         */
        startColor: createPropertyDescriptor('startColor'),

        /**
         * The color of a particle at the end of it's lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Color.WHITE
         */
        endColor: createPropertyDescriptor('endColor'),

        /**
         * The number of particles to emit per second.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        rate: createPropertyDescriptor('rate'),

        /**
         * The minimum width of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        minimumWidth: createPropertyDescriptor('minimumWidth'),

        /**
         * The maximum width of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        maximumWidth: createPropertyDescriptor('maximumWidth'),

        /**
         * The minimum height of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        minimumHeight: createPropertyDescriptor('minimumHeight'),

        /**
         * The maximum height of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        maximumHeight: createPropertyDescriptor('maximumHeight'),

        /**
         * The minimum speed of a particle in meters/second.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        minimumSpeed: createPropertyDescriptor('minimumSpeed'),

        /**
         * The maximum speed of a particle in meters/second.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        maximumSpeed: createPropertyDescriptor('maximumSpeed'),

        /**
         * Whether the particle system should loop when it's complete.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default true
         */
        loop: createPropertyDescriptor('loop'),

        /**
         * The lifetime of the particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Number.MAX_VALUE
         */
        lifeTime: createPropertyDescriptor('lifeTime'),

        /**
         * The model matrix of the emitter in the particle system.  This positions the emitter locally within the particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Matrix4.IDENTITY
         */
        emitterModelMatrix: createPropertyDescriptor("emitterModelMatrix"),

        /**
         * An array of bursts that specify the time to burst particles as well as the min and max number of particles to emit.  For example:
        *  bursts: [
        *      {time: 5.0, min: 300, max: 500},
        *      {time: 10.0, min: 50, max: 100},
        *      {time: 15.0, min: 200, max: 300}
        *  ],
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         */
        bursts: createPropertyDescriptor('bursts'),

        /**
         * The minimum life in seconds of a particle
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        minimumLife: createPropertyDescriptor("minimumLife"),

        /**
         * The maximum life in seconds of a particle
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        maximumLife: createPropertyDescriptor("maximumLife"),

        /**
         * An array of callbacks that apply a force to a given particle over time.
         * Callbacks can either be functions with the signature (particle, time delta) or
         * objects with an apply function with same signature.
         */
        forces: createPropertyDescriptor("forces")
    });

    /**
     * Duplicates this instance.
     *
     * @param {ParticleSystemGraphics} [result] The object onto which to store the result.
     * @returns {ParticleSystemGraphics} The modified result parameter or a new instance if one was not provided.
     */
    ParticleSystemGraphics.prototype.clone = function(result) {
        if (!defined(result)) {
            return new ParticleSystemGraphics(this);
        }

        result.show = this.show;
        result.emitter = this.emitter;
        result.image = this.image;
        result.startScale = this.startScale;
        result.endScale = this.endScale;
        result.startColor = this.startColor;
        result.endColor = this.endColor;
        result.rate = this.rate;
        result.minimumWidth = this.minimumWidth;
        result.maximumWidth = this.maximumWidth;
        result.minimumHeight = this.minimumHeight;
        result.maximumHeight = this.maximumHeight;
        result.minimumSpeed = this.minimumSpeed;
        result.maximumSpeed = this.maximumSpeed;
        result.minimumLife = this.minimumLife;
        result.maximumLife = this.maximumLife;
        result.loop = this.loop;
        result.lifeTime = this.lifeTime;
        result.emitterModelMatrix = this.emitterModelMatrix;
        result.bursts = this.bursts;
        result.forces = this.forces;

        return result;
    };

    /**
     * Assigns each unassigned property on this object to the value
     * of the same property on the provided source object.
     *
     * @param {ParticleSystemGraphics} source The object to be merged into this object.
     */
    ParticleSystemGraphics.prototype.merge = function(source) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(source)) {
            throw new DeveloperError('source is required.');
        }
        //>>includeEnd('debug');

        this.show = defaultValue(this.show, source.show);
        this.emitter = defaultValue(this.emitter, source.emitter);
        this.image = defaultValue(this.image, source.image);
        this.startScale = defaultValue(this.startScale, source.startScale);
        this.endScale = defaultValue(this.endScale, source.endScale);
        this.startColor = defaultValue(this.startColor, source.startColor);
        this.endColor = defaultValue(this.endColor, source.endColor);
        this.rate = defaultValue(this.rate, source.rate);
        this.minimumWidth = defaultValue(this.minimumWidth, source.minimumWidth);
        this.maximumWidth = defaultValue(this.maximumWidth, source.maximumWidth);
        this.minimumHeight = defaultValue(this.minimumHeight, source.minimumHeight);
        this.maximumHeight = defaultValue(this.maximumHeight, source.maximumHeight);
        this.minimumSpeed = defaultValue(this.minimumSpeed, source.minimumSpeed);
        this.maximumSpeed = defaultValue(this.maximumSpeed, source.maximumSpeed);
        this.minimumLife = defaultValue(this.minimumLife, source.minimumLife);
        this.maximumLife = defaultValue(this.maximumLife, source.maximumLife);
        this.loop = defaultValue(this.loop, source.loop);
        this.lifeTime = defaultValue(this.lifeTime, source.lifeTime);
        this.emitterModelMatrix = defaultValue(this.emitterModelMatrix, source.emitterModelMatrix);
        this.bursts = defaultValue(this.bursts, source.bursts);
        this.forces = defaultValue(this.forces, source.forces);
    };

    return ParticleSystemGraphics;
});
<commit_msg>Units<commit_after>/*global define*/
define([
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/DeveloperError',
        '../Core/Event',
        './createPropertyDescriptor',
        './PropertyBag'
    ], function(
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Event,
        createPropertyDescriptor,
        PropertyBag) {
    'use strict';

    /**
     * @alias ParticleSystemGraphics
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     */
    function ParticleSystemGraphics(options) {
        this._show = undefined;
        this._showSubscription = undefined;
        this._image = undefined;
        this._imageSubscription = undefined;
        this._startScale = undefined;
        this._startScaleSubscription = undefined;
        this._endScale = undefined;
        this._endScaleSubscription = undefined;
        this._startColor = undefined;
        this._startColorSubscription = undefined;
        this._endColor = undefined;
        this._endColorSubscription = undefined;
        this._rate = undefined;
        this._rateSubscription = undefined;
        this._minimumWidth = undefined;
        this._minimumWidthSubscription = undefined;
        this._maximumWidth = undefined;
        this._maximumWidthSubscription = undefined;
        this._minimumHeight = undefined;
        this._minimumHeightSubscription = undefined;
        this._maximumHeight = undefined;
        this._maximumHeightSubscription = undefined;
        this._minimumSpeed = undefined;
        this._minimumSpeedSubscription = undefined;
        this._maximumSpeed = undefined;
        this._maximumSpeedSubscription = undefined;
        this._minimumLife = undefined;
        this._minimumLifeSubscription = undefined;
        this._maximumLife = undefined;
        this._maximumLifeSubscription = undefined;
        this._loop = undefined;
        this._loopSubscription = undefined;
        this._lifeTime = undefined;
        this._lifeTimeSubscription = undefined;
        this._emitterModelMatrix = undefined;
        this._emitterModelMatrixSubscription = undefined;
        this._bursts = undefined;
        this._burstsSubscription = undefined;
        this._forces = undefined;
        this.__forcesSubscription = undefined;

        this._definitionChanged = new Event();

        this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
    }

    defineProperties(ParticleSystemGraphics.prototype, {
        /**
         * Gets the event that is raised whenever a property or sub-property is changed or modified.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Event}
         * @readonly
         */
        definitionChanged : {
            get : function() {
                return this._definitionChanged;
            }
        },

        /**
         * Gets or sets the boolean Property specifying the visibility of the model.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default true
         */
        show : createPropertyDescriptor('show'),

        /**
         * The particle emitter for this particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default new CircleEmitter({radius: 0.5});
         */
        emitter : createPropertyDescriptor('emitter'),

        /**
         * Gets or sets the Property specifying the Image, URI, or Canvas to use for the particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         */
        image : createPropertyDescriptor('image'),

        /**
         * The scale of a particle at the beginning of its lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 1.0
         */
        startScale: createPropertyDescriptor('startScale'),

        /**
         * The scale of a particle at the end of it's lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 1.0
         */
        endScale: createPropertyDescriptor('endScale'),

        /**
         * The color of a particle at the beginning of it's lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Color.WHITE
         */
        startColor: createPropertyDescriptor('startColor'),

        /**
         * The color of a particle at the end of it's lifetime.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Color.WHITE
         */
        endColor: createPropertyDescriptor('endColor'),

        /**
         * The number of particles to emit per second.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        rate: createPropertyDescriptor('rate'),

        /**
         * The minimum width of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        minimumWidth: createPropertyDescriptor('minimumWidth'),

        /**
         * The maximum width of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        maximumWidth: createPropertyDescriptor('maximumWidth'),

        /**
         * The minimum height of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        minimumHeight: createPropertyDescriptor('minimumHeight'),

        /**
         * The maximum height of a particle billboard in pixels.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 16.0
         */
        maximumHeight: createPropertyDescriptor('maximumHeight'),

        /**
         * The minimum speed of a particle in meters/second.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        minimumSpeed: createPropertyDescriptor('minimumSpeed'),

        /**
         * The maximum speed of a particle in meters/second.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        maximumSpeed: createPropertyDescriptor('maximumSpeed'),

        /**
         * Whether the particle system should loop when it's complete.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default true
         */
        loop: createPropertyDescriptor('loop'),

        /**
         * The lifetime of the particle system in seconds.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Number.MAX_VALUE
         */
        lifeTime: createPropertyDescriptor('lifeTime'),

        /**
         * The model matrix of the emitter in the particle system.  This positions the emitter locally within the particle system.
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default Matrix4.IDENTITY
         */
        emitterModelMatrix: createPropertyDescriptor("emitterModelMatrix"),

        /**
         * An array of bursts that specify the time to burst particles as well as the min and max number of particles to emit.  For example:
        *  bursts: [
        *      {time: 5.0, min: 300, max: 500},
        *      {time: 10.0, min: 50, max: 100},
        *      {time: 15.0, min: 200, max: 300}
        *  ],
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         */
        bursts: createPropertyDescriptor('bursts'),

        /**
         * The minimum life in seconds of a particle
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        minimumLife: createPropertyDescriptor("minimumLife"),

        /**
         * The maximum life in seconds of a particle
         * @memberof ParticleSystemGraphics.prototype
         * @type {Property}
         * @default 5.0
         */
        maximumLife: createPropertyDescriptor("maximumLife"),

        /**
         * An array of callbacks that apply a force to a given particle over time.
         * Callbacks can either be functions with the signature (particle, time delta) or
         * objects with an apply function with same signature.
         */
        forces: createPropertyDescriptor("forces")
    });

    /**
     * Duplicates this instance.
     *
     * @param {ParticleSystemGraphics} [result] The object onto which to store the result.
     * @returns {ParticleSystemGraphics} The modified result parameter or a new instance if one was not provided.
     */
    ParticleSystemGraphics.prototype.clone = function(result) {
        if (!defined(result)) {
            return new ParticleSystemGraphics(this);
        }

        result.show = this.show;
        result.emitter = this.emitter;
        result.image = this.image;
        result.startScale = this.startScale;
        result.endScale = this.endScale;
        result.startColor = this.startColor;
        result.endColor = this.endColor;
        result.rate = this.rate;
        result.minimumWidth = this.minimumWidth;
        result.maximumWidth = this.maximumWidth;
        result.minimumHeight = this.minimumHeight;
        result.maximumHeight = this.maximumHeight;
        result.minimumSpeed = this.minimumSpeed;
        result.maximumSpeed = this.maximumSpeed;
        result.minimumLife = this.minimumLife;
        result.maximumLife = this.maximumLife;
        result.loop = this.loop;
        result.lifeTime = this.lifeTime;
        result.emitterModelMatrix = this.emitterModelMatrix;
        result.bursts = this.bursts;
        result.forces = this.forces;

        return result;
    };

    /**
     * Assigns each unassigned property on this object to the value
     * of the same property on the provided source object.
     *
     * @param {ParticleSystemGraphics} source The object to be merged into this object.
     */
    ParticleSystemGraphics.prototype.merge = function(source) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(source)) {
            throw new DeveloperError('source is required.');
        }
        //>>includeEnd('debug');

        this.show = defaultValue(this.show, source.show);
        this.emitter = defaultValue(this.emitter, source.emitter);
        this.image = defaultValue(this.image, source.image);
        this.startScale = defaultValue(this.startScale, source.startScale);
        this.endScale = defaultValue(this.endScale, source.endScale);
        this.startColor = defaultValue(this.startColor, source.startColor);
        this.endColor = defaultValue(this.endColor, source.endColor);
        this.rate = defaultValue(this.rate, source.rate);
        this.minimumWidth = defaultValue(this.minimumWidth, source.minimumWidth);
        this.maximumWidth = defaultValue(this.maximumWidth, source.maximumWidth);
        this.minimumHeight = defaultValue(this.minimumHeight, source.minimumHeight);
        this.maximumHeight = defaultValue(this.maximumHeight, source.maximumHeight);
        this.minimumSpeed = defaultValue(this.minimumSpeed, source.minimumSpeed);
        this.maximumSpeed = defaultValue(this.maximumSpeed, source.maximumSpeed);
        this.minimumLife = defaultValue(this.minimumLife, source.minimumLife);
        this.maximumLife = defaultValue(this.maximumLife, source.maximumLife);
        this.loop = defaultValue(this.loop, source.loop);
        this.lifeTime = defaultValue(this.lifeTime, source.lifeTime);
        this.emitterModelMatrix = defaultValue(this.emitterModelMatrix, source.emitterModelMatrix);
        this.bursts = defaultValue(this.bursts, source.bursts);
        this.forces = defaultValue(this.forces, source.forces);
    };

    return ParticleSystemGraphics;
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
'use strict';

const Bundle = require('../Bundler/Bundle');
const Promise = require('promise');
const bser = require('bser');
const debug = require('debug')('ReactPackager:SocketClient');
const fs = require('fs');
const net = require('net');
const path  = require('path');
const tmpdir = require('os').tmpdir();

const LOG_PATH = path.join(tmpdir, 'react-packager.log');

class SocketClient {
  static create(sockPath) {
    return new SocketClient(sockPath).onReady();
  }

  constructor(sockPath) {
    debug('connecting to', sockPath);

    this._sock = net.connect(sockPath);
    this._ready = new Promise((resolve, reject) => {
      this._sock.on('connect', () => resolve(this));
      this._sock.on('error', (e) => {
        e.message = `Error connecting to server on ${sockPath} ` +
                    `with error: ${e.message}`;
        e.message += getServerLogs();

        reject(e);
      });
    });

    this._resolvers = Object.create(null);
    const bunser = new bser.BunserBuf();
    this._sock.on('data', (buf) => bunser.append(buf));
    bunser.on('value', (message) => this._handleMessage(message));

    this._sock.on('close', () => {
      if (!this._closing) {
        throw new Error('Server closed unexpectedly' + getServerLogs());
      }
    });
  }

  onReady() {
    return this._ready;
  }

  getDependencies(main) {
    return this._send({
      type: 'getDependencies',
      data: main,
    });
  }

  buildBundle(options) {
    return this._send({
      type: 'buildBundle',
      data: options,
    }).then(json => Bundle.fromJSON(json));
  }

  _send(message) {
    message.id = uid();
    this._sock.write(bser.dumpToBuffer(message));
    return new Promise((resolve, reject) => {
      this._resolvers[message.id] = {resolve, reject};
    });
  }

  _handleMessage(message) {
    if (!(message && message.id && message.type)) {
      throw new Error(
        'Malformed message from server ' + JSON.stringify(message)
      );
    }

    debug('got message with type', message.type);

    const resolver = this._resolvers[message.id];
    if (!resolver) {
      throw new Error(
        'Unrecognized message id (' + message.id + ') ' +
        'message already resolved or never existed.'
      );
    }

    delete this._resolvers[message.id];

    if (message.type === 'error') {
      resolver.reject(new Error(
        message.data + '\n' + 'See logs ' + LOG_PATH
      ));
    } else {
      resolver.resolve(message.data);
    }
  }

  close() {
    debug('closing connection');
    this._closing = true;
    this._sock.end();
  }
}

module.exports = SocketClient;

function uid(len) {
  len = len || 7;
  return Math.random().toString(35).substr(2, len);
}

function getServerLogs() {
  if (fs.existsSync(LOG_PATH)) {
    return '\nServer logs:\n' + fs.readFileSync(LOG_PATH, 'utf8');
  }

  return '';
}
<commit_msg>Add logging information when client's socket gets closed unexpetedly<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
'use strict';

const Bundle = require('../Bundler/Bundle');
const Promise = require('promise');
const bser = require('bser');
const debug = require('debug')('ReactPackager:SocketClient');
const fs = require('fs');
const net = require('net');
const path  = require('path');
const tmpdir = require('os').tmpdir();

const LOG_PATH = path.join(tmpdir, 'react-packager.log');

class SocketClient {
  static create(sockPath) {
    return new SocketClient(sockPath).onReady();
  }

  constructor(sockPath) {
    debug('connecting to', sockPath);

    this._sock = net.connect(sockPath);
    this._ready = new Promise((resolve, reject) => {
      this._sock.on('connect', () => resolve(this));
      this._sock.on('error', (e) => {
        e.message = `Error connecting to server on ${sockPath} ` +
                    `with error: ${e.message}`;
        e.message += getServerLogs();

        reject(e);
      });
    });

    this._resolvers = Object.create(null);
    const bunser = new bser.BunserBuf();
    this._sock.on('data', (buf) => bunser.append(buf));
    bunser.on('value', (message) => this._handleMessage(message));

    this._sock.on('close', () => {
      if (!this._closing) {
        const sockPathExists = fs.existsSync(sockPath);
        throw new Error(
          'Server closed unexpectedly.\n' +
          'Socket path: `' + sockPath + '` ' +
          (sockPathExists ? ' exists.' : 'doesn\'t exist') + '\n' +
          getServerLogs()
        );
      }
    });
  }

  onReady() {
    return this._ready;
  }

  getDependencies(main) {
    return this._send({
      type: 'getDependencies',
      data: main,
    });
  }

  buildBundle(options) {
    return this._send({
      type: 'buildBundle',
      data: options,
    }).then(json => Bundle.fromJSON(json));
  }

  _send(message) {
    message.id = uid();
    this._sock.write(bser.dumpToBuffer(message));
    return new Promise((resolve, reject) => {
      this._resolvers[message.id] = {resolve, reject};
    });
  }

  _handleMessage(message) {
    if (!(message && message.id && message.type)) {
      throw new Error(
        'Malformed message from server ' + JSON.stringify(message)
      );
    }

    debug('got message with type', message.type);

    const resolver = this._resolvers[message.id];
    if (!resolver) {
      throw new Error(
        'Unrecognized message id (' + message.id + ') ' +
        'message already resolved or never existed.'
      );
    }

    delete this._resolvers[message.id];

    if (message.type === 'error') {
      resolver.reject(new Error(
        message.data + '\n' + 'See logs ' + LOG_PATH
      ));
    } else {
      resolver.resolve(message.data);
    }
  }

  close() {
    debug('closing connection');
    this._closing = true;
    this._sock.end();
  }
}

module.exports = SocketClient;

function uid(len) {
  len = len || 7;
  return Math.random().toString(35).substr(2, len);
}

function getServerLogs() {
  if (fs.existsSync(LOG_PATH)) {
    return '\nServer logs:\n' + fs.readFileSync(LOG_PATH, 'utf8');
  }

  return '';
}
<|endoftext|>


<commit_before>'use strict';

var Plotly = window.Plotly;
var ToolPanel = window.ToolPanel;
var divs = [];

function createRemoveButton () {
    var removeButton = document.createElement('button');
    removeButton.innerHTML = 'remove toolpanel';
    removeButton.id = 'removeButton';
    document.body.appendChild(removeButton);

    removeButton.onclick = function () {
        divs[0].toolPanel.remove();
    };
}

function createPlot (divId) {
    var containerDiv = document.getElementById('main');
    var graphDiv = document.createElement('div');
    var toolDiv = document.createElement('div');
    containerDiv.style.width = '100%';
    containerDiv.style.height = '100%';
    containerDiv.style.clear = 'both';

    graphDiv.id = divId;
    graphDiv.style.width = '80%';
    graphDiv.style.display = 'inline-block';
    graphDiv.style.margin = '0px';
    graphDiv.style.position = 'relative';
    graphDiv.style.verticalAlign = 'top';

    toolDiv.style.verticalAlign = 'top';
    toolDiv.style.width = '130px';
    toolDiv.style.display = 'inline-block';

    containerDiv.appendChild(toolDiv);
    containerDiv.appendChild(graphDiv);

    var trace1 = {
        x: [1, 2, 3, 4],
        y: [10, 15, 13, 17],
        type: 'scatter'
    };

    var trace2 = {
        x: [1, 2, 3, 4],
        y: [16, 5, 11, 9],
        type: 'scatter'
    };

    var data = [trace1, trace2];
    var toolPanel;

    Plotly.newPlot(divId, data);

    graphDiv.toolPanel = toolPanel = new ToolPanel(Plotly, graphDiv, {
        standalone: true,
        popoverContainer: containerDiv
    });

    window.toolPanel = graphDiv.toolPanel;

    graphDiv.toolPanel.makeMenu({
        toolMenuContainer: toolDiv
    });

    toolPanel.createMenuMultiButton([
        {
            labelContent: 'Undo',
            iconClass: 'icon-rotate-left',
            handler: toolPanel.undo
        },
        {
            labelContent: 'Redo',
            iconClass: 'icon-rotate-right',
            handler: toolPanel.redo
        }
    ]);

    toolPanel.createMenuSpacer();

    toolPanel.createMenuButtons(toolPanel.getPanelButtonSpecs());

    divs.push(graphDiv, toolDiv);

}

['one'].forEach(function (index) {
    createPlot(index);
});

createRemoveButton();
<commit_msg>horizontal - vertical toolpanel function change<commit_after>'use strict';

var Plotly = window.Plotly;
var ToolPanel = window.ToolPanel;
var divs = [];

function createRemoveButton () {
    var removeButton = document.createElement('button');
    removeButton.innerHTML = 'remove toolpanel';
    removeButton.id = 'removeButton';
    document.body.appendChild(removeButton);

    removeButton.onclick = function () {
        divs[0].toolPanel.remove();
    };
}

function createPlot (divId) {
    var containerDiv = document.getElementById('main');
    var graphDiv = document.createElement('div');
    var toolDiv = document.createElement('div');
    containerDiv.style.width = '100%';
    containerDiv.style.height = '100%';
    containerDiv.style.clear = 'both';

    graphDiv.id = divId;
    graphDiv.style.width = '80%';
    graphDiv.style.display = 'inline-block';
    graphDiv.style.margin = '0px';
    graphDiv.style.position = 'relative';
    graphDiv.style.verticalAlign = 'top';

    toolDiv.className = 'toolDiv';

    containerDiv.appendChild(toolDiv);
    containerDiv.appendChild(graphDiv);

    var trace1 = {
        x: [1, 2, 3, 4],
        y: [10, 15, 13, 17],
        type: 'scatter'
    };

    var trace2 = {
        x: [1, 2, 3, 4],
        y: [16, 5, 11, 9],
        type: 'scatter'
    };

    var data = [trace1, trace2];
    var toolPanel;

    Plotly.newPlot(divId, data);

    graphDiv.toolPanel = toolPanel = new ToolPanel(Plotly, graphDiv, {
        standalone: true,
        popoverContainer: containerDiv
    });

    window.toolPanel = graphDiv.toolPanel;

    graphDiv.toolPanel.makeMenu({
        toolMenuContainer: toolDiv
    });

    toolPanel.createMenuMultiButton([
        {
            labelContent: 'Undo',
            iconClass: 'icon-rotate-left',
            handler: toolPanel.undo
        },
        {
            labelContent: 'Redo',
            iconClass: 'icon-rotate-right',
            handler: toolPanel.redo
        }
    ]);

    toolPanel.createMenuSpacer();

    toolPanel.createMenuButtons(toolPanel.getPanelButtonSpecs());

    divs.push(graphDiv, toolDiv);

}

['one'].forEach(function (index) {
    createPlot(index);
});

createRemoveButton();
<|endoftext|>


<commit_before>import { useQuery, useTracking } from '@strapi/helper-plugin';
import { AddIcon, DeleteIcon, EditIcon, Duplicate } from '@strapi/icons';
import {
  Button,
  ContentLayout,
  HeaderLayout,
  Table,
  TableLabel,
  Tbody,
  TFooter,
  Th,
  Thead,
  Tr,
  VisuallyHidden,
} from '@strapi/parts';
import matchSorter from 'match-sorter';
import React, { useCallback, useState } from 'react';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router';
import { EmptyRole, RoleRow } from '../../../components/Roles';
import PageTitle from '../../../components/SettingsPageTitle';
import UpgradePlanModal from '../../../components/UpgradePlanModal';
import { useRolesList } from '../../../hooks';

const useResults = () => {
  const { roles, isLoading } = useRolesList();

  const query = useQuery();
  const _q = decodeURIComponent(query.get('_q') || '');
  const results = matchSorter(roles, _q, { keys: ['name', 'description'] });

  return { isLoading, results };
};

const useFuncs = () => {
  const { formatMessage } = useIntl();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const { trackUsage } = useTracking();
  const { push } = useHistory();

  const handleGoTo = useCallback(
    id => {
      push(`/settings/roles/${id}`);
    },
    [push]
  );

  const handleToggle = useCallback(() => {
    setIsModalOpen(prev => !prev);
  }, []);

  const handleToggleModalForCreatingRole = useCallback(() => {
    trackUsage('didShowRBACUpgradeModal');
    setIsModalOpen(true);
  }, [trackUsage]);

  const getIcons = useCallback(
    role => [
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.duplicate', defaultMessage: 'Duplicate' }),
        icon: <Duplicate />,
      },
      {
        onClick: () => handleGoTo(role.id),
        label: formatMessage({ id: 'app.utils.edit', defaultMessage: 'Edit' }),
        icon: <EditIcon />,
      },
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.delete', defaultMessage: 'Delete' }),
        icon: <DeleteIcon />,
      },
    ],
    [formatMessage, handleToggle, handleGoTo]
  );

  return {
    isModalOpen,
    handleToggleModalForCreatingRole,
    handleToggle,
    getIcons,
  };
};

const RoleListPage = () => {
  const { formatMessage } = useIntl();

  const { results, isLoading } = useResults();
  const { isModalOpen, handleToggle, handleToggleModalForCreatingRole, getIcons } = useFuncs();

  const rowCount = results.length + 1;
  const colCount = results.length ? Object.keys(results[0]).length : 0;

  // ! TODO - Add the search input

  return (
    <>
      <PageTitle name="Roles" />
      <HeaderLayout
        primaryAction={(
          <Button onClick={handleToggleModalForCreatingRole} startIcon={<AddIcon />}>
            {formatMessage({
              id: 'Settings.roles.list.button.add',
              defaultMessage: 'Add new role',
            })}
          </Button>
        )}
        title={formatMessage({
          id: 'Settings.roles.title',
          defaultMessage: 'roles',
        })}
        subtitle={formatMessage({
          id: 'Settings.roles.list.description',
          defaultMessage: 'List of roles',
        })}
      />
      <ContentLayout>
        <Table
          colCount={colCount}
          rowCount={rowCount}
          footer={(
            <TFooter onClick={handleToggleModalForCreatingRole} icon={<AddIcon />}>
              {formatMessage({
                id: 'Settings.roles.list.button.add',
                defaultMessage: 'Add new role',
              })}
            </TFooter>
          )}
        >

                <TableLabel>
                  {formatMessage({
                    id: 'Settings.roles.list.header.name',
                    defaultMessage: 'Name',
                  })}
                </TableLabel>

                <TableLabel>
                  {formatMessage({
                    id: 'Settings.roles.list.header.description',
                    defaultMessage: 'Description',
                  })}
                </TableLabel>

                <TableLabel>
                  {formatMessage({
                    id: 'Settings.roles.list.header.users',
                    defaultMessage: 'Users',
                  })}
                </TableLabel>

                <VisuallyHidden>
                  {formatMessage({
                    id: 'Settings.roles.list.header.actions',
                    defaultMessage: 'Actions',
                  })}
                </VisuallyHidden>

            {results?.map(role => (
              <RoleRow
                key={role.id}
                id={role.id}
                name={role.name}
                description={role.description}
                usersCount={role.usersCount}
                icons={getIcons(role)}
              />
            ))}

        {!rowCount && !isLoading && <EmptyRole />}
      </ContentLayout>
      <UpgradePlanModal isOpen={isModalOpen} onToggle={handleToggle} />
    </>
  );
};

export default RoleListPage;
<commit_msg>Update packages/core/admin/admin/src/pages/Roles/ListPage/index.js<commit_after>import { useQuery, useTracking } from '@strapi/helper-plugin';
import { AddIcon, DeleteIcon, EditIcon, Duplicate } from '@strapi/icons';
import {
  Button,
  ContentLayout,
  HeaderLayout,
  Table,
  TableLabel,
  Tbody,
  TFooter,
  Th,
  Thead,
  Tr,
  VisuallyHidden,
} from '@strapi/parts';
import matchSorter from 'match-sorter';
import React, { useCallback, useState } from 'react';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router';
import { EmptyRole, RoleRow } from '../../../components/Roles';
import PageTitle from '../../../components/SettingsPageTitle';
import UpgradePlanModal from '../../../components/UpgradePlanModal';
import { useRolesList } from '../../../hooks';

const useResults = () => {
  const { roles, isLoading } = useRolesList();

  const query = useQuery();
  const _q = decodeURIComponent(query.get('_q') || '');
  const results = matchSorter(roles, _q, { keys: ['name', 'description'] });

  return { isLoading, results };
};

const useFuncs = () => {
  const { formatMessage } = useIntl();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const { trackUsage } = useTracking();
  const { push } = useHistory();

  const handleGoTo = useCallback(
    id => {
      push(`/settings/roles/${id}`);
    },
    [push]
  );

  const handleToggle = useCallback(() => {
    setIsModalOpen(prev => !prev);
  }, []);

  const handleToggleModalForCreatingRole = useCallback(() => {
    trackUsage('didShowRBACUpgradeModal');
    setIsModalOpen(true);
  }, [trackUsage]);

  const getIcons = useCallback(
    role => [
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.duplicate', defaultMessage: 'Duplicate' }),
        icon: <Duplicate />,
      },
      {
        onClick: () => handleGoTo(role.id),
        label: formatMessage({ id: 'app.utils.edit', defaultMessage: 'Edit' }),
        icon: <EditIcon />,
      },
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.delete', defaultMessage: 'Delete' }),
        icon: <DeleteIcon />,
      },
    ],
    [formatMessage, handleToggle, handleGoTo]
  );

  return {
    isModalOpen,
    handleToggleModalForCreatingRole,
    handleToggle,
    getIcons,
  };
};

const RoleListPage = () => {
  const { formatMessage } = useIntl();

  const { results, isLoading } = useResults();
  const { isModalOpen, handleToggle, handleToggleModalForCreatingRole, getIcons } = useFuncs();

  const rowCount = results.length + 1;
  const colCount = 5

  // ! TODO - Add the search input

  return (
    <>
      <PageTitle name="Roles" />
      <HeaderLayout
        primaryAction={(
          <Button onClick={handleToggleModalForCreatingRole} startIcon={<AddIcon />}>
            {formatMessage({
              id: 'Settings.roles.list.button.add',
              defaultMessage: 'Add new role',
            })}
          </Button>
        )}
        title={formatMessage({
          id: 'Settings.roles.title',
          defaultMessage: 'roles',
        })}
        subtitle={formatMessage({
          id: 'Settings.roles.list.description',
          defaultMessage: 'List of roles',
        })}
      />
      <ContentLayout>
        <Table
          colCount={colCount}
          rowCount={rowCount}
          footer={(
            <TFooter onClick={handleToggleModalForCreatingRole} icon={<AddIcon />}>
              {formatMessage({
                id: 'Settings.roles.list.button.add',
                defaultMessage: 'Add new role',
              })}
            </TFooter>
          )}
        >

                <TableLabel>
                  {formatMessage({
                    id: 'Settings.roles.list.header.name',
                    defaultMessage: 'Name',
                  })}
                </TableLabel>

                <TableLabel>
                  {formatMessage({
                    id: 'Settings.roles.list.header.description',
                    defaultMessage: 'Description',
                  })}
                </TableLabel>

                <TableLabel>
                  {formatMessage({
                    id: 'Settings.roles.list.header.users',
                    defaultMessage: 'Users',
                  })}
                </TableLabel>

                <VisuallyHidden>
                  {formatMessage({
                    id: 'Settings.roles.list.header.actions',
                    defaultMessage: 'Actions',
                  })}
                </VisuallyHidden>

            {results?.map(role => (
              <RoleRow
                key={role.id}
                id={role.id}
                name={role.name}
                description={role.description}
                usersCount={role.usersCount}
                icons={getIcons(role)}
              />
            ))}

        {!rowCount && !isLoading && <EmptyRole />}
      </ContentLayout>
      <UpgradePlanModal isOpen={isModalOpen} onToggle={handleToggle} />
    </>
  );
};

export default RoleListPage;
<|endoftext|>


<commit_before>var sugar = require('sugar');
var irc = require('irc');
var webSocket = require('ws');

var channel = '#atptest';

var titles = [];
var connections = [];

function sendToAll(packet) {
    connections.forEach(function (connection) {
        connection.send(JSON.stringify(packet));
    });
}

var client = new irc.Client('irc.freenode.net', 'accidentalbot', {
    channels: [channel]
});

client.addListener('join', function (channel, nick, message) {
    console.log('Joined channel ' + channel);
});

client.addListener('message', function (from, to, message) {
    if (message.startsWith('!s')) {
        var title = message.substring(3);

        // Make sure this isn't a duplicate.
        if (titles.findAll({titleLower: title.toLowerCase()}).length === 0) {
            var title = {
                id: titles.length,
                author: from,
                title: title,
                titleLower: title.toLowerCase(),
                votes: 0,
                time: new Date()
            };
            titles.push(title);

            sendToAll({operation: 'NEW', title: title});
        } else {
            //client.say(channel, 'Sorry, ' + from + ', your title is a duplicate. Please try another!');
            client.say(from, 'Sorry, your title is a duplicate. Please try another!');
        }
    }
});

client.addListener('error', function (message) {
    console.log('error: ', message)
});

/***************************************************
 * WEB SOCKETS                                     *
 ***************************************************/

var port = Number(process.env.PORT || 5001);
var socketServer = new webSocket.Server({port: port});

socketServer.on('connection', function(socket) {
    connections.push(socket);
    socket.send(JSON.stringify({operation: 'REFRESH', titles: titles}));

    socket.on('close', function () {
        connections.splice(connections.indexOf(socket), 1);
    });

    socket.on('message', function (data, flags) {
        var packet = JSON.parse(data);
        if (packet.operation === 'VOTE') {
            var matches = titles.findAll({id: packet['id']});
            if (matches.length > 0) {
                matches[0]['votes'] = new Number(matches[0]['votes']) + 1;
                sendToAll({operation: 'VOTE', votes: matches[0]['votes'], id: matches[0]['id']});
            } else {
                console.log('no matches for id: ' + packet['id']);
            }
        } else if (packet.operation === 'UPDATE') {
            socket.send(JSON.stringify(titles));
        } else {
            console.log("Don't know what to do with " + packet['operation']);
        }
    });
});
<commit_msg>lots of improvements.<commit_after>var sugar = require('sugar');
var irc = require('irc');
var webSocket = require('ws');
var fs = require('fs');

var channel = '#atptest';

var titles = [];
var connections = [];
var links = [];

function sendToAll(packet) {
    connections.forEach(function (connection) {
        connection.send(JSON.stringify(packet));
    });
}

function saveBackup() {
    // TODO: Figure out what to do here.
}

function handleNewSuggestion(from, message) {
    if (message.startsWith('!suggest')) {
        title = message.substring(9);
    } else if (message.startsWith('!s')) {
        title = message.substring(3);
    }

    if (title.length > 75) {
        client.say(from, 'That title is too long; please try again.');
        title = '';
    }
    if (title.length > 0) {
        // Make sure this isn't a duplicate.
        if (titles.findAll({titleLower: title.toLowerCase()}).length === 0) {
            var title = {
                id: titles.length,
                author: from,
                title: title,
                titleLower: title.toLowerCase(),
                votes: 0,
                time: new Date()
            };
            titles.push(title);

            sendToAll({operation: 'NEW', title: title});
        } else {
            //client.say(channel, 'Sorry, ' + from + ', your title is a duplicate. Please try another!');
            client.say(from, 'Sorry, your title is a duplicate. Please try another!');
        }
    }
}

function handleSendVotes(from, message) {
    var titlesByVote = titles.sortBy(function (t) {
        return t.votes;
    }, true).to(3);
    console.log(JSON.stringify(titlesByVote));

    client.say(from, 'Three most popular titles:');
    for (var i = 0; i < titlesByVote.length; ++i) {
        console.log(JSON.stringify(titlesByVote[i]));
        var votes = titlesByVote[i]['votes'];
        client.say(from, titlesByVote[i]['votes'] + ' vote' + (votes != 1 ? 's' : '') +  ': " ' + titlesByVote[i].title + '"');
    }
}

function handleNewLink(from, message) {
    message = message.substring(6);
    if (message.startsWith('http')) {
        var link = {
            id: links.length,
            author: from,
            link: message,
            time: new Date()
        };
        links.push(link);

        sendToAll({operation: 'NEWLINK', link: link});
    } else {
        client.say(from, "That doesn't look like a link to me.");
    }
}

function handleHelp(from, message) {
    client.say(from, 'Options:');
    client.say('!s {title} - suggest a title.');
    client.say('!votes - get the three most highly voted titles.')
    client.say('!link {URL} - suggest a link.');
    client.say('!help - see this message.');
}

var client = new irc.Client('irc.freenode.net', 'accidentalbot', {
    channels: [channel]
});

client.addListener('join', function (channel, nick, message) {
    console.log('Joined channel ' + channel);
    setInterval(saveBackup, 300000);
});

client.addListener('message', function (from, to, message) {
    var title = '';

    if (message.startsWith('!s')) {
        handleNewSuggestion(from, message);
    } else if (message.startsWith("!votes")) {
        handleSendVotes(from, message);
    } else if (message.startsWith('!link')) {
        handleNewLink(from, message);
    }
});

client.addListener('error', function (message) {
    console.log('error: ', message)
});

/***************************************************
 * WEB SOCKETS                                     *
 ***************************************************/

var port = Number(process.env.PORT || 5001);
var socketServer = new webSocket.Server({port: port});

socketServer.on('connection', function(socket) {
    connections.push(socket);
    socket.send(JSON.stringify({operation: 'REFRESH', titles: titles, links: links}));

    socket.on('close', function () {
        connections.splice(connections.indexOf(socket), 1);
    });

    socket.on('message', function (data, flags) {
        var packet = JSON.parse(data);
        if (packet.operation === 'VOTE') {
            var matches = titles.findAll({id: packet['id']});
            if (matches.length > 0) {
                matches[0]['votes'] = new Number(matches[0]['votes']) + 1;
                sendToAll({operation: 'VOTE', votes: matches[0]['votes'], id: matches[0]['id']});
            } else {
                console.log('no matches for id: ' + packet['id']);
            }
        } else if (packet.operation === 'PING') {
            socket.send(JSON.stringify({operation: 'PONG'}));
        } else {
            console.log("Don't know what to do with " + packet['operation']);
        }
    });
});
<|endoftext|>


<commit_before>Template.registerHelper( 'arrayHasObject', ( array ) => {
  return array ? array.length > 0 : false;
});

Template.SpotlightShow.onCreated( function() {

	this.ready = new ReactiveVar(false);
    this.mySpotlight = new ReactiveDict();
    var self = this;
    self.autorun(function () {

    var subscription = Telescope.subsManager.subscribe('resourceFiles', FlowRouter.getParam("_id")); //self.subscribe( 'resourceFiles', FlowRouter.getParam("_id"));
    if (subscription.ready()) {

        var spotlight = {
          attachment: new Array(),
          photo: new Array(),
          video: new Array(),
        }

        Files.find({resourceID: FlowRouter.getParam("_id")}).forEach(function(doc){
          spotlight[doc.type].push(doc);
        });

        self.mySpotlight.set("attachment", spotlight["attachment"]);
        self.mySpotlight.set("video", spotlight["video"]);
        self.mySpotlight.set("photo", spotlight["photo"]);
        //   self.mySpotlight.set(spotlight);
          self.ready.set(true);
    }
  });
});

Template.SpotlightShow.helpers({
	ready: function () {
	  return Template.instance().ready.get();
	},
	spotlight: function(type){
    //console.log(Template.instance().mySpotlight.get("video"));
		return Template.instance().mySpotlight.get(type);
	},
	editMode: function(){
		return false;
	}
});<commit_msg>sort file<commit_after>Template.registerHelper( 'arrayHasObject', ( array ) => {
  return array ? array.length > 0 : false;
});

Template.SpotlightShow.onCreated( function() {

	this.ready = new ReactiveVar(false);
    this.mySpotlight = new ReactiveDict();
    var self = this;
    self.autorun(function () {

    var subscription = Telescope.subsManager.subscribe('resourceFiles', FlowRouter.getParam("_id")); //self.subscribe( 'resourceFiles', FlowRouter.getParam("_id"));
    if (subscription.ready()) {

        var spotlight = {
          attachment: new Array(),
          photo: new Array(),
          video: new Array(),
        }

        Files.find({resourceID: FlowRouter.getParam("_id")}, { sort: { "order": 1, "added": 1 }).forEach(function(doc){
          spotlight[doc.type].push(doc);
        });

        self.mySpotlight.set("attachment", spotlight["attachment"]);
        self.mySpotlight.set("video", spotlight["video"]);
        self.mySpotlight.set("photo", spotlight["photo"]);
        //   self.mySpotlight.set(spotlight);
          self.ready.set(true);
    }
  });
});

Template.SpotlightShow.helpers({
	ready: function () {
	  return Template.instance().ready.get();
	},
	spotlight: function(type){
    //console.log(Template.instance().mySpotlight.get("video"));
		return Template.instance().mySpotlight.get(type);
	},
	editMode: function(){
		return false;
	}
});<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const expect = require('chai').expect;
const cp = require('child_process');
const fs = require('fs-extra');
const fixturify = require('fixturify');
const gitFixtures = require('git-fixtures');
const run = require('../../src/run');

const gitInit = gitFixtures.gitInit;

function buildTmp(
  fixturesPath,
  tmpPath
) {
  gitInit(tmpPath);

  fs.copySync(fixturesPath, tmpPath);

  run('git add -A', {
    cwd: tmpPath
  });

  run('git commit -m "add files"', {
    cwd: tmpPath
  });

  run('git checkout -b foo', {
    cwd: tmpPath
  });
}

function fixtureCompare(
  tmpPath,
  mergeFixtures
) {
  let actual = fixturify.readSync(tmpPath);
  let expected = fixturify.readSync(mergeFixtures);

  delete actual['.git'];

  expect(actual).to.deep.equal(expected);
}

describe('Acceptance - ember-cli-build', function() {
  this.timeout(30000);

  let cwd;

  before(function() {
    cwd = process.cwd();
  });

  function merge(
    fixturesPath,
    tmpPath,
    messages
  ) {
    fs.emptyDirSync(tmpPath);

    buildTmp(
      fixturesPath,
      tmpPath
    );

    let binFile = path.join(cwd, 'bin/ember-cli-update');

    return new Promise(resolve => {
      let ps = cp.spawn('node', [
        binFile,
        '--to',
        '2.14.1'
      ], {
        cwd: tmpPath,
        env: process.env
      });

      let i = 0;
      ps.stdout.on('data', data => {
        let str = data.toString();
        if (str.includes('Normal merge conflict')) {
          ps.stdin.write(':%diffg 3\n');
          ps.stdin.write(':wqa\n');
          i++;
        } else if (str.includes('Deleted merge conflict')) {
          ps.stdin.write('d\n');
          i++;
        }
        if (i === messages) {
          // this is only needed because 'inherit' isn't working in node 4 windows
          ps.stdin.end();
        }
      });

      let stderr = '';

      ps.stderr.on('data', data => {
        stderr += data.toString();
      });

      ps.stderr.pipe(process.stdout);

      ps.on('exit', () => {
        let status = run('git status', {
          cwd: tmpPath
        });

        expect(stderr).to.not.contain('Error:');
        expect(stderr).to.not.contain('fatal:');
        expect(stderr).to.not.contain('Command failed');

        let result = run('git log -1', {
          cwd: tmpPath
        });

        // verify it is not committed
        expect(result).to.contain('Author: Your Name <you@example.com>');
        expect(result).to.contain('add files');

        result = run('git branch', {
          cwd: tmpPath
        });

        // verify branch was deleted
        expect(result.trim()).to.match(/\* foo\r?\n {2}master/);

        resolve({
          status,
          stderr
        });
      });
    });
  }

  it('updates app', function() {
    return merge(
      'test/fixtures/local/my-app',
      'tmp/my-app',
      2
    ).then(result => {
      let status = result.status;

      fixtureCompare(
        'tmp/my-app',
        'test/fixtures/merge/my-app'
      );

      // changed locally, no change upstream
      expect(status).to.not.contain(' .ember-cli');

      // exists locally, also added upstream with changes
      expect(status).to.contain('modified:   .eslintrc.js');

      // changed locally, removed upstream
      expect(status).to.contain('deleted:    bower.json');

      // changed locally, also changed upstream
      expect(status).to.contain('modified:   README.md');
    });
  });

  it('updates addon', function() {
    return merge(
      'test/fixtures/local/my-addon',
      'tmp/my-addon',
      2
    ).then(result => {
      let status = result.status;

      fixtureCompare(
        'tmp/my-addon',
        'test/fixtures/merge/my-addon'
      );

      // changed locally, no change upstream
      expect(status).to.not.contain(' .ember-cli');

      // exists locally, also added upstream with changes
      expect(status).to.contain('modified:   .eslintrc.js');

      // changed locally, removed upstream
      expect(status).to.contain('deleted:    bower.json');

      // changed locally, also changed upstream
      expect(status).to.contain('modified:   README.md');
    });
  });
});
<commit_msg>forgot git init spot<commit_after>'use strict';

const path = require('path');
const expect = require('chai').expect;
const cp = require('child_process');
const fs = require('fs-extra');
const fixturify = require('fixturify');
const gitFixtures = require('git-fixtures');
const run = require('../../src/run');

const gitInit = gitFixtures.gitInit;

function buildTmp(
  fixturesPath,
  tmpPath
) {
  gitInit({
    cwd: tmpPath
  });

  fs.copySync(fixturesPath, tmpPath);

  run('git add -A', {
    cwd: tmpPath
  });

  run('git commit -m "add files"', {
    cwd: tmpPath
  });

  run('git checkout -b foo', {
    cwd: tmpPath
  });
}

function fixtureCompare(
  tmpPath,
  mergeFixtures
) {
  let actual = fixturify.readSync(tmpPath);
  let expected = fixturify.readSync(mergeFixtures);

  delete actual['.git'];

  expect(actual).to.deep.equal(expected);
}

describe('Acceptance - ember-cli-build', function() {
  this.timeout(30000);

  let cwd;

  before(function() {
    cwd = process.cwd();
  });

  function merge(
    fixturesPath,
    tmpPath,
    messages
  ) {
    fs.emptyDirSync(tmpPath);

    buildTmp(
      fixturesPath,
      tmpPath
    );

    let binFile = path.join(cwd, 'bin/ember-cli-update');

    return new Promise(resolve => {
      let ps = cp.spawn('node', [
        binFile,
        '--to',
        '2.14.1'
      ], {
        cwd: tmpPath,
        env: process.env
      });

      let i = 0;
      ps.stdout.on('data', data => {
        let str = data.toString();
        if (str.includes('Normal merge conflict')) {
          ps.stdin.write(':%diffg 3\n');
          ps.stdin.write(':wqa\n');
          i++;
        } else if (str.includes('Deleted merge conflict')) {
          ps.stdin.write('d\n');
          i++;
        }
        if (i === messages) {
          // this is only needed because 'inherit' isn't working in node 4 windows
          ps.stdin.end();
        }
      });

      let stderr = '';

      ps.stderr.on('data', data => {
        stderr += data.toString();
      });

      ps.stderr.pipe(process.stdout);

      ps.on('exit', () => {
        let status = run('git status', {
          cwd: tmpPath
        });

        expect(stderr).to.not.contain('Error:');
        expect(stderr).to.not.contain('fatal:');
        expect(stderr).to.not.contain('Command failed');

        let result = run('git log -1', {
          cwd: tmpPath
        });

        // verify it is not committed
        expect(result).to.contain('Author: Your Name <you@example.com>');
        expect(result).to.contain('add files');

        result = run('git branch', {
          cwd: tmpPath
        });

        // verify branch was deleted
        expect(result.trim()).to.match(/\* foo\r?\n {2}master/);

        resolve({
          status,
          stderr
        });
      });
    });
  }

  it('updates app', function() {
    return merge(
      'test/fixtures/local/my-app',
      'tmp/my-app',
      2
    ).then(result => {
      let status = result.status;

      fixtureCompare(
        'tmp/my-app',
        'test/fixtures/merge/my-app'
      );

      // changed locally, no change upstream
      expect(status).to.not.contain(' .ember-cli');

      // exists locally, also added upstream with changes
      expect(status).to.contain('modified:   .eslintrc.js');

      // changed locally, removed upstream
      expect(status).to.contain('deleted:    bower.json');

      // changed locally, also changed upstream
      expect(status).to.contain('modified:   README.md');
    });
  });

  it('updates addon', function() {
    return merge(
      'test/fixtures/local/my-addon',
      'tmp/my-addon',
      2
    ).then(result => {
      let status = result.status;

      fixtureCompare(
        'tmp/my-addon',
        'test/fixtures/merge/my-addon'
      );

      // changed locally, no change upstream
      expect(status).to.not.contain(' .ember-cli');

      // exists locally, also added upstream with changes
      expect(status).to.contain('modified:   .eslintrc.js');

      // changed locally, removed upstream
      expect(status).to.contain('deleted:    bower.json');

      // changed locally, also changed upstream
      expect(status).to.contain('modified:   README.md');
    });
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import {mount} from 'enzyme';

import * as reporterProxy from '../../lib/reporter-proxy';
import {createRepositoryResult} from '../fixtures/factories/repository-result';
import Remote from '../../lib/models/remote';
import Branch, {nullBranch} from '../../lib/models/branch';
import BranchSet from '../../lib/models/branch-set';
import GithubLoginModel from '../../lib/models/github-login-model';
import {nullOperationStateObserver} from '../../lib/models/operation-state-observer';
import {InMemoryStrategy} from '../../lib/shared/keytar-strategy';
import RemoteContainer from '../../lib/containers/remote-container';
import {expectRelayQuery} from '../../lib/relay-network-layer-manager';

describe('RemoteContainer', function() {
  let atomEnv, model;

  beforeEach(function() {
    atomEnv = global.buildAtomEnvironment();
    model = new GithubLoginModel(InMemoryStrategy);
  });

  afterEach(function() {
    atomEnv.destroy();
  });

  function buildApp(overrideProps = {}) {
    const origin = new Remote('origin', 'git@github.com:atom/github.git');
    const branch = new Branch('master', nullBranch, nullBranch, true);
    const branchSet = new BranchSet();
    branchSet.add(branch);

    return (
      <RemoteContainer
        loginModel={model}

        host="https://api.github.com"

        remoteOperationObserver={nullOperationStateObserver}
        notifications={atomEnv.notifications}
        workspace={atomEnv.workspace}
        remote={origin}
        remotesByName={new Map()}
        branches={branchSet}

        aheadCount={0}
        pushInProgress={false}

        onPushBranch={() => {}}

        {...overrideProps}
      />
    );
  }

  function expectRepositoryQuery() {
    return expectRelayQuery({
      name: 'remoteContainerQuery',
      variables: {
        owner: 'atom',
        name: 'github',
      },
    }, {
      repository: createRepositoryResult(),
    });
  }

  function expectEmptyIssueishQuery() {
    return expectRelayQuery({
      name: 'issueishSearchContainerQuery',
      variables: {
        query: 'repo:atom/github type:pr state:open',
        first: 20,
      },
    }, {
      search: {
        issueCount: 0,
        nodes: [],
      },
    });
  }

  it('renders a loading spinner while the token is being fetched', function() {
    const wrapper = mount(buildApp());
    assert.isTrue(wrapper.find('LoadingView').exists());
  });

  it('renders a loading spinner while the GraphQL query is being performed', async function() {
    expectRepositoryQuery();
    model.setToken('https://api.github.com', '1234');
    sinon.spy(model, 'getToken');
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());
    await model.getToken.returnValues[0];

    assert.isTrue(wrapper.find('LoadingView').exists());
  });

  it('renders a login prompt if no token is found', async function() {
    sinon.spy(model, 'getToken');

    const wrapper = mount(buildApp());
    await model.getToken.returnValues[0];

    assert.isTrue(wrapper.update().find('GithubLoginView').exists());
  });

  it('renders a login prompt if the token has insufficient OAuth scopes', async function() {
    model.setToken('https://api.github.com', '1234');
    sinon.spy(model, 'getToken');
    sinon.stub(model, 'getScopes').resolves([]);

    const wrapper = mount(buildApp());
    await model.getToken.returnValues[0];

    assert.match(wrapper.update().find('GithubLoginView').find('p').text(), /sufficient/);
  });

  it('renders an error message if the GraphQL query fails', async function() {
    const {reject} = expectRepositoryQuery();
    const e = new Error('oh shit!');
    e.rawStack = e.stack;
    reject(e);
    model.setToken('https://api.github.com', '1234');
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());
    await assert.async.isTrue(wrapper.update().find('QueryErrorView').exists());

    const qev = wrapper.find('QueryErrorView');
    assert.strictEqual(qev.prop('error'), e);
  });

  it('increments a counter on login', async function() {
    const token = '1234';
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);
    const incrementCounterStub = sinon.stub(reporterProxy, 'incrementCounter');

    const wrapper = mount(buildApp());
    wrapper.instance().handleLogin(token);
    assert.isTrue(incrementCounterStub.calledOnceWith('github-login'));
  });

  it('increments a counter on logout', async function() {
    const token = '1234';
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());
    wrapper.instance().handleLogin(token);

    const incrementCounterStub = sinon.stub(reporterProxy, 'incrementCounter');
    wrapper.instance().handleLogout();
    assert.isTrue(incrementCounterStub.calledOnceWith('github-logout'));
  });

  it('renders the controller once results have arrived', async function() {
    const {resolve} = expectRepositoryQuery();
    expectEmptyIssueishQuery();
    model.setToken('https://api.github.com', '1234');
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());

    resolve();

    await assert.async.isTrue(wrapper.update().find('RemoteController').exists());
    const controller = wrapper.find('RemoteController');
    assert.strictEqual(controller.prop('token'), '1234');
    assert.deepEqual(controller.prop('repository'), {
      id: 'repository0',
      defaultBranchRef: {
        prefix: 'refs/heads/',
        name: 'master',
      },
    });
  });
});
<commit_msg>:fire: unnecessary async in tests<commit_after>import React from 'react';
import {mount} from 'enzyme';

import * as reporterProxy from '../../lib/reporter-proxy';
import {createRepositoryResult} from '../fixtures/factories/repository-result';
import Remote from '../../lib/models/remote';
import Branch, {nullBranch} from '../../lib/models/branch';
import BranchSet from '../../lib/models/branch-set';
import GithubLoginModel from '../../lib/models/github-login-model';
import {nullOperationStateObserver} from '../../lib/models/operation-state-observer';
import {InMemoryStrategy} from '../../lib/shared/keytar-strategy';
import RemoteContainer from '../../lib/containers/remote-container';
import {expectRelayQuery} from '../../lib/relay-network-layer-manager';

describe('RemoteContainer', function() {
  let atomEnv, model;

  beforeEach(function() {
    atomEnv = global.buildAtomEnvironment();
    model = new GithubLoginModel(InMemoryStrategy);
  });

  afterEach(function() {
    atomEnv.destroy();
  });

  function buildApp(overrideProps = {}) {
    const origin = new Remote('origin', 'git@github.com:atom/github.git');
    const branch = new Branch('master', nullBranch, nullBranch, true);
    const branchSet = new BranchSet();
    branchSet.add(branch);

    return (
      <RemoteContainer
        loginModel={model}

        host="https://api.github.com"

        remoteOperationObserver={nullOperationStateObserver}
        notifications={atomEnv.notifications}
        workspace={atomEnv.workspace}
        remote={origin}
        remotesByName={new Map()}
        branches={branchSet}

        aheadCount={0}
        pushInProgress={false}

        onPushBranch={() => {}}

        {...overrideProps}
      />
    );
  }

  function expectRepositoryQuery() {
    return expectRelayQuery({
      name: 'remoteContainerQuery',
      variables: {
        owner: 'atom',
        name: 'github',
      },
    }, {
      repository: createRepositoryResult(),
    });
  }

  function expectEmptyIssueishQuery() {
    return expectRelayQuery({
      name: 'issueishSearchContainerQuery',
      variables: {
        query: 'repo:atom/github type:pr state:open',
        first: 20,
      },
    }, {
      search: {
        issueCount: 0,
        nodes: [],
      },
    });
  }

  it('renders a loading spinner while the token is being fetched', function() {
    const wrapper = mount(buildApp());
    assert.isTrue(wrapper.find('LoadingView').exists());
  });

  it('renders a loading spinner while the GraphQL query is being performed', async function() {
    expectRepositoryQuery();
    model.setToken('https://api.github.com', '1234');
    sinon.spy(model, 'getToken');
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());
    await model.getToken.returnValues[0];

    assert.isTrue(wrapper.find('LoadingView').exists());
  });

  it('renders a login prompt if no token is found', async function() {
    sinon.spy(model, 'getToken');

    const wrapper = mount(buildApp());
    await model.getToken.returnValues[0];

    assert.isTrue(wrapper.update().find('GithubLoginView').exists());
  });

  it('renders a login prompt if the token has insufficient OAuth scopes', async function() {
    model.setToken('https://api.github.com', '1234');
    sinon.spy(model, 'getToken');
    sinon.stub(model, 'getScopes').resolves([]);

    const wrapper = mount(buildApp());
    await model.getToken.returnValues[0];

    assert.match(wrapper.update().find('GithubLoginView').find('p').text(), /sufficient/);
  });

  it('renders an error message if the GraphQL query fails', async function() {
    const {reject} = expectRepositoryQuery();
    const e = new Error('oh shit!');
    e.rawStack = e.stack;
    reject(e);
    model.setToken('https://api.github.com', '1234');
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());
    await assert.async.isTrue(wrapper.update().find('QueryErrorView').exists());

    const qev = wrapper.find('QueryErrorView');
    assert.strictEqual(qev.prop('error'), e);
  });

  it('increments a counter on login', function() {
    const token = '1234';
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);
    const incrementCounterStub = sinon.stub(reporterProxy, 'incrementCounter');

    const wrapper = mount(buildApp());
    wrapper.instance().handleLogin(token);
    assert.isTrue(incrementCounterStub.calledOnceWith('github-login'));
  });

  it('increments a counter on logout', function() {
    const token = '1234';
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());
    wrapper.instance().handleLogin(token);

    const incrementCounterStub = sinon.stub(reporterProxy, 'incrementCounter');
    wrapper.instance().handleLogout();
    assert.isTrue(incrementCounterStub.calledOnceWith('github-logout'));
  });

  it('renders the controller once results have arrived', async function() {
    const {resolve} = expectRepositoryQuery();
    expectEmptyIssueishQuery();
    model.setToken('https://api.github.com', '1234');
    sinon.stub(model, 'getScopes').resolves(GithubLoginModel.REQUIRED_SCOPES);

    const wrapper = mount(buildApp());

    resolve();

    await assert.async.isTrue(wrapper.update().find('RemoteController').exists());
    const controller = wrapper.find('RemoteController');
    assert.strictEqual(controller.prop('token'), '1234');
    assert.deepEqual(controller.prop('repository'), {
      id: 'repository0',
      defaultBranchRef: {
        prefix: 'refs/heads/',
        name: 'master',
      },
    });
  });
});
<|endoftext|>