<commit_before>// Ken
// -----------------
//
// A Visual Knowledge Browser

var Ken = {};

// Colors
// ------------

Ken.COLOR_PALETTES = {
  "greenish": ["#afc59c", "#bcc97b", "#d8c46f"],
  "blueish": ["#a377b8", "#6c6db4", "#6c9db4"],
  "redish": ["#e3ae78", "#df8682", "#cb829b"]
};

// Ken.Session
// -----------------

Ken.Session = function(collection) {
  // The original collection
  this.collection = collection;
  this.filteredCollection = collection;

  this.filterValueCount = 0;
  this.filters = {};
  this.matches = {};

  this.colors = new ColorPool(Ken.COLOR_PALETTES);

  this.initValueMap();
};

_.extend(Ken.Session.prototype, _.Events, {

  addFilter: function(property, value) {
    if (!this.filters[property]) this.filters[property] = {};
    this.filters[property][value] = {
      color: this.colors.getNext()
    };
    this.filterValueCount += 1;
    this.filter();
  },

  removeFilter: function(property, value) {
    delete this.filters[property][value];
    this.filterValueCount -= 1;
    this.filter();
  },

  // Compute collection based on filters
  filter: function() {
    var that = this;

    // Reset matches
    this.matches = {};

    function flattenFilters() {
      var filters = [];
      _.each(that.filters, function(f, key) {
        _.each(f, function(bla, val) {
          filters.push({
            property: key,
            value: val
          });
        });
      });
      return filters;
    }

    function registerMatch(o, filter) {
      var obj = that.matches[o._id];
      if (!obj) obj = that.matches[o._id] = [];
      obj.push(filter);
    }

    var filters = flattenFilters();

    // Join 'em together
    if (filters.length > 0) {
      this.filteredCollection = new Data.Collection({
        "type": {
          "_id": this.collection.type._id,
          "name": this.collection.type.name,
          "properties": this.collection.type.properties,
        },
        "objects": []
      });
      _.each(filters, function(f) {
        var objects = this.valueMap[f.property][f.value];
        _.each(objects, function(o) {
          registerMatch(o, [f.property, f.value]);

          if (!this.filteredCollection.get(o._id)) this.filteredCollection.add(o);
        }, this);
      }, this);
    } else {
      this.filteredCollection = this.collection;
    }
    console.log('matches', this.matches);
    this.trigger('data:changed');
  },

  // getMatchesForObject: function(o) {
  //   var that = this;
  //   var matches = [];
  //   _.each(this.filters, function(values, property) {
  //     _.each(values, function(color, value) {
  //       if (_.include(that.valueMap[property][value], o)) {
  //         matches.push(color);
  //       }
  //     });
  //   });

  //   console.log('color');
  // },

  getMatchesForObject: function(o) {
    var that = this;
    return _.map(this.matches[o._id], function(filter) {
      return that.filters[filter[0]][filter[1]];
    });
  },

  // Based on current filter criteria, get facets
  getFacets: function() {
    var that = this;
    var facets = {};

    _.each(this.collection.type.properties, function(p, key) {
      if (!p.meta || !p.meta.facet) return;

      function getRelatedObjects(property, value) {
        var objects = [];
        _.each(that.valueMap[property][value], function(o) {
          if (that.filteredCollection.get(o._id)) objects.push(o);
        });
        return objects;
      }

      function getAvailableValues() {
        // Extract available values
        var values = [];
        _.each(that.valueMap[key], function(objects, value) {
          if (that.filters[key] && that.filters[key][value]) return;
          values.push({
            val: value,
            objects: objects,
            relatedObjects: getRelatedObjects(key, value)
          });
        });
        return values;
      }

      function getSelectedValues() {
        var values = [];
        _.each(that.filters[key], function(filter, val) {
          values.push({
            val: val,
            objects: that.valueMap[key][val],
            relatedObjects: getRelatedObjects(key, val),
            color: filter.color
          });
        });
        return values;
      }

      // Find max object count
      var availableValues = getAvailableValues();
      var selectedValues  = getSelectedValues();
      var maxCount = Math.max.apply(this, _.map(availableValues.concat(selectedValues), function(v) {
        return v.objects.length
      }));

      facets[key] = {
        property: p,
        name: p.name,
        availableValues: availableValues,
        selectedValues: selectedValues,
        values: [],
        maxObjectCount: maxCount,
        scale: function(count) {
          return count*60/maxCount; // pixel space = 60px
        }
      };
    });
    return facets;
  },

  initValueMap: function() {
    var that = this;

    this.valueMap = {};

    function extractValues(key) {
      var values = {};

      function registerVal(val, o) {
        if (values[val]) {
          values[val].push(o);
        } else {
          values[val] = [o];
        }
      }

      _.each(that.collection.objects, function(o) {
        var vals = o.properties[key];
        vals = _.isArray(vals) ? vals : [ vals ];

        _.each(vals, function(v) {
          registerVal(v, o);
        });
      });
      return values;
    }

    _.each(this.collection.type.properties, function(p, key) {
      that.valueMap[key] = extractValues(key);
    }, this);
  }
});

// Ken.Matrix
// -----------------
//
// Matrix Plot

Ken.Matrix = Backbone.View.extend({
  events: {

  },

  update: function() {
    this.render();
  },

  render: function() {
    // Empty container
    this.$el.empty();
    _.each(this.model.filteredCollection.objects, function(item) {
      var html = _.tpl('item', {
        item: item,
        matches: this.model.getMatchesForObject(item)
      });

      this.$el.append(html);
    }, this);
    return this;
  }
});

// Ken.Facets
// -----------------

Ken.Facets = Backbone.View.extend({
  events: {
    'click a.value.add': 'addValue',
    'click a.value.remove': 'removeValue'
  },

  // Set a new filter
  addValue: function(e) {
    var property = $(e.currentTarget).attr('data-property'),
        value = $(e.currentTarget).attr('data-value');

    this.model.addFilter(property, value);
    return false;
  },

  // Set a new filter
  removeValue: function(e) {
    var property = $(e.currentTarget).attr('data-property'),
        value = $(e.currentTarget).attr('data-value');

    this.model.removeFilter(property, value);

    return false;
  },

  initialize: function(options) {

  },

  render: function() {
    $(this.el).html(_.tpl('facets', {
      filters: this.model.filters,
      facets: this.model.getFacets()
    }));

    return this;
  }
});

// Ken.Browser
// -------------------

Ken.Browser = Backbone.View.extend({
  events: {

  },

  initialize: function(options) {
    this.model.bind('data:changed', this.update, this);
  },

  // Update plot and facets
  update: function() {
    this.matrix.update();
    this.facets.render();
  },

  render: function() {
    // Should be rendered just once
    $(this.el).html(_.tpl('browser', {}));

    this.facets = new Ken.Facets({model: this.model, el: this.$('#facets')});

    this.matrix = new Ken.Matrix({model: this.model, el: this.$('#matrix')});

    // Initially render the facets
    this.facets.render();

    // Initially render the matrix
    this.matrix.render();

    return this;
  }
});<commit_msg>Sorted by relevance and frequency.<commit_after>// Ken
// -----------------
//
// A Visual Knowledge Browser

var Ken = {};

// Colors
// ------------

Ken.COLOR_PALETTES = {
  "greenish": ["#afc59c", "#bcc97b", "#d8c46f"],
  "blueish": ["#a377b8", "#6c6db4", "#6c9db4"],
  "redish": ["#e3ae78", "#df8682", "#cb829b"]
};

// Ken.Session
// -----------------

Ken.Session = function(collection) {
  // The original collection
  this.collection = collection;
  this.filteredCollection = collection;

  this.filterValueCount = 0;
  this.filters = {};
  this.matches = {};

  this.colors = new ColorPool(Ken.COLOR_PALETTES);

  this.initValueMap();
};

_.extend(Ken.Session.prototype, _.Events, {

  addFilter: function(property, value) {
    if (!this.filters[property]) this.filters[property] = {};
    this.filters[property][value] = {
      color: this.colors.getNext()
    };
    this.filterValueCount += 1;
    this.filter();
  },

  removeFilter: function(property, value) {
    delete this.filters[property][value];
    this.filterValueCount -= 1;
    this.filter();
  },

  // Compute collection based on filters
  filter: function() {
    var that = this;

    // Reset matches
    this.matches = {};

    function flattenFilters() {
      var filters = [];
      _.each(that.filters, function(f, key) {
        _.each(f, function(bla, val) {
          filters.push({
            property: key,
            value: val
          });
        });
      });
      return filters;
    }

    function registerMatch(o, filter) {
      var obj = that.matches[o._id];
      if (!obj) obj = that.matches[o._id] = [];
      obj.push(filter);
    }

    var filters = flattenFilters();

    // Join 'em together
    if (filters.length > 0) {
      this.filteredCollection = new Data.Collection({
        "type": {
          "_id": this.collection.type._id,
          "name": this.collection.type.name,
          "properties": this.collection.type.properties,
        },
        "objects": []
      });
      _.each(filters, function(f) {
        var objects = this.valueMap[f.property][f.value];
        _.each(objects, function(o) {
          registerMatch(o, [f.property, f.value]);

          if (!this.filteredCollection.get(o._id)) this.filteredCollection.add(o);
        }, this);
      }, this);
    } else {
      this.filteredCollection = this.collection;
    }
    console.log('matches', this.matches);
    this.trigger('data:changed');
  },

  // getMatchesForObject: function(o) {
  //   var that = this;
  //   var matches = [];
  //   _.each(this.filters, function(values, property) {
  //     _.each(values, function(color, value) {
  //       if (_.include(that.valueMap[property][value], o)) {
  //         matches.push(color);
  //       }
  //     });
  //   });

  //   console.log('color');
  // },

  getMatchesForObject: function(o) {
    var that = this;
    return _.map(this.matches[o._id], function(filter) {
      return that.filters[filter[0]][filter[1]];
    });
  },

  // Based on current filter criteria, get facets
  getFacets: function() {
    var that = this;
    var facets = {};

    _.each(this.collection.type.properties, function(p, key) {
      if (!p.meta || !p.meta.facet) return;

      function getRelatedObjects(property, value) {
        var objects = [];
        _.each(that.valueMap[property][value], function(o) {
          if (that.filteredCollection.get(o._id)) objects.push(o);
        });
        return objects;
      }

      function getAvailableValues() {
        // Extract available values
        var values = [];
        _.each(that.valueMap[key], function(objects, value) {
          if (that.filters[key] && that.filters[key][value]) return;
          values.push({
            val: value,
            objects: objects,
            relatedObjects: getRelatedObjects(key, value)
          });
        });
        return values;
      }

      function getSelectedValues() {
        var values = [];
        _.each(that.filters[key], function(filter, val) {
          values.push({
            val: val,
            objects: that.valueMap[key][val],
            relatedObjects: getRelatedObjects(key, val),
            color: filter.color
          });
        });
        return values;
      }

      // Find max object count
      var availableValues = getAvailableValues();
      var selectedValues  = getSelectedValues();
      var maxCount = Math.max.apply(this, _.map(availableValues.concat(selectedValues), function(v) {
        return v.objects.length
      }));

      // Sort functions
      var VALUES_BY_RELEVANCE = function(item1, item2) {
        var i1 = item1.relatedObjects.length;
        var i2 = item2.relatedObjects.length;

        return i1 === i2 ? 0 : (i1 > i2 ? -1 : 1);
      };

      var VALUES_BY_FREQUENCY = function(item1, item2) {
        var i1 = item1.objects.length;
        var i2 = item2.objects.length;

        return i1 === i2 ? 0 : (i1 > i2 ? -1 : 1);
      };

      var VALUES_BY_RELEVANCE_AND_FREQUENCY = function(item1, item2) {
        var byRelevance = VALUES_BY_RELEVANCE(item1, item2);
        if (byRelevance !== 0) return byRelevance;
        return VALUES_BY_FREQUENCY(item1, item2);
      };

      availableValues = availableValues.sort(VALUES_BY_RELEVANCE_AND_FREQUENCY);
      selectedValues = selectedValues.sort(VALUES_BY_RELEVANCE_AND_FREQUENCY);

      facets[key] = {
        property: p,
        name: p.name,
        availableValues: availableValues,
        selectedValues: selectedValues,
        values: [],
        maxObjectCount: maxCount,
        scale: function(count) {
          return count*60/maxCount; // pixel space = 60px
        }
      };
    });
    return facets;
  },

  initValueMap: function() {
    var that = this;

    this.valueMap = {};

    function extractValues(key) {
      var values = {};

      function registerVal(val, o) {
        if (values[val]) {
          values[val].push(o);
        } else {
          values[val] = [o];
        }
      }

      _.each(that.collection.objects, function(o) {
        var vals = o.properties[key];
        vals = _.isArray(vals) ? vals : [ vals ];

        _.each(vals, function(v) {
          registerVal(v, o);
        });
      });
      return values;
    }

    _.each(this.collection.type.properties, function(p, key) {
      that.valueMap[key] = extractValues(key);
    }, this);
  }
});

// Ken.Matrix
// -----------------
//
// Matrix Plot

Ken.Matrix = Backbone.View.extend({
  events: {

  },

  update: function() {
    this.render();
  },

  render: function() {
    // Empty container
    this.$el.empty();
    _.each(this.model.filteredCollection.objects, function(item) {
      var html = _.tpl('item', {
        item: item,
        matches: this.model.getMatchesForObject(item)
      });

      this.$el.append(html);
    }, this);
    return this;
  }
});

// Ken.Facets
// -----------------

Ken.Facets = Backbone.View.extend({
  events: {
    'click a.value.add': 'addValue',
    'click a.value.remove': 'removeValue'
  },

  // Set a new filter
  addValue: function(e) {
    var property = $(e.currentTarget).attr('data-property'),
        value = $(e.currentTarget).attr('data-value');

    this.model.addFilter(property, value);
    return false;
  },

  // Set a new filter
  removeValue: function(e) {
    var property = $(e.currentTarget).attr('data-property'),
        value = $(e.currentTarget).attr('data-value');

    this.model.removeFilter(property, value);

    return false;
  },

  initialize: function(options) {

  },

  render: function() {
    $(this.el).html(_.tpl('facets', {
      filters: this.model.filters,
      facets: this.model.getFacets()
    }));

    return this;
  }
});

// Ken.Browser
// -------------------

Ken.Browser = Backbone.View.extend({
  events: {

  },

  initialize: function(options) {
    this.model.bind('data:changed', this.update, this);
  },

  // Update plot and facets
  update: function() {
    this.matrix.update();
    this.facets.render();
  },

  render: function() {
    // Should be rendered just once
    $(this.el).html(_.tpl('browser', {}));

    this.facets = new Ken.Facets({model: this.model, el: this.$('#facets')});

    this.matrix = new Ken.Matrix({model: this.model, el: this.$('#matrix')});

    // Initially render the facets
    this.facets.render();

    // Initially render the matrix
    this.matrix.render();

    return this;
  }
});<|endoftext|>


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

/**
 * @fileoverview Loop blocks for Blockly.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.Blocks.loops');

goog.require('Blockly.Blocks');

/**
 * Common HSV hue for all blocks in this category.
 */
Blockly.Blocks.loops.HUE = 120;

Blockly.Blocks['controls_repeat_ext'] = {
  /**
   * Block for repeat n times (external number).
   * @this Blockly.Block
   */
  init: function() {
    var faded = Blockly.Blocks.oop.isFaded("controls_repeat_ext");
    var message = Blockly.Msg.CONTROLS_REPEAT_TITLE;
    if (faded) {
      message = "for _ in range(%1):";
    }

    this.jsonInit({
      "message0": message,
      "args0": [
        {
          "type": "input_value",
          "name": "TIMES",
          "check": "Number"
        }
      ],
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "tooltip": Blockly.Msg.CONTROLS_REPEAT_TOOLTIP,
      "helpUrl": Blockly.Msg.CONTROLS_REPEAT_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(faded ? "": Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
  }
};

Blockly.Blocks['controls_whileUntil'] = {
  /**
   * Block for 'do while/until' loop.
   * @this Blockly.Block
   */
  init: function() {
    var OPERATORS =
        [[Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE, 'WHILE'],
         [Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, 'UNTIL']];
    this.setHelpUrl(Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL);
    this.setColour(Blockly.Blocks.loops.HUE);
    this.appendValueInput('BOOL')
        .setCheck('Boolean')
        .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE');
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var op = thisBlock.getFieldValue('MODE');
      var TOOLTIPS = {
        'WHILE': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE,
        'UNTIL': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL
      };
      return TOOLTIPS[op];
    });
  }
};

Blockly.Blocks['controls_for'] = {
  /**
   * Block for 'for' loop.
   * @this Blockly.Block
   */
  init: function() {
    this.jsonInit({
      "message0": Blockly.Msg.CONTROLS_FOR_TITLE,
      "args0": [
        {
          "type": "field_variable",
          "name": "VAR",
          "variable": null
        },
        {
          "type": "input_value",
          "name": "FROM",
          "check": "Number",
          "align": "RIGHT"
        },
        {
          "type": "input_value",
          "name": "TO",
          "check": "Number",
          "align": "RIGHT"
        },
        {
          "type": "input_value",
          "name": "BY",
          "check": "Number",
          "align": "RIGHT"
        }
      ],
      "inputsInline": true,
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "helpUrl": Blockly.Msg.CONTROLS_FOR_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_FOR_INPUT_DO);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return Blockly.Msg.CONTROLS_FOR_TOOLTIP.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  },
  /**
   * Return all variables referenced by this block.
   * @return {!Array.<string>} List of variable names.
   * @this Blockly.Block
   */
  getVars: function() {
    return [this.getFieldValue('VAR')];
  },
  /**
   * Notification that a variable is renaming.
   * If the name matches one of this block's variables, rename it.
   * @param {string} oldName Previous name of variable.
   * @param {string} newName Renamed variable.
   * @this Blockly.Block
   */
  renameVar: function(oldName, newName) {
    if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
      this.setFieldValue(newName, 'VAR');
    }
  },
  /**
   * Add menu option to create getter block for loop variable.
   * @param {!Array} options List of menu options to add to.
   * @this Blockly.Block
   */
  customContextMenu: function(options) {
    if (!this.isCollapsed()) {
      var option = {enabled: true};
      var name = this.getFieldValue('VAR');
      option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name);
      var xmlField = goog.dom.createDom('field', null, name);
      xmlField.setAttribute('name', 'VAR');
      var xmlBlock = goog.dom.createDom('block', null, xmlField);
      xmlBlock.setAttribute('type', 'variables_get');
      option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
      options.push(option);
    }
  }
};

Blockly.Blocks['controls_forEach'] = {
  /**
   * Block for 'for each' loop.
   * @this Blockly.Block
   */
  init: function() {
    this.jsonInit({
      "message0": Blockly.Msg.CONTROLS_FOREACH_TITLE,
      "args0": [
        {
          "type": "field_variable",
          "name": "VAR",
          "variable": null
        },
        {
          "type": "input_value",
          "name": "LIST",
          "check": "Array"
        }
      ],
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "helpUrl": Blockly.Msg.CONTROLS_FOREACH_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_FOREACH_INPUT_DO);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return Blockly.Msg.CONTROLS_FOREACH_TOOLTIP.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  },
  /**
   * Return all variables referenced by this block.
   * @return {!Array.<string>} List of variable names.
   * @this Blockly.Block
   */
  getVars: function() {
    return [this.getFieldValue('VAR')];
  },
  /**
   * Notification that a variable is renaming.
   * If the name matches one of this block's variables, rename it.
   * @param {string} oldName Previous name of variable.
   * @param {string} newName Renamed variable.
   * @this Blockly.Block
   */
  renameVar: function(oldName, newName) {
    if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
      this.setFieldValue(newName, 'VAR');
    }
  },
  customContextMenu: Blockly.Blocks['controls_for'].customContextMenu
};

Blockly.Blocks['controls_flow_statements'] = {
  /**
   * Block for flow statements: continue, break.
   * @this Blockly.Block
   */
  init: function() {
    var OPERATORS =
        [[Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK, 'BREAK'],
         [Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE, 'CONTINUE']];
    this.setHelpUrl(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL);
    this.setColour(Blockly.Blocks.loops.HUE);
    this.appendDummyInput()
        .appendField(new Blockly.FieldDropdown(OPERATORS), 'FLOW');
    this.setPreviousStatement(true);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var op = thisBlock.getFieldValue('FLOW');
      var TOOLTIPS = {
        'BREAK': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK,
        'CONTINUE': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE
      };
      return TOOLTIPS[op];
    });
  },
  /**
   * Called whenever anything on the workspace changes.
   * Add warning if this flow block is not nested inside a loop.
   * @this Blockly.Block
   */
  onchange: function() {
    var legal = false;
    // Is the block nested in a loop?
    var block = this;
    do {
      if (this.LOOP_TYPES.indexOf(block.type) != -1) {
        legal = true;
        break;
      }
      block = block.getSurroundParent();
    } while (block);
    if (legal) {
      this.setWarningText(null);
    } else {
      this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
    }
  },
  /**
   * List of block types that are loops and thus do not need warnings.
   * To add a new loop type add this to your code:
   * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop');
   */
  LOOP_TYPES: ['controls_repeat', 'controls_forEach',
      'controls_for', 'controls_whileUntil']
};
<commit_msg>feat(Block Editor): controls_repeat block (for loop with embedded text field) with fading<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Loop blocks for Blockly.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.Blocks.loops');

goog.require('Blockly.Blocks');

/**
 * Common HSV hue for all blocks in this category.
 */
Blockly.Blocks.loops.HUE = 120;

Blockly.Blocks['controls_repeat_ext'] = {
  /**
   * Block for repeat n times (external number).
   * @this Blockly.Block
   */
  init: function() {
    var faded = Blockly.Blocks.oop.isFaded("controls_repeat_ext");
    var message = Blockly.Msg.CONTROLS_REPEAT_TITLE;
    if (faded) {
      message = "for _ in range(%1):";
    }

    this.jsonInit({
      "message0": message,
      "args0": [
        {
          "type": "input_value",
          "name": "TIMES",
          "check": "Number"
        }
      ],
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "tooltip": Blockly.Msg.CONTROLS_REPEAT_TOOLTIP,
      "helpUrl": Blockly.Msg.CONTROLS_REPEAT_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(faded ? "": Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
  }
};

Blockly.Blocks['controls_repeat'] = {
  /**
   * Block for repeat n times (internal number).
   * The 'controls_repeat_ext' block is preferred as it is more flexible.
   * @this Blockly.Block
   */
  init: function() {
    var faded = Blockly.Blocks.oop.isFaded("controls_repeat");
    var message = Blockly.Msg.CONTROLS_REPEAT_TITLE;
    if (faded) {
      message = "for _ in range(%1):";
    }

    this.jsonInit({
      "message0": message,
      "args0": [
        {
          "type": "field_input",
          "name": "TIMES",
          "text": "0"
        }
      ],
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "tooltip": Blockly.Msg.CONTROLS_REPEAT_TOOLTIP,
      "helpUrl": Blockly.Msg.CONTROLS_REPEAT_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
    this.getField('TIMES').setValidator(
        Blockly.FieldTextInput.nonnegativeIntegerValidator);
  }
};

Blockly.Blocks['controls_whileUntil'] = {
  /**
   * Block for 'do while/until' loop.
   * @this Blockly.Block
   */
  init: function() {
    var OPERATORS =
        [[Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE, 'WHILE'],
         [Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, 'UNTIL']];
    this.setHelpUrl(Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL);
    this.setColour(Blockly.Blocks.loops.HUE);
    this.appendValueInput('BOOL')
        .setCheck('Boolean')
        .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE');
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var op = thisBlock.getFieldValue('MODE');
      var TOOLTIPS = {
        'WHILE': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE,
        'UNTIL': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL
      };
      return TOOLTIPS[op];
    });
  }
};

Blockly.Blocks['controls_for'] = {
  /**
   * Block for 'for' loop.
   * @this Blockly.Block
   */
  init: function() {
    this.jsonInit({
      "message0": Blockly.Msg.CONTROLS_FOR_TITLE,
      "args0": [
        {
          "type": "field_variable",
          "name": "VAR",
          "variable": null
        },
        {
          "type": "input_value",
          "name": "FROM",
          "check": "Number",
          "align": "RIGHT"
        },
        {
          "type": "input_value",
          "name": "TO",
          "check": "Number",
          "align": "RIGHT"
        },
        {
          "type": "input_value",
          "name": "BY",
          "check": "Number",
          "align": "RIGHT"
        }
      ],
      "inputsInline": true,
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "helpUrl": Blockly.Msg.CONTROLS_FOR_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_FOR_INPUT_DO);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return Blockly.Msg.CONTROLS_FOR_TOOLTIP.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  },
  /**
   * Return all variables referenced by this block.
   * @return {!Array.<string>} List of variable names.
   * @this Blockly.Block
   */
  getVars: function() {
    return [this.getFieldValue('VAR')];
  },
  /**
   * Notification that a variable is renaming.
   * If the name matches one of this block's variables, rename it.
   * @param {string} oldName Previous name of variable.
   * @param {string} newName Renamed variable.
   * @this Blockly.Block
   */
  renameVar: function(oldName, newName) {
    if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
      this.setFieldValue(newName, 'VAR');
    }
  },
  /**
   * Add menu option to create getter block for loop variable.
   * @param {!Array} options List of menu options to add to.
   * @this Blockly.Block
   */
  customContextMenu: function(options) {
    if (!this.isCollapsed()) {
      var option = {enabled: true};
      var name = this.getFieldValue('VAR');
      option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name);
      var xmlField = goog.dom.createDom('field', null, name);
      xmlField.setAttribute('name', 'VAR');
      var xmlBlock = goog.dom.createDom('block', null, xmlField);
      xmlBlock.setAttribute('type', 'variables_get');
      option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
      options.push(option);
    }
  }
};

Blockly.Blocks['controls_forEach'] = {
  /**
   * Block for 'for each' loop.
   * @this Blockly.Block
   */
  init: function() {
    this.jsonInit({
      "message0": Blockly.Msg.CONTROLS_FOREACH_TITLE,
      "args0": [
        {
          "type": "field_variable",
          "name": "VAR",
          "variable": null
        },
        {
          "type": "input_value",
          "name": "LIST",
          "check": "Array"
        }
      ],
      "previousStatement": null,
      "nextStatement": null,
      "colour": Blockly.Blocks.loops.HUE,
      "helpUrl": Blockly.Msg.CONTROLS_FOREACH_HELPURL
    });
    this.appendStatementInput('DO')
        .appendField(Blockly.Msg.CONTROLS_FOREACH_INPUT_DO);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return Blockly.Msg.CONTROLS_FOREACH_TOOLTIP.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  },
  /**
   * Return all variables referenced by this block.
   * @return {!Array.<string>} List of variable names.
   * @this Blockly.Block
   */
  getVars: function() {
    return [this.getFieldValue('VAR')];
  },
  /**
   * Notification that a variable is renaming.
   * If the name matches one of this block's variables, rename it.
   * @param {string} oldName Previous name of variable.
   * @param {string} newName Renamed variable.
   * @this Blockly.Block
   */
  renameVar: function(oldName, newName) {
    if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
      this.setFieldValue(newName, 'VAR');
    }
  },
  customContextMenu: Blockly.Blocks['controls_for'].customContextMenu
};

Blockly.Blocks['controls_flow_statements'] = {
  /**
   * Block for flow statements: continue, break.
   * @this Blockly.Block
   */
  init: function() {
    var OPERATORS =
        [[Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK, 'BREAK'],
         [Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE, 'CONTINUE']];
    this.setHelpUrl(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL);
    this.setColour(Blockly.Blocks.loops.HUE);
    this.appendDummyInput()
        .appendField(new Blockly.FieldDropdown(OPERATORS), 'FLOW');
    this.setPreviousStatement(true);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var op = thisBlock.getFieldValue('FLOW');
      var TOOLTIPS = {
        'BREAK': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK,
        'CONTINUE': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE
      };
      return TOOLTIPS[op];
    });
  },
  /**
   * Called whenever anything on the workspace changes.
   * Add warning if this flow block is not nested inside a loop.
   * @this Blockly.Block
   */
  onchange: function() {
    var legal = false;
    // Is the block nested in a loop?
    var block = this;
    do {
      if (this.LOOP_TYPES.indexOf(block.type) != -1) {
        legal = true;
        break;
      }
      block = block.getSurroundParent();
    } while (block);
    if (legal) {
      this.setWarningText(null);
    } else {
      this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
    }
  },
  /**
   * List of block types that are loops and thus do not need warnings.
   * To add a new loop type add this to your code:
   * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop');
   */
  LOOP_TYPES: ['controls_repeat', 'controls_forEach',
      'controls_for', 'controls_whileUntil']
};
<|endoftext|>


<commit_before>/**
 * Config file for testing
 * @author NHN Ent. FE Development Lab <dl_javascript@nhnent.com>
 */

'use strict';

var webdriverConfig = {
    hostname: 'fe.nhnent.com',
    port: 4444,
    remoteHost: true
};

/**
 * Set config by environment
 * @param {object} defaultConfig - default config
 * @param {string} server - server type ('ne' or local)
 */
function setConfig(defaultConfig, server) {
    if (server === 'ne') {
        defaultConfig.customLaunchers = {
            'IE8': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '8'
            },
            'IE9': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '9'
            },
            'IE10': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '10'
            },
            'IE11': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '11'
            },
            'Edge': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'MicrosoftEdge'
            },
            'Chrome-WebDriver': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'chrome'
            },
            'Firefox-WebDriver': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'firefox'
            },
            'Safari-WebDriver': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'safari'
            }
        };
        defaultConfig.browsers = [
            'IE9',
            'IE10',
            'IE11',
            'Edge',
            'Chrome-WebDriver',
            'Firefox-WebDriver'
            // 'Safari-WebDriver' // active only when safari test is needed
        ];
        defaultConfig.reporters.push('coverage');
        defaultConfig.reporters.push('junit');
        defaultConfig.coverageReporter = {
            dir: 'report/coverage/',
            reporters: [
                {
                    type: 'html',
                    subdir: function(browser) {
                        return 'report-html/' + browser;
                    }
                },
                {
                    type: 'cobertura',
                    subdir: function(browser) {
                        return 'report-cobertura/' + browser;
                    },
                    file: 'cobertura.txt'
                }
            ]
        };
        defaultConfig.junitReporter = {
            outputDir: 'report',
            suite: ''
        };
    } else {
        defaultConfig.browsers = [
            'ChromeHeadless'
        ];
    }
}

module.exports = function(config) {
    var defaultConfig = {
        basePath: './',
        frameworks: [
            'jquery-1.11.0',
            'jasmine',
            'es5-shim'
        ],
        files: [
            // reason for not using karma-jasmine-jquery framework is that including older jasmine-karma file
            // included jasmine-karma version is 2.0.5 and this version don't support ie8
            {
                pattern: 'node_modules/jasmine-jquery/lib/jasmine-jquery.js',
                watched: false
            },
            {
                pattern: 'test/fixtures/*.html',
                included: false
            },
            {
                pattern: 'test/fixtures/*.css',
                included: false
            },

            'test/index.js'
        ],
        preprocessors: {
            'test/index.js': ['webpack', 'sourcemap']
        },
        reporters: ['dots'],
        webpack: {
            devtool: 'inline-source-map',
            module: {
                preLoaders: [
                    {
                        test: /\.js$/,
                        exclude: /(test|bower_components|node_modules)/,
                        loader: 'istanbul-instrumenter'
                    },
                    {
                        test: /\.js$/,
                        exclude: /(bower_components|node_modules)/,
                        loader: 'eslint-loader'
                    }
                ]
            }
        },
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        singleRun: true
    };

    /* eslint-disable */
    setConfig(defaultConfig, process.env.KARMA_SERVER);
    config.set(defaultConfig);
};
<commit_msg>chore: change path of junit report on karma config file<commit_after>/**
 * Config file for testing
 * @author NHN Ent. FE Development Lab <dl_javascript@nhnent.com>
 */

'use strict';

var webdriverConfig = {
    hostname: 'fe.nhnent.com',
    port: 4444,
    remoteHost: true
};

/**
 * Set config by environment
 * @param {object} defaultConfig - default config
 * @param {string} server - server type ('ne' or local)
 */
function setConfig(defaultConfig, server) {
    if (server === 'ne') {
        defaultConfig.customLaunchers = {
            'IE8': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '8'
            },
            'IE9': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '9'
            },
            'IE10': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '10'
            },
            'IE11': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'internet explorer',
                version: '11'
            },
            'Edge': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'MicrosoftEdge'
            },
            'Chrome-WebDriver': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'chrome'
            },
            'Firefox-WebDriver': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'firefox'
            },
            'Safari-WebDriver': {
                base: 'WebDriver',
                config: webdriverConfig,
                browserName: 'safari'
            }
        };
        defaultConfig.browsers = [
            'IE9',
            'IE10',
            'IE11',
            'Edge',
            'Chrome-WebDriver',
            'Firefox-WebDriver'
            // 'Safari-WebDriver' // active only when safari test is needed
        ];
        defaultConfig.reporters.push('coverage');
        defaultConfig.reporters.push('junit');
        defaultConfig.coverageReporter = {
            dir: 'report/coverage/',
            reporters: [
                {
                    type: 'html',
                    subdir: function(browser) {
                        return 'report-html/' + browser;
                    }
                },
                {
                    type: 'cobertura',
                    subdir: function(browser) {
                        return 'report-cobertura/' + browser;
                    },
                    file: 'cobertura.txt'
                }
            ]
        };
        defaultConfig.junitReporter = {
            outputDir: 'report/junit',
            suite: ''
        };
    } else {
        defaultConfig.browsers = [
            'ChromeHeadless'
        ];
    }
}

module.exports = function(config) {
    var defaultConfig = {
        basePath: './',
        frameworks: [
            'jquery-1.11.0',
            'jasmine',
            'es5-shim'
        ],
        files: [
            // reason for not using karma-jasmine-jquery framework is that including older jasmine-karma file
            // included jasmine-karma version is 2.0.5 and this version don't support ie8
            {
                pattern: 'node_modules/jasmine-jquery/lib/jasmine-jquery.js',
                watched: false
            },
            {
                pattern: 'test/fixtures/*.html',
                included: false
            },
            {
                pattern: 'test/fixtures/*.css',
                included: false
            },

            'test/index.js'
        ],
        preprocessors: {
            'test/index.js': ['webpack', 'sourcemap']
        },
        reporters: ['dots'],
        webpack: {
            devtool: 'inline-source-map',
            module: {
                preLoaders: [
                    {
                        test: /\.js$/,
                        exclude: /(test|bower_components|node_modules)/,
                        loader: 'istanbul-instrumenter'
                    },
                    {
                        test: /\.js$/,
                        exclude: /(bower_components|node_modules)/,
                        loader: 'eslint-loader'
                    }
                ]
            }
        },
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        singleRun: true
    };

    /* eslint-disable */
    setConfig(defaultConfig, process.env.KARMA_SERVER);
    config.set(defaultConfig);
};
<|endoftext|>


<commit_before>var through = require('through');

module.exports = function(config) {
  var cacheSource = function(file) {
    // Hack to give karma-coverage the source files for html reporter
    // since we do not actually use karma to instrument in order to
    // map to pre-browserified code
    var store = require('karma-coverage/lib/source-cache').get(config.basePath);
    var chunks = [];
    return through(function(buff) {
      chunks.push(buff);
      this.queue(buff);
    }, function() {
      store[file] = chunks.join('');
      this.queue(null);
    });
  };

  config.set({
    basePath: '',
    frameworks: ['browserify', 'jasmine'],
    files: [
      'test/parchment.ts',
      'test/registry/*.js',
      'test/unit/linked-list.js',   // Control test order
      'test/unit/registry.js',
      'test/unit/blot.js',
      'test/unit/text.js',
      'test/unit/embed.js',
      'test/unit/inline.js',
      'test/unit/block.js',
      'test/unit/container.js',
      'test/unit/attributor.js'
    ],
    preprocessors: {
      'test/registry/*.js': ['babel'],
      'test/parchment.ts': ['browserify']
    },
    browserify: {
      transform: [cacheSource, 'browserify-istanbul'],
      plugin: [['tsify']]
    },
    exclude: [],
    reporters: ['progress'],
    coverageReporter: {
      dir: '.build/coverage',
      reporters: [
        { type: 'html' },
        { type: 'text' }
      ]
    },
    browsers: ['Chrome'],
    customLaunchers: {
      'saucelabs-chrome': {
        base: 'SauceLabs',
        browserName: 'Chrome',
        platform: 'Mac 10.10',
        version: '43'
      }
    },
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    singleRun: true
  });
};
<commit_msg>istanbul ignore typescript generated extend block<commit_after>var Buffer = require('buffer').Buffer;
var through = require('through');

module.exports = function(config) {
  var cacheSource = function(file) {
    // Hack to give karma-coverage the source files for html reporter
    // since we do not actually use karma to instrument in order to
    // map to pre-browserified code
    var store = require('karma-coverage/lib/source-cache').get(config.basePath);
    var chunks = [];
    var tsExtends = /^var __extends =/;
    return through(function(buff) {
      var str = buff.toString();
      // More hacks for ignoring typescript's __extend
      if (Buffer.isBuffer(buff) && tsExtends.test(str)) {
        buff = Buffer.concat([
          new Buffer(str.split('\n')[0]),
          new Buffer('\n    /* istanbul ignore next */\n'),
          new Buffer(str.split('\n').slice(1).join('\n'))
        ])
      }
      chunks.push(buff);
      this.queue(buff);
    }, function() {
      store[file] = chunks.join('');
      this.queue(null);
    });
  };

  config.set({
    basePath: '',
    frameworks: ['browserify', 'jasmine'],
    files: [
      'test/parchment.ts',
      'test/registry/*.js',
      'test/unit/linked-list.js',   // Control test order
      'test/unit/registry.js',
      'test/unit/blot.js',
      'test/unit/text.js',
      'test/unit/embed.js',
      'test/unit/inline.js',
      'test/unit/block.js',
      'test/unit/container.js',
      'test/unit/attributor.js'
    ],
    preprocessors: {
      'test/registry/*.js': ['babel'],
      'test/parchment.ts': ['browserify']
    },
    browserify: {
      transform: [cacheSource, 'browserify-istanbul'],
      plugin: [['tsify']]
    },
    exclude: [],
    reporters: ['progress'],
    coverageReporter: {
      dir: '.build/coverage',
      reporters: [
        { type: 'html' },
        { type: 'text' }
      ]
    },
    browsers: ['Chrome'],
    customLaunchers: {
      'saucelabs-chrome': {
        base: 'SauceLabs',
        browserName: 'Chrome',
        platform: 'Mac 10.10',
        version: '43'
      }
    },
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    singleRun: true
  });
};
<|endoftext|>


<commit_before>/** @jsx React.DOM */

var shims = require('./shims');
shims.shimIt();
var Physics = require('./Physics');
var React = require('react');
var ReactKinetic = require('react-kinetic');
var InputHandler = require('./InputHandler');
var ResourceLoader = require('./ResourceLoader');

var Ship = require('./Ship');

var Stage = ReactKinetic.Stage;
var Layer = ReactKinetic.Layer;

var Game = React.createClass({
  getDefaultProps: function () {
    return {
      shipAcceleration: 150,
      shipRotAcceleration: Math.PI / 6,
      shipHeight: 191,
      shipWidth: 95
    };
  },

  getInitialState: function () {
    return {
      playerPos: [this.props.height - 200,
                  this.props.width / 2 - 47],
      playerVel: [0, 0],
      playerAcc: [0, 0],
      playerRot: 0,
      playerRotVel: 0,
      playerRotAcc: 0,
      currentTick: 0
    };
  },

  tick: function (timestampMs) {
    var timestamp = timestampMs / 1000.0;
    var inputHandler = this.props.inputHandler;

    if ((this.state.currentTick === 0)) {
      this.setState({
        currentTick: timestamp
      });
    } else {
      var diff = timestamp - this.state.currentTick;
      var rotation = this.state.playerRot;
      var rotVel = this.state.playerRotVel;
      var rotAcc;
      var latAcc;

      if (inputHandler.leftOn) {
        rotAcc  = this.props.shipRotAcceleration;
      } else if (inputHandler.rightOn) {
        rotAcc = -this.props.shipRotAcceleration;
      } else if (rotVel > 0) {
        rotAcc = -this.props.shipRotAcceleration;
      } else if (rotVel < 0) {
        rotAcc = this.props.shipRotAcceleration;
      } else {
        rotAcc = 0;
      }

      if (inputHandler.upOn) {
        latAcc = [Math.sin(rotation) * this.props.shipAcceleration,
                  -Math.cos(rotation) * this.props.shipAcceleration];
      }
      else {
        latAcc = [0, 0];
      }

      var latResult = Physics.simulateVecOffset(
        this.state.playerPos,
        this.state.playerVel,
        latAcc,
        diff
      );

      var newLatPos = latResult.pos;

      if (newLatPos[0] < 0 - this.props.shipHeight) {
        newLatPos[0] = this.props.width;
      } else if (newLatPos[0] > this.props.width + this.props.shipHeight) {
        newLatPos[0] = this.props.width - newLatPos[0];
      }

      if (newLatPos[1] < 0 - this.props.shipHeight) {
        newLatPos[1] = this.props.height;
      } else if (newLatPos[1] > this.props.height + this.props.shipHeight) {
        newLatPos[1] = this.props.height - newLatPos[1];
      }

      var rotResult = Physics.simulateOffset(
        rotation,
        this.state.playerRotVel,
        rotAcc,
        diff
      );

      var newRotVel = rotResult.vel;

      if (rotAcc === 0 && Math.abs(newRotVel) < 1) {
          newRotVel = 0;
      }

      this.setState({
        currentTick: timestamp,
        playerPos: latResult.pos,
        playerVel: latResult.vel,
        playerAcc: latAcc,
        playerRot: rotResult.pos,
        playerRotVel: newRotVel,
        playerRotAcc: rotAcc
      });
    }
    window.requestAnimationFrame(this.tick);
  },

  handlePause: function () {
    if (document.hidden) {
      this.setState({
        currentTick: 0
      });
    }
  },

  componentDidMount: function () {
    document.addEventListener("visibilitychange", this.handlePause, false);
    window.requestAnimationFrame(this.tick);
  },

  render: function () {
    var planeSprite = this.props.resourceLoader.getResource('planeSprite');
    return (
      <Layer>
        <Ship x={this.state.playerPos[0]}
              y={this.state.playerPos[1]}
              rotation={this.state.playerRot}
              rotVel={this.state.playerRotVel}
              velX={this.state.playerVelX}
              image={planeSprite}/>
      </Layer>
    );
  }
});

module.exports = {
  start: function () {
    var loader = new ResourceLoader(function () {
    });
    React.renderComponent(
      <Stage height={700} width={1000}>
        <Game height={700} width={1000}
         inputHandler={new InputHandler()}
         resourceLoader={loader} />
      </Stage>,
      document.getElementById('canvas')
    );
  }
};
<commit_msg>Reverse rotations.<commit_after>/** @jsx React.DOM */

var shims = require('./shims');
shims.shimIt();
var Physics = require('./Physics');
var React = require('react');
var ReactKinetic = require('react-kinetic');
var InputHandler = require('./InputHandler');
var ResourceLoader = require('./ResourceLoader');

var Ship = require('./Ship');

var Stage = ReactKinetic.Stage;
var Layer = ReactKinetic.Layer;

var Game = React.createClass({
  getDefaultProps: function () {
    return {
      shipAcceleration: 150,
      shipRotAcceleration: Math.PI / 6,
      shipHeight: 191,
      shipWidth: 95
    };
  },

  getInitialState: function () {
    return {
      playerPos: [this.props.height - 200,
                  this.props.width / 2 - 47],
      playerVel: [0, 0],
      playerAcc: [0, 0],
      playerRot: 0,
      playerRotVel: 0,
      playerRotAcc: 0,
      currentTick: 0
    };
  },

  tick: function (timestampMs) {
    var timestamp = timestampMs / 1000.0;
    var inputHandler = this.props.inputHandler;

    if ((this.state.currentTick === 0)) {
      this.setState({
        currentTick: timestamp
      });
    } else {
      var diff = timestamp - this.state.currentTick;
      var rotation = this.state.playerRot;
      var rotVel = this.state.playerRotVel;
      var rotAcc;
      var latAcc;

      if (inputHandler.leftOn) {
        rotAcc  = -this.props.shipRotAcceleration;
      } else if (inputHandler.rightOn) {
        rotAcc = this.props.shipRotAcceleration;
      } else if (rotVel > 0) {
        rotAcc = -this.props.shipRotAcceleration;
      } else if (rotVel < 0) {
        rotAcc = this.props.shipRotAcceleration;
      } else {
        rotAcc = 0;
      }

      if (inputHandler.upOn) {
        latAcc = [Math.sin(rotation) * this.props.shipAcceleration,
                  -Math.cos(rotation) * this.props.shipAcceleration];
      }
      else {
        latAcc = [0, 0];
      }

      var latResult = Physics.simulateVecOffset(
        this.state.playerPos,
        this.state.playerVel,
        latAcc,
        diff
      );

      var newLatPos = latResult.pos;

      if (newLatPos[0] < 0 - this.props.shipHeight) {
        newLatPos[0] = this.props.width;
      } else if (newLatPos[0] > this.props.width + this.props.shipHeight) {
        newLatPos[0] = this.props.width - newLatPos[0];
      }

      if (newLatPos[1] < 0 - this.props.shipHeight) {
        newLatPos[1] = this.props.height;
      } else if (newLatPos[1] > this.props.height + this.props.shipHeight) {
        newLatPos[1] = this.props.height - newLatPos[1];
      }

      var rotResult = Physics.simulateOffset(
        rotation,
        this.state.playerRotVel,
        rotAcc,
        diff
      );

      var newRotVel = rotResult.vel;

      if (rotAcc === 0 && Math.abs(newRotVel) < 1) {
          newRotVel = 0;
      }

      this.setState({
        currentTick: timestamp,
        playerPos: latResult.pos,
        playerVel: latResult.vel,
        playerAcc: latAcc,
        playerRot: rotResult.pos,
        playerRotVel: newRotVel,
        playerRotAcc: rotAcc
      });
    }
    window.requestAnimationFrame(this.tick);
  },

  handlePause: function () {
    if (document.hidden) {
      this.setState({
        currentTick: 0
      });
    }
  },

  componentDidMount: function () {
    document.addEventListener("visibilitychange", this.handlePause, false);
    window.requestAnimationFrame(this.tick);
  },

  render: function () {
    var planeSprite = this.props.resourceLoader.getResource('planeSprite');
    return (
      <Layer>
        <Ship x={this.state.playerPos[0]}
              y={this.state.playerPos[1]}
              rotation={this.state.playerRot}
              rotVel={this.state.playerRotVel}
              velX={this.state.playerVelX}
              image={planeSprite}/>
      </Layer>
    );
  }
});

module.exports = {
  start: function () {
    var loader = new ResourceLoader(function () {
    });
    React.renderComponent(
      <Stage height={700} width={1000}>
        <Game height={700} width={1000}
         inputHandler={new InputHandler()}
         resourceLoader={loader} />
      </Stage>,
      document.getElementById('canvas')
    );
  }
};
<|endoftext|>


<commit_before>// Karma configuration
const process = require('process');
const path = require('path');
const webpack = require('webpack');
process.env.CHROME_BIN = require('puppeteer').executablePath();

const isAppveyor = process.env.APPVEYOR_BUILD_NUMBER ? true : false;

module.exports = (config) => {
  config.set({
    singleRun: true,
    frameworks: ['jasmine'],
    client: {
      // Excalibur logs / console logs suppressed when captureConsole = false;
      captureConsole: false,
      jasmine: {
        timeoutInterval: 30000
      }
    },
    proxies: {
      // smooths over loading files because karma prepends '/base/' to everything
      '/src/' : '/base/src/'
    },
    files: [
            'src/spec/_boot.ts',
            { pattern: 'src/spec/images/**/*.mp3', included: false, served: true },
            { pattern: 'src/spec/images/**/*.png', included: false, served: true },
            { pattern: 'src/spec/images/**/*.gif', included: false, served: true },
            { pattern: 'src/spec/images/**/*.txt', included: false, served: true },
            { pattern: 'src/spec/images/**/*.css', included: false, served: true },
            { pattern: 'src/spec/images/**/*.woff2', included: false, served: true },
           ],
    mime: { 'text/x-typescript': ['ts', 'tsx'] },
    preprocessors: {
      './src/spec/_boot.ts': ['webpack']
    },
    webpack: {
      mode: 'none',
      devtool: 'source-map',
      resolve: {
        extensions: ['.ts', '.js'],
        alias: {
          "@excalibur": path.resolve(__dirname, './src/engine/')
        }
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env.__EX_VERSION': '\'test-runner\''
        }),
      ],
      module: {
        rules: [
          {
            test: /\.ts$/,
            loader: 'ts-loader',
            options: {
              projectReferences: true,
              configFile: 'tsconfig.json'
            }
          },
          {
            test: /\.css$/,
            use: ['css-loader']
          },
          {
            test: /\.(png|jpg|gif|mp3)$/i,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192
                }
              }
            ]
          },
          {
            test: /\.glsl$/,
            use: ['raw-loader']
          },
          {
            test: /\.ts$/,
            enforce: 'post',
            include: path.resolve('src/engine/'),
            use: {
              loader: 'istanbul-instrumenter-loader',
              options: { esModules: true }
            }
          }
        ]
      }
    },
    webpackMiddleware: {
    // webpack-dev-middleware configuration
    // i. e.
        stats: 'normal'
    },
    reporters: ['progress', 'coverage-istanbul'],
    coverageReporter: {
      reporters: [
          { type: 'html', dir: 'coverage/' },
          { type: 'lcovonly', dir: 'coverage/', file: 'lcov.info' },
          { type: 'text-summary' }]
    },
    coverageIstanbulReporter: {
      // reports can be any that are listed here: https://github.com/istanbuljs/istanbuljs/tree/aae256fb8b9a3d19414dcf069c592e88712c32c6/packages/istanbul-reports/lib
      reports: ['html', 'lcovonly', 'text-summary'],

      // base output directory. If you include %browser% in the path it will be replaced with the karma browser name
      dir: path.join(__dirname, 'coverage')
    },
    browsers: ['ChromeHeadless_with_audio'],
    browserDisconnectTolerance : 1,
    browserDisconnectTimeout: 10000,
    browserNoActivityTimeout: 60000, // appveyor is slow :(
    customLaunchers: {
      ChromeHeadless_with_audio: {
          base: 'ChromeHeadless',
          flags: ['--autoplay-policy=no-user-gesture-required', '--mute-audio']
      },
      ChromeHeadless_with_debug: {
        base: 'ChromeHeadless',
        flags: ['--remote-debugging-port=9334', '--no-sandbox', '--disable-web-security']
      },
      Chrome_with_debug: {
        base: 'Chrome',
        flags: ['--remote-debugging-port=9334', '--no-sandbox']
      }
    }
  });
};
<commit_msg>fix: Tweak browser params to fix flaky test runner disconnect (#2311)<commit_after>// Karma configuration
const process = require('process');
const path = require('path');
const webpack = require('webpack');
process.env.CHROME_BIN = require('puppeteer').executablePath();

const isAppveyor = process.env.APPVEYOR_BUILD_NUMBER ? true : false;

module.exports = (config) => {
  config.set({
    singleRun: true,
    frameworks: ['jasmine'],
    client: {
      // Excalibur logs / console logs suppressed when captureConsole = false;
      captureConsole: false,
      jasmine: {
        timeoutInterval: 30000
      }
    },
    proxies: {
      // smooths over loading files because karma prepends '/base/' to everything
      '/src/' : '/base/src/'
    },
    files: [
            'src/spec/_boot.ts',
            { pattern: 'src/spec/images/**/*.mp3', included: false, served: true },
            { pattern: 'src/spec/images/**/*.png', included: false, served: true },
            { pattern: 'src/spec/images/**/*.gif', included: false, served: true },
            { pattern: 'src/spec/images/**/*.txt', included: false, served: true },
            { pattern: 'src/spec/images/**/*.css', included: false, served: true },
            { pattern: 'src/spec/images/**/*.woff2', included: false, served: true },
           ],
    mime: { 'text/x-typescript': ['ts', 'tsx'] },
    preprocessors: {
      './src/spec/_boot.ts': ['webpack']
    },
    webpack: {
      mode: 'none',
      devtool: 'source-map',
      resolve: {
        extensions: ['.ts', '.js'],
        alias: {
          "@excalibur": path.resolve(__dirname, './src/engine/')
        }
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env.__EX_VERSION': '\'test-runner\''
        }),
      ],
      module: {
        rules: [
          {
            test: /\.ts$/,
            loader: 'ts-loader',
            options: {
              projectReferences: true,
              configFile: 'tsconfig.json'
            }
          },
          {
            test: /\.css$/,
            use: ['css-loader']
          },
          {
            test: /\.(png|jpg|gif|mp3)$/i,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192
                }
              }
            ]
          },
          {
            test: /\.glsl$/,
            use: ['raw-loader']
          },
          {
            test: /\.ts$/,
            enforce: 'post',
            include: path.resolve('src/engine/'),
            use: {
              loader: 'istanbul-instrumenter-loader',
              options: { esModules: true }
            }
          }
        ]
      }
    },
    webpackMiddleware: {
    // webpack-dev-middleware configuration
    // i. e.
        stats: 'normal'
    },
    reporters: ['progress', 'coverage-istanbul'],
    coverageReporter: {
      reporters: [
          { type: 'html', dir: 'coverage/' },
          { type: 'lcovonly', dir: 'coverage/', file: 'lcov.info' },
          { type: 'text-summary' }]
    },
    coverageIstanbulReporter: {
      // reports can be any that are listed here: https://github.com/istanbuljs/istanbuljs/tree/aae256fb8b9a3d19414dcf069c592e88712c32c6/packages/istanbul-reports/lib
      reports: ['html', 'lcovonly', 'text-summary'],

      // base output directory. If you include %browser% in the path it will be replaced with the karma browser name
      dir: path.join(__dirname, 'coverage')
    },
    browsers: ['ChromeHeadless_with_audio'],
    browserDisconnectTolerance : 1,
    browserDisconnectTimeout: 10000,
    browserNoActivityTimeout: 60000, // appveyor is slow :(
    customLaunchers: {
      ChromeHeadless_with_audio: {
          base: 'ChromeHeadless',
          flags: ['--autoplay-policy=no-user-gesture-required', '--mute-audio', '--disable-gpu', '--no-sandbox']
      },
      ChromeHeadless_with_debug: {
        base: 'ChromeHeadless',
        flags: ['--remote-debugging-port=9334', '--no-sandbox', '--disable-web-security']
      },
      Chrome_with_debug: {
        base: 'Chrome',
        flags: ['--remote-debugging-port=9334', '--no-sandbox']
      }
    }
  });
};
<|endoftext|>


<commit_before>
module.exports = function(config) {

  config.set({
    // base path, that will be used to resolve files and exclude
    basePath : '',

    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files : [
      'public/javascripts/test.js',
      // 'public/javascripts/chunks/TestView.bundle.js',
      // 'public/javascripts/vendor.js', // need for jade definition...
      // 'public/javascripts/whole-vendor.js',
      // 'public/lib/ace/ace.js',
      // 'public/javascripts/aether.js',
      // 'public/javascripts/whole-app.js',
      // 'public/javascripts/app/vendor/jasmine-mock-ajax.js',
      // 'public/javascripts/app/tests.js',
      // 'public/javascripts/run-tests.js'
    ],

    preprocessors : {
      '**/*.coffee': 'coffee',
      '**/javascripts/whole-app.js': 'coverage' // TODO: Webpack: get this working
    },

    // list of files to exclude
    exclude : [],

    // test results reporter to use
    // possible values: 'dots', 'progress', 'junit'
    reporters : ['progress', 'coverage'],

    // web server port
    port : 9050,

    // cli runner port
    runnerPort : 9051,

    // enable / disable colors in the output (reporters and logs)
    colors : true,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel : config.LOG_ERROR, // doesn't seem to work?

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch : true,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers : ['Chrome'],

    // If browser does not capture in given timeout [ms], kill it
    captureTimeout : 5000,

    // Continuous Integration mode
    // if true, it capture browsers, run tests and executing
    singleRun : false,

    coverageReporter : {
      type : 'html',
      dir : 'coverage/'
    },

    //browserConsoleLogOptions: {
    //  level: 'log',
    //  terminal: true
    //},

    plugins : [
      'karma-jasmine',
      'karma-chrome-launcher',
      'karma-phantomjs-launcher',
      'karma-coffee-preprocessor',
      'karma-coverage',
      'karma-firefox-launcher'
    ],

    retryLimit: 5,
    browserNoActivityTimeout: 60000,     // default 10,000ms
    browserDisconnectTolerance: 5
  });

};
<commit_msg>Try some more random Karma config tweaks<commit_after>
module.exports = function(config) {

  config.set({
    // base path, that will be used to resolve files and exclude
    basePath : '',

    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files : [
      'public/javascripts/test.js',
      // 'public/javascripts/chunks/TestView.bundle.js',
      // 'public/javascripts/vendor.js', // need for jade definition...
      // 'public/javascripts/whole-vendor.js',
      // 'public/lib/ace/ace.js',
      // 'public/javascripts/aether.js',
      // 'public/javascripts/whole-app.js',
      // 'public/javascripts/app/vendor/jasmine-mock-ajax.js',
      // 'public/javascripts/app/tests.js',
      // 'public/javascripts/run-tests.js'
    ],

    preprocessors : {
      '**/*.coffee': 'coffee',
      '**/javascripts/whole-app.js': 'coverage' // TODO: Webpack: get this working
    },

    // list of files to exclude
    exclude : [],

    // test results reporter to use
    // possible values: 'dots', 'progress', 'junit'
    reporters : ['progress', 'coverage'],

    // web server port
    port : 9050,

    // cli runner port
    runnerPort : 9051,

    // enable / disable colors in the output (reporters and logs)
    colors : true,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel : config.LOG_ERROR, // doesn't seem to work?

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch : true,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers : ['Firefox'],

    // If browser does not capture in given timeout [ms], kill it
    captureTimeout : 15000,

    transports: ['polling'],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and executing
    singleRun : false,

    coverageReporter : {
      type : 'html',
      dir : 'coverage/'
    },

    //browserConsoleLogOptions: {
    //  level: 'log',
    //  terminal: true
    //},

    plugins : [
      'karma-jasmine',
      //'karma-chrome-launcher',
      //'karma-phantomjs-launcher',
      'karma-coffee-preprocessor',
      'karma-coverage',
      'karma-firefox-launcher'
    ],

    retryLimit: 5,
    browserNoActivityTimeout: 60000,     // default 10,000ms
    browserDisconnectTolerance: 5
  });

};
<|endoftext|>


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

const path = require('path');
const webpackConfig = require('./webpack.config')[0];

const USING_TRAVISCI = Boolean(process.env.TRAVIS);
const USING_SL = Boolean(process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY);

const SL_LAUNCHERS = {
  'sl-chrome-stable': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'latest',
    platform: 'macOS 10.12',
  },
  'sl-chrome-beta': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'dev',
    platform: 'macOS 10.12',
  },
  'sl-chrome-previous': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'latest-1',
    platform: 'macOS 10.12',
  },
  'sl-firefox-stable': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'latest',
    platform: 'Windows 10',
  },
  'sl-firefox-previous': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'latest-1',
    platform: 'Windows 10',
  },
  'sl-ie': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    version: '11',
    platform: 'Windows 8.1',
  },
  // TODO(sgomes): Re-enable Edge and Safari after Sauce Labs problems are fixed.
  // 'sl-edge': {
  //   base: 'SauceLabs',
  //   browserName: 'microsoftedge',
  //   version: 'latest',
  //   platform: 'Windows 10',
  // },
  // 'sl-safari-stable': {
  //   base: 'SauceLabs',
  //   browserName: 'safari',
  //   version: 'latest',
  //   platform: 'macOS 10.12',
  // },
  // 'sl-safari-previous': {
  //   base: 'SauceLabs',
  //   browserName: 'safari',
  //   version: '9.0',
  //   platform: 'OS X 10.11',
  // },
  'sl-ios-safari-latest': {
    base: 'SauceLabs',
    deviceName: 'iPhone Simulator',
    platformVersion: '10.0',
    platformName: 'iOS',
    browserName: 'Safari',
  },
  // 'sl-ios-safari-previous': {
  //   base: 'SauceLabs',
  //   deviceName: 'iPhone Simulator',
  //   platformVersion: '9.3',
  //   platformName: 'iOS',
  //   browserName: 'Safari',
  // },
};

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['mocha'],
    files: [
      'test/unit/index.js',
    ],
    preprocessors: {
      'test/unit/index.js': ['webpack', 'sourcemap'],
    },
    reporters: ['dots', 'coverage'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    browsers: determineBrowsers(),
    browserDisconnectTimeout: 40000,
    browserNoActivityTimeout: 120000,
    captureTimeout: 240000,
    concurrency: USING_SL ? 4 : Infinity,
    customLaunchers: SL_LAUNCHERS,

    coverageReporter: {
      dir: 'coverage',
      reporters: [
        {type: 'lcovonly', subdir: '.'},
        {type: 'json', subdir: '.', file: 'coverage.json'},
        {type: 'html'},
      ],
    },

    client: {
      mocha: {
        reporter: 'html',
        ui: 'qunit',
      },
    },

    webpack: Object.assign({}, webpackConfig, {
      devtool: 'inline-source-map',
      module: Object.assign({}, webpackConfig.module, {
        // Cover source files when not debugging tests. Otherwise, omit coverage instrumenting to get
        // uncluttered source maps.
        rules: webpackConfig.module.rules.concat([config.singleRun ? {
          test: /\.js$/,
          include: path.resolve('./packages'),
          exclude: [
            /node_modules/,
            /adapter.js/,
          ],
          loader: 'istanbul-instrumenter-loader',
          query: {esModules: true},
        } : undefined]).filter(Boolean),
      }),
    }),

    webpackMiddleware: {
      noInfo: true,
    },
  });

  // See https://github.com/karma-runner/karma-sauce-launcher/issues/73
  if (USING_TRAVISCI) {
    config.set({
      sauceLabs: {
        testName: 'Material Components Web Unit Tests - CI',
        tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        username: process.env.SAUCE_USERNAME,
        accessKey: process.env.SAUCE_ACCESS_KEY,
        startConnect: false,
      },
      // Attempt to de-flake Sauce Labs tests on TravisCI.
      transports: ['polling'],
      browserDisconnectTolerance: 3,
    });
  }
};

function determineBrowsers() {
  return USING_SL ? Object.keys(SL_LAUNCHERS) : ['Chrome'];
}
<commit_msg>chore(infrastructure): Increase SL timeout and disable N-1/N+1 browsers (#3182)<commit_after>/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const path = require('path');
const webpackConfig = require('./webpack.config')[0];

const USING_TRAVISCI = Boolean(process.env.TRAVIS);
const USING_SL = Boolean(process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY);

const SL_LAUNCHERS = {
  /*
   * Chrome (desktop)
   */

  'sl-chrome-stable': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'latest',
    platform: 'macOS 10.12',
    extendedDebugging: true,
  },
  // 'sl-chrome-beta': {
  //   base: 'SauceLabs',
  //   browserName: 'chrome',
  //   version: 'dev',
  //   platform: 'macOS 10.12',
  //   extendedDebugging: true,
  // },
  // 'sl-chrome-previous': {
  //   base: 'SauceLabs',
  //   browserName: 'chrome',
  //   version: 'latest-1',
  //   platform: 'macOS 10.12',
  //   extendedDebugging: true,
  // },

  /*
   * Firefox
   */

  'sl-firefox-stable': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'latest',
    platform: 'Windows 10',
    extendedDebugging: true,
  },
  // 'sl-firefox-previous': {
  //   base: 'SauceLabs',
  //   browserName: 'firefox',
  //   version: 'latest-1',
  //   platform: 'Windows 10',
  //   extendedDebugging: true,
  // },

  /*
   * IE
   */

  'sl-ie': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    version: '11',
    platform: 'Windows 8.1',
  },

  /*
   * Edge
   */

  // TODO(sgomes): Re-enable Edge and Safari after Sauce Labs problems are fixed.
  // 'sl-edge': {
  //   base: 'SauceLabs',
  //   browserName: 'microsoftedge',
  //   version: 'latest',
  //   platform: 'Windows 10',
  // },

  /*
   * Safari (desktop)
   */

  // 'sl-safari-stable': {
  //   base: 'SauceLabs',
  //   browserName: 'safari',
  //   version: 'latest',
  //   platform: 'macOS 10.12',
  // },
  // 'sl-safari-previous': {
  //   base: 'SauceLabs',
  //   browserName: 'safari',
  //   version: '9.0',
  //   platform: 'OS X 10.11',
  // },

  /*
   * Safari (mobile)
   */

  'sl-ios-safari-latest': {
    base: 'SauceLabs',
    deviceName: 'iPhone Simulator',
    platformVersion: '10.0',
    platformName: 'iOS',
    browserName: 'Safari',
  },
  // 'sl-ios-safari-previous': {
  //   base: 'SauceLabs',
  //   deviceName: 'iPhone Simulator',
  //   platformVersion: '9.3',
  //   platformName: 'iOS',
  //   browserName: 'Safari',
  // },
};

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['mocha'],
    files: [
      'test/unit/index.js',
    ],
    preprocessors: {
      'test/unit/index.js': ['webpack', 'sourcemap'],
    },
    reporters: ['dots', 'coverage'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    browsers: determineBrowsers(),
    browserDisconnectTimeout: 40000,
    browserNoActivityTimeout: 120000,
    captureTimeout: 240000,
    concurrency: USING_SL ? 4 : Infinity,
    customLaunchers: SL_LAUNCHERS,

    coverageReporter: {
      dir: 'coverage',
      reporters: [
        {type: 'lcovonly', subdir: '.'},
        {type: 'json', subdir: '.', file: 'coverage.json'},
        {type: 'html'},
      ],
    },

    client: {
      mocha: {
        reporter: 'html',
        ui: 'qunit',

        // Number of milliseconds to wait for an individual `test(...)` function to complete.
        // The default is 2000.
        timeout: 10000,
      },
    },

    webpack: Object.assign({}, webpackConfig, {
      devtool: 'inline-source-map',
      module: Object.assign({}, webpackConfig.module, {
        // Cover source files when not debugging tests. Otherwise, omit coverage instrumenting to get
        // uncluttered source maps.
        rules: webpackConfig.module.rules.concat([config.singleRun ? {
          test: /\.js$/,
          include: path.resolve('./packages'),
          exclude: [
            /node_modules/,
            /adapter.js/,
          ],
          loader: 'istanbul-instrumenter-loader',
          query: {esModules: true},
        } : undefined]).filter(Boolean),
      }),
    }),

    webpackMiddleware: {
      noInfo: true,
    },
  });

  // See https://github.com/karma-runner/karma-sauce-launcher/issues/73
  if (USING_TRAVISCI) {
    config.set({
      sauceLabs: {
        testName: 'Material Components Web Unit Tests - CI',
        tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        username: process.env.SAUCE_USERNAME,
        accessKey: process.env.SAUCE_ACCESS_KEY,
        startConnect: false,
      },
      // Attempt to de-flake Sauce Labs tests on TravisCI.
      transports: ['polling'],
      browserDisconnectTolerance: 3,
    });
  }
};

function determineBrowsers() {
  return USING_SL ? Object.keys(SL_LAUNCHERS) : ['Chrome'];
}
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Sun Jan 15 2017 13:33:46 GMT+0800 (中国标准时间)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'test.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
<commit_msg>0.1.1<commit_after>// Karma configuration
// Generated on Sun Jan 15 2017 13:33:46 GMT+0800 (中国标准时间)

var cfg  = {

  // base path that will be used to resolve all patterns (eg. files, exclude)
  basePath: '',

  // frameworks to use
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  frameworks: ['jasmine'],

  // list of files / patterns to load in the browser
  files: [
    'test.js'
  ],

  // list of files to exclude
  exclude: [
  ],

  // preprocess matching files before serving them to the browser
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  preprocessors: {
  },

  // test results reporter to use
  // possible values: 'dots', 'progress'
  // available reporters: https://npmjs.org/browse/keyword/karma-reporter
  reporters: ['progress'],

  // web server port
  port: 9876,

  // enable / disable colors in the output (reporters and logs)
  colors: true,

  // level of logging
  // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG

  // enable / disable watching file and executing tests whenever any file changes
  autoWatch: true,

  // start these browsers
  // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
  browsers: ['Chrome'],

  // Continuous Integration mode
  // if true, Karma captures browsers, runs the tests and exits
  singleRun: false,

  // Concurrency level
  // how many browser should be started simultaneous
  concurrency: Infinity,

  customLaunchers: {
    Chrome_travis_ci: {
      base: 'Chrome',
      flags: ['--no-sandbox']
    }
  }
};

if (process.env.TRAVIS) {
  cfg.browsers = ['Chrome_travis_ci'];
}

module.exports = function(config) {
  cfg.logLevel = config.LOG_INFO;
  config.set(cfg)
}
<|endoftext|>


<commit_before>var process = require("process");

var travis = process.env.TRAVIS;
var singleRun = process.argv.includes("--single-run");
var integrationTests = travis || singleRun || false;

const files = [ './test/tests.js' ];

if (singleRun) {
    files.push('test/integration-tests.js');
}

module.exports = function (config) {

    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['jasmine'],

        // list of files / patterns to load in the browser
        files: files,

        // list of files to exclude
        exclude: [],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            "test/*tests.js": ["webpack", "sourcemap"]
        },

        webpack: require("./webpack.config.js"),

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['progress', "coverage", "kjhtml"],

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['Chrome', 'Firefox'],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: travis ? 4 : undefined,

        coverageReporter: {
            type : 'json',
            dir : 'coverage/'
        }
    });

    if (travis) {
        var customLaunchers = {
            // see https://www.browserstack.com/list-of-browsers-and-platforms?product=automate
            chrome_latest: {
                base: "BrowserStack",
                browser: "Chrome",
                os: "Windows",
                os_version: "10"
            },
            firefox_latest: {
                base: "BrowserStack",
                browser: "firefox",
                os: "Windows",
                os_version: "10"
            },
            opera_latest: {
                base: "BrowserStack",
                browser: "opera",
                os: "Windows",
                os_version: "7"
            },
            ie_latest: {
                base: "BrowserStack",
                os: "Windows",
                os_version: "8.1",
                browser: "ie",
                browser_version: "11.0"
            },
            ie_10: {
                base: "BrowserStack",
                os: "Windows",
                os_version: "8",
                browser: "ie",
                browser_version: "10.0"
            },
            edge_latest: {
                base: "BrowserStack",
                browser: "Edge",
                os: "Windows",
                os_version: "10"
            },
            safari_latest: {
                base: "BrowserStack",
                browser: "safari",
                os: "OS X",
                os_version: "El Capitan"
            },
            ios_latest: {
                base: "BrowserStack",
                browser: "iPhone",
                device: "iPhone 6S",
                os: "ios",
                os_version: "9.1"
            },
            ios_8: {
                base: "BrowserStack",
                browser: "iPhone",
                device: "iPhone 6",
                os: "ios",
                os_version: "8.3"
            },
            ios_7: {
                base: "BrowserStack",
                os: "ios",
                os_version: "7.0",
                browser: "iphone",
                device: "iPhone 5S"
            },
            ios_6: {
                base: "BrowserStack",
                os: "ios",
                os_version: "6.0",
                browser: "iphone",
                device: "iPhone 5"
            },
            ios_51: { // oldest that with web worker support
                base: "BrowserStack",
                os: "ios",
                os_version: "5.1",
                browser: "iphone",
                device: "iPhone 4S"
            },
            android_5: {
                base: "BrowserStack",
                browser: "android",
                device: "Google Nexus 5",
                os: "android",
                os_version: "5"
            },
            android_44: {
                base: "BrowserStack",
                browser: "android",
                device: "Samsung Galaxy S5",
                os: "android",
                os_version: "4.4"
            }
        };

        config.set({
            customLaunchers: customLaunchers,
            browserStack: {
                project: 'Parallel.ES Tests',
                username: process.env.BROWSER_STACK_USERNAME,
                accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
                startTunnel: false,
                tunnelIdentifier: process.env.BROWSERSTACK_LOCAL_IDENTIFIER,
                build: process.env.TRAVIS_BUILD_NUMBER + " - "  + process.env.TRAVIS_BRANCH
            },
            browsers: Object.keys(customLaunchers),
            reporters: ['dots', 'coverage'],
            singleRun: true
        });
    }
};

<commit_msg>Fix android 5.0 configuration<commit_after>var process = require("process");

var travis = process.env.TRAVIS;
var singleRun = process.argv.includes("--single-run");
var integrationTests = travis || singleRun || false;

const files = [ './test/tests.js' ];

if (singleRun) {
    files.push('test/integration-tests.js');
}

module.exports = function (config) {

    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['jasmine'],

        // list of files / patterns to load in the browser
        files: files,

        // list of files to exclude
        exclude: [],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            "test/*tests.js": ["webpack", "sourcemap"]
        },

        webpack: require("./webpack.config.js"),

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['progress', "coverage", "kjhtml"],

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['Chrome', 'Firefox'],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: travis ? 4 : undefined,

        coverageReporter: {
            type : 'json',
            dir : 'coverage/'
        }
    });

    if (travis) {
        var customLaunchers = {
            // see https://www.browserstack.com/list-of-browsers-and-platforms?product=automate
            chrome_latest: {
                base: "BrowserStack",
                browser: "Chrome",
                os: "Windows",
                os_version: "10"
            },
            firefox_latest: {
                base: "BrowserStack",
                browser: "firefox",
                os: "Windows",
                os_version: "10"
            },
            opera_latest: {
                base: "BrowserStack",
                browser: "opera",
                os: "Windows",
                os_version: "7"
            },
            ie_latest: {
                base: "BrowserStack",
                os: "Windows",
                os_version: "8.1",
                browser: "ie",
                browser_version: "11.0"
            },
            ie_10: {
                base: "BrowserStack",
                os: "Windows",
                os_version: "8",
                browser: "ie",
                browser_version: "10.0"
            },
            edge_latest: {
                base: "BrowserStack",
                browser: "Edge",
                os: "Windows",
                os_version: "10"
            },
            safari_latest: {
                base: "BrowserStack",
                browser: "safari",
                os: "OS X",
                os_version: "El Capitan"
            },
            ios_latest: {
                base: "BrowserStack",
                browser: "iPhone",
                device: "iPhone 6S",
                os: "ios",
                os_version: "9.1"
            },
            ios_8: {
                base: "BrowserStack",
                browser: "iPhone",
                device: "iPhone 6",
                os: "ios",
                os_version: "8.3"
            },
            ios_7: {
                base: "BrowserStack",
                os: "ios",
                os_version: "7.0",
                browser: "iphone",
                device: "iPhone 5S"
            },
            ios_6: {
                base: "BrowserStack",
                os: "ios",
                os_version: "6.0",
                browser: "iphone",
                device: "iPhone 5"
            },
            ios_51: { // oldest that with web worker support
                base: "BrowserStack",
                os: "ios",
                os_version: "5.1",
                browser: "iphone",
                device: "iPhone 4S"
            },
            android_5: {
                base: "BrowserStack",
                browser: "android",
                device: "Google Nexus 5",
                os: "android",
                os_version: "5.0"
            },
            android_44: {
                base: "BrowserStack",
                browser: "android",
                device: "Samsung Galaxy S5",
                os: "android",
                os_version: "4.4"
            }
        };

        config.set({
            customLaunchers: customLaunchers,
            browserStack: {
                project: 'Parallel.ES Tests',
                username: process.env.BROWSER_STACK_USERNAME,
                accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
                startTunnel: false,
                tunnelIdentifier: process.env.BROWSERSTACK_LOCAL_IDENTIFIER,
                build: process.env.TRAVIS_BUILD_NUMBER + " - "  + process.env.TRAVIS_BRANCH
            },
            browsers: Object.keys(customLaunchers),
            reporters: ['dots', 'coverage'],
            singleRun: true
        });
    }
};

<|endoftext|>