<commit_before>/*
  backgrid-filter
  http://github.com/wyuenho/backgrid

  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
  Licensed under the MIT @license.
*/
(function (factory) {

  // CommonJS
  if (typeof exports == "object") {

    var lunr;

    try {
      lunr = require("lunr");
    }
    catch (err) {}

    module.exports = factory(require("underscore"),
                             require("backbone"),
                             require("backgrid"),
                             lunr);
  }
  // Browser
  else if (typeof _ !== "underscore" &&
           typeof Backbone !== "undefined" &&
           typeof Backgrid !== "undefined") {
    factory(_, Backbone, Backgrid, window.lunr);
  }

}(function (_, Backbone, Backgrid, lunr) {

  "use strict";

  /**
     ServerSideFilter is a search form widget that submits a query to the server
     for filtering the current collection.

     @class Backgrid.Extension.ServerSideFilter
  */
  var ServerSideFilter = Backgrid.Extension.ServerSideFilter = Backbone.View.extend({

    /** @property */
    tagName: "form",

    /** @property */
    className: "backgrid-filter form-search",

    /** @property {function(Object, ?Object=): string} template */
    template: _.template('
<input type="text" <% if (placeholder) { %> placeholder="<%- placeholder %>" <% } %> name="<%- name %>" />×
'),

    /** @property */
    events: {
      "click .close": "clear",
      "submit": "search"
    },

    /** @property {string} [name='q'] Query key */
    name: "q",

    /**
       @property {string} [placeholder] The HTML5 placeholder to appear beneath
       the search box.
    */
    placeholder: null,

    /**
       @param {Object} options
       @param {Backbone.Collection} options.collection
       @param {string} [options.name]
       @param {string} [options.placeholder]
    */
    initialize: function (options) {
      Backgrid.requireOptions(options, ["collection"]);
      Backbone.View.prototype.initialize.apply(this, arguments);
      this.name = options.name || this.name;
      this.placeholder = options.placeholder || this.placeholder;

      // Persist the query on pagination
      var collection = this.collection, self = this;
      if (Backbone.PageableCollection &&
          collection instanceof Backbone.PageableCollection &&
          collection.mode == "server") {
        collection.queryParams[this.name] = function () {
          return self.searchBox().val() || null;
        };
      }
    },

    searchBox: function () {
      return this.$el.find("input[type=text]");
    },

    /**
       Upon search form submission, this event handler constructs a query
       parameter object and pass it to Collection#fetch for server-side
       filtering.
    */
    search: function (e) {
      if (e) e.preventDefault();

      var data = {};

      // go back to the first page on search
      var collection = this.collection;
      if (Backbone.PageableCollection &&
          collection instanceof Backbone.PageableCollection &&
          collection.mode == "server") {
        collection.state.currentPage = 1;
      }
      else {
        var query = this.searchBox().val();
        if (query) data[this.name] = query;
      }

      collection.fetch({data: data, reset: true});
    },

    /**
       Event handler for the close button. Clears the search box and refetch the
       collection.
    */
    clear: function (e) {
      if (e) e.preventDefault();
      this.searchBox().val(null);
      this.collection.fetch({reset: true});
    },

    /**
       Renders a search form with a text box, optionally with a placeholder and
       a preset value if supplied during initialization.
    */
    render: function () {
      this.$el.empty().append(this.template({
        name: this.name,
        placeholder: this.placeholder,
        value: this.value
      }));
      this.delegateEvents();
      return this;
    }

  });

  /**
     ClientSideFilter is a search form widget that searches a collection for
     model matches against a query on the client side. The exact matching
     algorithm can be overriden by subclasses.

     @class Backgrid.Extension.ClientSideFilter
     @extends Backgrid.Extension.ServerSideFilter
  */
  var ClientSideFilter = Backgrid.Extension.ClientSideFilter = ServerSideFilter.extend({

    /** @property */
    events: {
      "click .close": function (e) {
        e.preventDefault();
        this.clear();
      },
      "keydown input[type=text]": "search",
      "submit": function (e) {
        e.preventDefault();
        this.search();
      }
    },

    /**
       @property {?Array.<string>} [fields] A list of model field names to
       search for matches. If null, all of the fields will be searched.
    */
    fields: null,

    /**
       @property [wait=149] The time in milliseconds to wait since for since the
       last change to the search box's value before searching. This value can be
       adjusted depending on how often the search box is used and how large the
       search index is.
    */
    wait: 149,

    /**
       Debounces the #search and #clear methods and makes a copy of the given
       collection for searching.

       @param {Object} options
       @param {Backbone.Collection} options.collection
       @param {string} [options.placeholder]
       @param {string} [options.fields]
       @param {string} [options.wait=149]
    */
    initialize: function (options) {
      ServerSideFilter.prototype.initialize.apply(this, arguments);

      this.fields = options.fields || this.fields;
      this.wait = options.wait || this.wait;

      this._debounceMethods(["search", "clear"]);

      var collection = this.collection = this.collection.fullCollection || this.collection;
      var shadowCollection = this.shadowCollection = collection.clone();

      this.listenTo(collection, "add", function (model, collection, options) {
        shadowCollection.add(model, options);
      });
      this.listenTo(collection, "remove", function (model, collection, options) {
        shadowCollection.remove(model, options);
      });
      this.listenTo(collection, "sort", function (col) {
        if (!this.searchBox().val()) shadowCollection.reset(col.models);
      });
      this.listenTo(collection, "reset", function (col, options) {
        options = _.extend({reindex: true}, options || {});
        if (options.reindex && col === collection &&
            options.from == null && options.to == null) {
          shadowCollection.reset(col.models);
        }
      });
    },

    _debounceMethods: function (methodNames) {
      if (_.isString(methodNames)) methodNames = [methodNames];

      this.undelegateEvents();

      for (var i = 0, l = methodNames.length; i < l; i++) {
        var methodName = methodNames[i];
        var method = this[methodName];
        this[methodName] = _.debounce(method, this.wait);
      }

      this.delegateEvents();
    },

    /**
       This default implementation takes a query string and returns a matcher
       function that looks for matches in the model's #fields or all of its
       fields if #fields is null, for any of the words in the query
       case-insensitively.

       Subclasses overriding this method must take care to conform to the
       signature of the matcher function. In addition, when the matcher function
       is called, its context will be bound to this ClientSideFilter object so
       it has access to the filter's attributes and methods.

       @param {string} query The search query in the search box.
       @return {function(Backbone.Model):boolean} A matching function.
    */
    makeMatcher: function (query) {
      var regexp = new RegExp(query.trim().split(/\W/).join("|"), "i");
      return function (model) {
        var keys = this.fields || model.keys();
        for (var i = 0, l = keys.length; i < l; i++) {
          if (regexp.test(model.get(keys[i]) + "")) return true;
        }
        return false;
      };
    },

    /**
       Takes the query from the search box, constructs a matcher with it and
       loops through collection looking for matches. Reset the given collection
       when all the matches have been found.
    */
    search: function () {
      var matcher = _.bind(this.makeMatcher(this.searchBox().val()), this);
      var col = this.collection;
      if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
      this.collection.reset(this.shadowCollection.filter(matcher), {reindex: false});
    },

    /**
       Clears the search box and reset the collection to its original.
    */
    clear: function () {
      this.searchBox().val(null);
      this.collection.reset(this.shadowCollection.models, {reindex: false});
    }

  });

  /**
     LunrFilter is a ClientSideFilter that uses [lunrjs](http://lunrjs.com/) to
     index the text fields of each model for a collection, and performs
     full-text searching.

     @class Backgrid.Extension.LunrFilter
     @extends Backgrid.Extension.ClientSideFilter
  */
  Backgrid.Extension.LunrFilter = ClientSideFilter.extend({

    /**
       @property {string} [ref="id"]｀lunrjs` document reference attribute name.
    */
    ref: "id",

    /**
       @property {Object} fields A hash of `lunrjs` index field names and boost
       value. Unlike ClientSideFilter#fields, LunrFilter#fields is _required_ to
       initialize the index.
    */
    fields: null,

    /**
       Indexes the underlying collection on construction. The index will refresh
       when the underlying collection is reset. If any model is added, removed
       or if any indexed fields of any models has changed, the index will be
       updated.

       @param {Object} options
       @param {Backbone.Collection} options.collection
       @param {string} [options.placeholder]
       @param {string} [options.ref] ｀lunrjs` document reference attribute name.
       @param {Object} [options.fields] A hash of `lunrjs` index field names and
       boost value.
       @param {number} [options.wait]
    */
    initialize: function (options) {
      ClientSideFilter.prototype.initialize.apply(this, arguments);

      this.ref = options.ref || this.ref;

      var collection = this.collection = this.collection.fullCollection || this.collection;
      this.listenTo(collection, "add", this.addToIndex);
      this.listenTo(collection, "remove", this.removeFromIndex);
      this.listenTo(collection, "reset", this.resetIndex);
      this.listenTo(collection, "change", this.updateIndex);

      this.resetIndex(collection);
    },

    /**
       Reindex the collection. If `options.reindex` is `false`, this method is a
       no-op.

       @param {Backbone.Collection} collection
       @param {Object} [options]
       @param {boolean} [options.reindex=true]
    */
    resetIndex: function (collection, options) {
      options = _.extend({reindex: true}, options || {});

      if (options.reindex) {
        var self = this;
        this.index = lunr(function () {
          _.each(self.fields, function (boost, fieldName) {
            this.field(fieldName, boost);
            this.ref(self.ref);
          }, this);
        });

        collection.each(function (model) {
          this.addToIndex(model);
        }, this);
      }
    },

    /**
       Adds the given model to the index.

       @param {Backbone.Model} model
    */
    addToIndex: function (model) {
      var index = this.index;
      var doc = model.toJSON();
      if (index.documentStore.has(doc[this.ref])) index.update(doc);
      else index.add(doc);
    },

    /**
       Removes the given model from the index.

       @param {Backbone.Model} model
    */
    removeFromIndex: function (model) {
      var index = this.index;
      var doc = model.toJSON();
      if (index.documentStore.has(doc[this.ref])) index.remove(doc);
    },

    /**
       Updates the index for the given model.

       @param {Backbone.Model} model
    */
    updateIndex: function (model) {
      var changed = model.changedAttributes();
      if (changed && !_.isEmpty(_.intersection(_.keys(this.fields),
                                               _.keys(changed)))) {
        this.index.update(model.toJSON());
      }
    },

    /**
       Takes the query from the search box and performs a full-text search on
       the client-side. The search result is returned by resetting the
       underlying collection to the models after interrogating the index for the
       query answer.
    */
    search: function () {
      var searchResults = this.index.search(this.searchBox().val());
      var models = [];
      for (var i = 0; i < searchResults.length; i++) {
        var result = searchResults[i];
        models.push(this.shadowCollection.get(result.ref));
      }
      var col = this.collection;
      if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
      col.reset(models, {reindex: false});
    }

  });

}));
<commit_msg>Fix wyuenho/backgrid#259 move regex factory out of makeMatcher for easier overriding<commit_after>/*
  backgrid-filter
  http://github.com/wyuenho/backgrid

  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
  Licensed under the MIT @license.
*/
(function (factory) {

  // CommonJS
  if (typeof exports == "object") {

    var lunr;

    try {
      lunr = require("lunr");
    }
    catch (err) {}

    module.exports = factory(require("underscore"),
                             require("backbone"),
                             require("backgrid"),
                             lunr);
  }
  // Browser
  else if (typeof _ !== "underscore" &&
           typeof Backbone !== "undefined" &&
           typeof Backgrid !== "undefined") {
    factory(_, Backbone, Backgrid, window.lunr);
  }

}(function (_, Backbone, Backgrid, lunr) {

  "use strict";

  /**
     ServerSideFilter is a search form widget that submits a query to the server
     for filtering the current collection.

     @class Backgrid.Extension.ServerSideFilter
  */
  var ServerSideFilter = Backgrid.Extension.ServerSideFilter = Backbone.View.extend({

    /** @property */
    tagName: "form",

    /** @property */
    className: "backgrid-filter form-search",

    /** @property {function(Object, ?Object=): string} template */
    template: _.template('
<input type="text" <% if (placeholder) { %> placeholder="<%- placeholder %>" <% } %> name="<%- name %>" />×
'),

    /** @property */
    events: {
      "click .close": "clear",
      "submit": "search"
    },

    /** @property {string} [name='q'] Query key */
    name: "q",

    /**
       @property {string} [placeholder] The HTML5 placeholder to appear beneath
       the search box.
    */
    placeholder: null,

    /**
       @param {Object} options
       @param {Backbone.Collection} options.collection
       @param {string} [options.name]
       @param {string} [options.placeholder]
    */
    initialize: function (options) {
      Backgrid.requireOptions(options, ["collection"]);
      Backbone.View.prototype.initialize.apply(this, arguments);
      this.name = options.name || this.name;
      this.placeholder = options.placeholder || this.placeholder;

      // Persist the query on pagination
      var collection = this.collection, self = this;
      if (Backbone.PageableCollection &&
          collection instanceof Backbone.PageableCollection &&
          collection.mode == "server") {
        collection.queryParams[this.name] = function () {
          return self.searchBox().val() || null;
        };
      }
    },

    searchBox: function () {
      return this.$el.find("input[type=text]");
    },

    /**
       Upon search form submission, this event handler constructs a query
       parameter object and pass it to Collection#fetch for server-side
       filtering.
    */
    search: function (e) {
      if (e) e.preventDefault();

      var data = {};

      // go back to the first page on search
      var collection = this.collection;
      if (Backbone.PageableCollection &&
          collection instanceof Backbone.PageableCollection &&
          collection.mode == "server") {
        collection.state.currentPage = 1;
      }
      else {
        var query = this.searchBox().val();
        if (query) data[this.name] = query;
      }

      collection.fetch({data: data, reset: true});
    },

    /**
       Event handler for the close button. Clears the search box and refetch the
       collection.
    */
    clear: function (e) {
      if (e) e.preventDefault();
      this.searchBox().val(null);
      this.collection.fetch({reset: true});
    },

    /**
       Renders a search form with a text box, optionally with a placeholder and
       a preset value if supplied during initialization.
    */
    render: function () {
      this.$el.empty().append(this.template({
        name: this.name,
        placeholder: this.placeholder,
        value: this.value
      }));
      this.delegateEvents();
      return this;
    }

  });

  /**
     ClientSideFilter is a search form widget that searches a collection for
     model matches against a query on the client side. The exact matching
     algorithm can be overriden by subclasses.

     @class Backgrid.Extension.ClientSideFilter
     @extends Backgrid.Extension.ServerSideFilter
  */
  var ClientSideFilter = Backgrid.Extension.ClientSideFilter = ServerSideFilter.extend({

    /** @property */
    events: {
      "click .close": function (e) {
        e.preventDefault();
        this.clear();
      },
      "keydown input[type=text]": "search",
      "submit": function (e) {
        e.preventDefault();
        this.search();
      }
    },

    /**
       @property {?Array.<string>} [fields] A list of model field names to
       search for matches. If null, all of the fields will be searched.
    */
    fields: null,

    /**
       @property [wait=149] The time in milliseconds to wait since for since the
       last change to the search box's value before searching. This value can be
       adjusted depending on how often the search box is used and how large the
       search index is.
    */
    wait: 149,

    /**
       Debounces the #search and #clear methods and makes a copy of the given
       collection for searching.

       @param {Object} options
       @param {Backbone.Collection} options.collection
       @param {string} [options.placeholder]
       @param {string} [options.fields]
       @param {string} [options.wait=149]
    */
    initialize: function (options) {
      ServerSideFilter.prototype.initialize.apply(this, arguments);

      this.fields = options.fields || this.fields;
      this.wait = options.wait || this.wait;

      this._debounceMethods(["search", "clear"]);

      var collection = this.collection = this.collection.fullCollection || this.collection;
      var shadowCollection = this.shadowCollection = collection.clone();

      this.listenTo(collection, "add", function (model, collection, options) {
        shadowCollection.add(model, options);
      });
      this.listenTo(collection, "remove", function (model, collection, options) {
        shadowCollection.remove(model, options);
      });
      this.listenTo(collection, "sort", function (col) {
        if (!this.searchBox().val()) shadowCollection.reset(col.models);
      });
      this.listenTo(collection, "reset", function (col, options) {
        options = _.extend({reindex: true}, options || {});
        if (options.reindex && col === collection &&
            options.from == null && options.to == null) {
          shadowCollection.reset(col.models);
        }
      });
    },

    _debounceMethods: function (methodNames) {
      if (_.isString(methodNames)) methodNames = [methodNames];

      this.undelegateEvents();

      for (var i = 0, l = methodNames.length; i < l; i++) {
        var methodName = methodNames[i];
        var method = this[methodName];
        this[methodName] = _.debounce(method, this.wait);
      }

      this.delegateEvents();
    },

    /**
       Constructs a Javascript regular expression object for #makeMatcher.

       This default implementation takes a query string and returns a Javascript
       RegExp object that matches any of the words contained in the query string
       case-insensitively. Override this method to return a different regular
       expression matcher if this behavior is not desired.

       @param {string} query The search query in the search box.
       @return {RegExp} A RegExp object to match against model #fields.
     */
    makeRegExp: function (query) {
      return new RegExp(query.trim().split(/\W/).join("|"), "i");
    },

    /**
       This default implementation takes a query string and returns a matcher
       function that looks for matches in the model's #fields or all of its
       fields if #fields is null, for any of the words in the query
       case-insensitively using the regular expression object returned from
       #makeRegExp.

       Most of time, you'd want to override the regular expression used for
       matching. If so, please refer to the #makeRegExp documentation,
       otherwise, you can override this method to return a custom matching
       function.

       Subclasses overriding this method must take care to conform to the
       signature of the matcher function. The matcher function is a function
       that takes a model as paramter and returns true if the model matches a
       search, or false otherwise.

       In addition, when the matcher function is called, its context will be
       bound to this ClientSideFilter object so it has access to the filter's
       attributes and methods.

       @param {string} query The search query in the search box.
       @return {function(Backbone.Model):boolean} A matching function.
    */
    makeMatcher: function (query) {
      var regexp = this.makeRegExp(query);
      return function (model) {
        var keys = this.fields || model.keys();
        for (var i = 0, l = keys.length; i < l; i++) {
          if (regexp.test(model.get(keys[i]) + "")) return true;
        }
        return false;
      };
    },

    /**
       Takes the query from the search box, constructs a matcher with it and
       loops through collection looking for matches. Reset the given collection
       when all the matches have been found.
    */
    search: function () {
      var matcher = _.bind(this.makeMatcher(this.searchBox().val()), this);
      var col = this.collection;
      if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
      this.collection.reset(this.shadowCollection.filter(matcher), {reindex: false});
    },

    /**
       Clears the search box and reset the collection to its original.
    */
    clear: function () {
      this.searchBox().val(null);
      this.collection.reset(this.shadowCollection.models, {reindex: false});
    }

  });

  /**
     LunrFilter is a ClientSideFilter that uses [lunrjs](http://lunrjs.com/) to
     index the text fields of each model for a collection, and performs
     full-text searching.

     @class Backgrid.Extension.LunrFilter
     @extends Backgrid.Extension.ClientSideFilter
  */
  Backgrid.Extension.LunrFilter = ClientSideFilter.extend({

    /**
       @property {string} [ref="id"]｀lunrjs` document reference attribute name.
    */
    ref: "id",

    /**
       @property {Object} fields A hash of `lunrjs` index field names and boost
       value. Unlike ClientSideFilter#fields, LunrFilter#fields is _required_ to
       initialize the index.
    */
    fields: null,

    /**
       Indexes the underlying collection on construction. The index will refresh
       when the underlying collection is reset. If any model is added, removed
       or if any indexed fields of any models has changed, the index will be
       updated.

       @param {Object} options
       @param {Backbone.Collection} options.collection
       @param {string} [options.placeholder]
       @param {string} [options.ref] ｀lunrjs` document reference attribute name.
       @param {Object} [options.fields] A hash of `lunrjs` index field names and
       boost value.
       @param {number} [options.wait]
    */
    initialize: function (options) {
      ClientSideFilter.prototype.initialize.apply(this, arguments);

      this.ref = options.ref || this.ref;

      var collection = this.collection = this.collection.fullCollection || this.collection;
      this.listenTo(collection, "add", this.addToIndex);
      this.listenTo(collection, "remove", this.removeFromIndex);
      this.listenTo(collection, "reset", this.resetIndex);
      this.listenTo(collection, "change", this.updateIndex);

      this.resetIndex(collection);
    },

    /**
       Reindex the collection. If `options.reindex` is `false`, this method is a
       no-op.

       @param {Backbone.Collection} collection
       @param {Object} [options]
       @param {boolean} [options.reindex=true]
    */
    resetIndex: function (collection, options) {
      options = _.extend({reindex: true}, options || {});

      if (options.reindex) {
        var self = this;
        this.index = lunr(function () {
          _.each(self.fields, function (boost, fieldName) {
            this.field(fieldName, boost);
            this.ref(self.ref);
          }, this);
        });

        collection.each(function (model) {
          this.addToIndex(model);
        }, this);
      }
    },

    /**
       Adds the given model to the index.

       @param {Backbone.Model} model
    */
    addToIndex: function (model) {
      var index = this.index;
      var doc = model.toJSON();
      if (index.documentStore.has(doc[this.ref])) index.update(doc);
      else index.add(doc);
    },

    /**
       Removes the given model from the index.

       @param {Backbone.Model} model
    */
    removeFromIndex: function (model) {
      var index = this.index;
      var doc = model.toJSON();
      if (index.documentStore.has(doc[this.ref])) index.remove(doc);
    },

    /**
       Updates the index for the given model.

       @param {Backbone.Model} model
    */
    updateIndex: function (model) {
      var changed = model.changedAttributes();
      if (changed && !_.isEmpty(_.intersection(_.keys(this.fields),
                                               _.keys(changed)))) {
        this.index.update(model.toJSON());
      }
    },

    /**
       Takes the query from the search box and performs a full-text search on
       the client-side. The search result is returned by resetting the
       underlying collection to the models after interrogating the index for the
       query answer.
    */
    search: function () {
      var searchResults = this.index.search(this.searchBox().val());
      var models = [];
      for (var i = 0; i < searchResults.length; i++) {
        var result = searchResults[i];
        models.push(this.shadowCollection.get(result.ref));
      }
      var col = this.collection;
      if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
      col.reset(models, {reindex: false});
    }

  });

}));
<|endoftext|>


<commit_before>// https://leetcode.com/problems/subsets/description/

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var subsets = function (nums) {
  let result = [[]];
  for (let num of nums) {
    let len = result.length;
    for (let i = 0; i < len; i++) {
      let temp = [].concat(result[i]);
      temp.push(num);
      result.push(temp);
    }
  }
  return result;
};

var nums = [1, 2, 3];
console.log(subsets(nums));

var nums = [1, 2, 3, 4];
console.log(subsets(nums));<commit_msg>Add second solution for subsets<commit_after>// https://leetcode.com/problems/subsets/description/

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var subsets2 = function (nums) {
  let result = [[]];
  for (let num of nums) {
    let len = result.length;
    for (let i = 0; i < len; i++) {
      let temp = [].concat(result[i]);
      temp.push(num);
      result.push(temp);
    }
  }
  return result;
};

var subsets = function (nums) {
  let dfs = (tempRes, nums, start) => {
    if (start === nums.length) return [];
    let result = [];
    for (let i = start; i < nums.length; i++) {
      let temp = [].concat(tempRes);
      temp.push(nums[i]);
      result.push(temp);
      result = result.concat(dfs(temp, nums, i + 1));
    }
    return result;
  }

  let result = [[]].concat(dfs([], nums, 0));
  return result;
};

var nums = [1, 2, 3];
console.log(subsets(nums));

var nums = [1, 2, 3, 4];
console.log(subsets(nums));<|endoftext|>


<commit_before>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticMouseEvent
 */

'use strict';

var SyntheticUIEvent = require('SyntheticUIEvent');

var getEventModifierState = require('getEventModifierState');

/**
 * @interface MouseEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var MouseEventInterface = {
  screenX: null,
  screenY: null,
  clientX: null,
  clientY: null,
  pageX: null,
  pageY: null,
  ctrlKey: null,
  shiftKey: null,
  altKey: null,
  metaKey: null,
  getModifierState: getEventModifierState,
  button: function(event) {
    // Webkit, Firefox, IE9+
    // which:  1 2 3
    // button: 0 1 2 (standard)
    var button = event.button;
    if ('which' in event) {
      return button;
    }
    // IE<9
    // which:  undefined
    // button: 0 0 0
    // button: 1 4 2 (onmouseup)
    return button === 2 ? 2 : button === 4 ? 1 : 0;
  },
  buttons: null,
  relatedTarget: function(event) {
    return event.relatedTarget ||
      (event.fromElement === event.srcElement
        ? event.toElement
        : event.fromElement);
  },
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticMouseEvent(
  dispatchConfig,
  dispatchMarker,
  nativeEvent,
  nativeEventTarget,
) {
  return SyntheticUIEvent.call(
    this,
    dispatchConfig,
    dispatchMarker,
    nativeEvent,
    nativeEventTarget,
  );
}

SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);

module.exports = SyntheticMouseEvent;
<commit_msg>Remove MouseEvent.button polyfill (#9334)<commit_after>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticMouseEvent
 */

'use strict';

var SyntheticUIEvent = require('SyntheticUIEvent');

var getEventModifierState = require('getEventModifierState');

/**
 * @interface MouseEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var MouseEventInterface = {
  screenX: null,
  screenY: null,
  clientX: null,
  clientY: null,
  pageX: null,
  pageY: null,
  ctrlKey: null,
  shiftKey: null,
  altKey: null,
  metaKey: null,
  getModifierState: getEventModifierState,
  button: null,
  buttons: null,
  relatedTarget: function(event) {
    return event.relatedTarget ||
      (event.fromElement === event.srcElement
        ? event.toElement
        : event.fromElement);
  },
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticMouseEvent(
  dispatchConfig,
  dispatchMarker,
  nativeEvent,
  nativeEventTarget,
) {
  return SyntheticUIEvent.call(
    this,
    dispatchConfig,
    dispatchMarker,
    nativeEvent,
    nativeEventTarget,
  );
}

SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);

module.exports = SyntheticMouseEvent;
<|endoftext|>


<commit_before>'use strict';
var gulp        = require('gulp'),                   // Base gulp package
    babelify    = require('babelify'),               // Used to convert ES6 & JSX to ES5
    browserify  = require('browserify'),             // Providers "require" support, CommonJS
    buffer      = require('vinyl-buffer'),           // Vinyl stream support
    chalk       = require('chalk'),                  // Allows for coloring for logging
    cssmin      = require('gulp-cssmin'),            // Minifies CSS files
    del         = require('del'),                    // Deletes files / folders
    duration    = require('gulp-duration'),          // Time aspects of your gulp process
    gutil       = require('gulp-util'),              // Provides gulp utilities, including logging and beep
    livereload  = require('gulp-livereload'),        // Livereload support for the browser
    merge       = require('utils-merge'),            // Object merge tool
    notify      = require('gulp-notify'),            // Provides notification to both the console and Growel
    rename      = require('gulp-rename'),            // Rename sources
    resolutions = require('browserify-resolutions'), // Resolve duplicate dependencies
    sass        = require('gulp-sass'),              // Compile .scss CSS files
    sass_glob   = require('gulp-sass-glob'),         // SCSS with wildcard @imports
    source      = require('vinyl-source-stream'),    // Vinyl stream support
    streamify   = require('gulp-streamify'),         // Creates gulp streams
    uglify      = require('gulp-uglify'),            // Minifies JavaScript
    watchify    = require('watchify')                // Watchify for source changes
;

var package_json = require('./package.json');

var paths = {
  develop_folder:  './build/develop',
  release_folder:  './build/release',

  app_js_develop:  'app/Application.jsx',
  app_js_release:  'js/application.js',

  app_css_develop: 'styles/Application.scss',
  app_css_release: 'styles/application.css',

  pkg_js_develop:  'app/Packages.jsx',
  pkg_js_release:  'js/dependencies.js',

  pkg_css_develop: 'styles/Dependencies.scss',
  pkg_css_release: 'styles/dependencies.css'
};

function mapError(err) {
  if (err.filename) { // General error
    gutil.log(chalk.red(err.name)
      + ': ' + chalk.yellow(err.filename.replace(__dirname, ''))
      + ': ' + 'Line ' + chalk.magenta(err.lineNumber || err.line)
      + ', ' + 'Column ' + chalk.magenta(err.columnNumber || err.column)
      + ': ' + chalk.blue(err.description || err.message)
    );
  } else { // Browserify error
    gutil.log(chalk.red(err.name)
      + ': ' + chalk.yellow(err.message)
    );
  }
}

var options = {
  application: {
    js:  merge(watchify.args, { debug: true  }),
    css: merge(watchify.args, { debug: true  })
  },
  dependencies: {
    js:  merge(watchify.args, { debug: false }),
    css: merge(watchify.args, { debug: false })
  }
}

var DEPENDENCIES = Object.keys(package_json.dependencies).map(function(dependency) {
  return dependency;
});

var bundlers = {
  'js:Application': browserify(paths.app_js_develop, options.application.js)
    .plugin(function(bundle) {
      // remove all dependencies from the Application.js build
      DEPENDENCIES.forEach(function(tool) {
        bundle.external(tool);
      });
    })
    .transform(babelify, { presets: ['es2015', 'react']})
, 'js:Dependencies': browserify(paths.pkg_js_develop, options.dependencies.js)
    .plugin(function(bundle) {
      // add all dependencies to the dependencies.js build
      DEPENDENCIES.forEach(function(tool) {
        bundle.require(tool);
      })
    })
};

var build_js = function(bundler, infile, outfile) {
  var bundleTimer = duration(outfile + ' bundle time');
  return bundler
    .plugin(resolutions, '*')
    .bundle()
    .on('error', mapError)     // report all errors to console
    .pipe(source(infile))      // start with main .jsx file
    .pipe(buffer())            // convert to a gulp pipeline
    .pipe(rename(outfile))     // rename the output file
    .pipe(gulp.dest(paths.develop_folder))
    .pipe(notify({ message: 'DEVELOP: <%= file.relative %> created.' }))
    .pipe(streamify(uglify())) // uglify/minify the output
    .pipe(gulp.dest(paths.release_folder))
    .pipe(notify({ message: 'RELEASE: <%= file.relative %> created.' }))
    .pipe(bundleTimer)         // output build timing
    .pipe(livereload())        // reload the view in the browser
};
var build_sass = function(infile, outfile) {
  var bundleTimer = duration(outfile + ' bundle time');
  return gulp.src(infile)
    .pipe(sass_glob())
    .pipe(sass().on('error', sass.logError))
    .pipe(rename(outfile))
    .pipe(gulp.dest(paths.develop_folder))
    .pipe(notify({ message: 'DEVELOP: <%= file.relative %> created.' }))
    .pipe(cssmin())
    .pipe(gulp.dest(paths.release_folder))
    .pipe(notify({ message: 'RELEASE: <%= file.relative %> created.' }))
    .pipe(bundleTimer)         // output build timing
    .pipe(livereload())        // reload the view in the browser
  ;
};

// Build file outputs
bundlers['js:Application'].run = build_js.bind(
  this, bundlers['js:Application'], paths.app_js_develop, paths.app_js_release
);
bundlers['js:Dependencies'].run = build_js.bind(
  this, bundlers['js:Dependencies'], paths.pkg_js_develop, paths.pkg_js_release
);

gulp.task('clean', function() {
  return del(['build/**/*', 'build']);
});

gulp.task('build', ['build_js', 'build_app_css', 'build_pkg_css']);
gulp.task('build_js', function() {
  for (var name in bundlers) {
    if (typeof bundlers[name].run != 'function') continue;

    bundlers[name].run();
  }
});
gulp.task('build_app_css', function() {
  return build_sass(paths.app_css_develop, paths.app_css_release);
});
gulp.task('build_pkg_css', function() {
  return build_sass(paths.pkg_css_develop, paths.pkg_css_release);
});

gulp.task('listen', function() {
  livereload.listen(); // start livereload server

  for (var name in bundlers) {
    var bundler = bundlers[name]
      .plugin(watchify, { ignoreWatch: ['**/node_modules/**', '**/bower_components/**'] });

    if (typeof bundler.run != 'function') continue;

    bundler.on('update', function() {
      bundler.run(); // Re-run bundle on source updates
    })
  }
  gulp.watch(['styles/**/*.{css,scss}', '!styles/Dependencies.scss'], ['build_app_css']);
  gulp.watch('styles/Dependencies.scss', ['build_pkg_css'])
});

gulp.task('default', ['clean', 'build', 'listen']);<commit_msg>ta - reorganized Gulpfile<commit_after>'use strict';
var gulp        = require('gulp'),                   // Base gulp package
    babelify    = require('babelify'),               // Used to convert ES6 & JSX to ES5
    browserify  = require('browserify'),             // Providers "require" support, CommonJS
    buffer      = require('vinyl-buffer'),           // Vinyl stream support
    chalk       = require('chalk'),                  // Allows for coloring for logging
    cssmin      = require('gulp-cssmin'),            // Minifies CSS files
    del         = require('del'),                    // Deletes files / folders
    duration    = require('gulp-duration'),          // Time aspects of your gulp process
    gutil       = require('gulp-util'),              // Provides gulp utilities, including logging and beep
    livereload  = require('gulp-livereload'),        // Livereload support for the browser
    merge       = require('utils-merge'),            // Object merge tool
    notify      = require('gulp-notify'),            // Provides notification to both the console and Growel
    rename      = require('gulp-rename'),            // Rename sources
    resolutions = require('browserify-resolutions'), // Resolve duplicate dependencies
    sass        = require('gulp-sass'),              // Compile .scss CSS files
    sass_glob   = require('gulp-sass-glob'),         // SCSS with wildcard @imports
    source      = require('vinyl-source-stream'),    // Vinyl stream support
    streamify   = require('gulp-streamify'),         // Creates gulp streams
    uglify      = require('gulp-uglify'),            // Minifies JavaScript
    watchify    = require('watchify')                // Watchify for source changes
;
var DEPENDENCIES = Object.keys(require('./package.json').dependencies)
  .map(function(dependency) {
    return dependency;
  }
);
var options = {
  application: {
    js:  merge(watchify.args, { debug: true  }),
    css: merge(watchify.args, { debug: true  })
  },
  dependencies: {
    js:  merge(watchify.args, { debug: false }),
    css: merge(watchify.args, { debug: false })
  }
}
var paths = {
  develop_folder:  './build/develop',
  release_folder:  './build/release',

  app_js_develop:  'app/Application.jsx',
  app_js_release:  'js/application.js',

  app_css_develop: 'styles/Application.scss',
  app_css_release: 'styles/application.css',

  pkg_js_develop:  'app/Packages.jsx',
  pkg_js_release:  'js/dependencies.js',

  pkg_css_develop: 'styles/Dependencies.scss',
  pkg_css_release: 'styles/dependencies.css'
};

var build_js = function(bundler, infile, outfile) {
  var bundleTimer = duration(outfile + ' bundle time');
  return bundler
    .plugin(resolutions, '*')
    .bundle()
    .on('error', mapError)     // report all errors to console
    .pipe(source(infile))      // start with main .jsx file
    .pipe(buffer())            // convert to a gulp pipeline
    .pipe(rename(outfile))     // rename the output file
    .pipe(gulp.dest(paths.develop_folder))
    .pipe(notify({ message: 'DEVELOP: <%= file.relative %> created.' }))
    .pipe(streamify(uglify())) // uglify/minify the output
    .pipe(gulp.dest(paths.release_folder))
    .pipe(notify({ message: 'RELEASE: <%= file.relative %> created.' }))
    .pipe(bundleTimer)         // output build timing
    .pipe(livereload())        // reload the view in the browser
};
var build_sass = function(infile, outfile) {
  var bundleTimer = duration(outfile + ' bundle time');
  return gulp.src(infile)
    .pipe(sass_glob())
    .pipe(sass().on('error', sass.logError))
    .pipe(rename(outfile))
    .pipe(gulp.dest(paths.develop_folder))
    .pipe(notify({ message: 'DEVELOP: <%= file.relative %> created.' }))
    .pipe(cssmin())
    .pipe(gulp.dest(paths.release_folder))
    .pipe(notify({ message: 'RELEASE: <%= file.relative %> created.' }))
    .pipe(bundleTimer)         // output build timing
    .pipe(livereload())        // reload the view in the browser
    ;
};

var bundlers = {
  'js:Application': browserify(paths.app_js_develop, options.application.js)
    .plugin(function(bundle) {
      // remove all dependencies from the Application.js build
      DEPENDENCIES.forEach(function(tool) {
        bundle.external(tool);
      });
    })
    .transform(babelify, { presets: ['es2015', 'react']})
, 'js:Dependencies': browserify(paths.pkg_js_develop, options.dependencies.js)
    .plugin(function(bundle) {
      // add all dependencies to the dependencies.js build
      DEPENDENCIES.forEach(function(tool) {
        bundle.require(tool);
      })
    })
};
bundlers['js:Application'].run = build_js.bind(
  this, bundlers['js:Application'], paths.app_js_develop, paths.app_js_release
);
bundlers['js:Dependencies'].run = build_js.bind(
  this, bundlers['js:Dependencies'], paths.pkg_js_develop, paths.pkg_js_release
);

gulp.task('build', ['build_js', 'build_app_css', 'build_pkg_css']);
gulp.task('build_js', function() {
  for (var name in bundlers) {
    if (typeof bundlers[name].run != 'function') continue;

    bundlers[name].run();
  }
});
gulp.task('build_app_css', function() {
  return build_sass(paths.app_css_develop, paths.app_css_release);
});
gulp.task('build_pkg_css', function() {
  return build_sass(paths.pkg_css_develop, paths.pkg_css_release);
});

gulp.task('clean', function() {
  return del(['build/**/*', 'build']);
});
gulp.task('listen', function() {
  livereload.listen(); // start livereload server

  for (var name in bundlers) {
    var bundler = bundlers[name]
      .plugin(watchify, { ignoreWatch: ['**/node_modules/**', '**/bower_components/**'] });

    if (typeof bundler.run != 'function') continue;

    bundler.on('update', function() {
      bundler.run(); // Re-run bundle on source updates
    })
  }
  gulp.watch(['styles/**/*.{css,scss}', '!styles/Dependencies.scss'], ['build_app_css']);
  gulp.watch(['styles/Dependencies.scss'], ['build_pkg_css']);
});

gulp.task('default', ['clean', 'build', 'listen']);

function mapError(err) {
  if (err.filename) { // General error
    gutil.log(chalk.red(err.name)
      + ': ' + chalk.yellow(err.filename.replace(__dirname, ''))
      + ': ' + 'Line ' + chalk.magenta(err.lineNumber || err.line)
      + ', ' + 'Column ' + chalk.magenta(err.columnNumber || err.column)
      + ': ' + chalk.blue(err.description || err.message)
    );
  } else { // Browserify error
    gutil.log(chalk.red(err.name)
      + ': ' + chalk.yellow(err.message)
    );
  }
}
<|endoftext|>


<commit_before>if(!tc){ var tc = {}; }
if(!tc.gam){ tc.gam = {}; }

tc.gam.project = function(options){
	var me, hash_onload;
	me = this;
	tc.util.log("tc.gam.project");

	this.options = tc.jQ.extend({

	},options);

	this.dom = this.options.dom;
	this.event_data = { project:this };
	this.data = this.options.data;
	this.widget = new tc.gam.widget(null,this);

	hash_onload = window.location.hash;

	this.components = {
		infopane:new tc.gam.project_widgets.infopane(this,this.dom.find('.box.mission'),{widget:this.widget},{app:options.app}),
		resources:new tc.gam.project_widgets.resources(this,this.dom.find('.box.resources'),{widget:this.widget},{app:options.app}),
		related_resources:new tc.gam.project_widgets.related_resources(this,this.dom.find('.box.related-resources'),{widget:this.widget},{app:options.app}),
		add_link:new tc.gam.project_widgets.add_link(this,this.dom.find('.box.add-link'),{widget:this.widget},{app:options.app}),
		goals_main:new tc.gam.project_widgets.goals_main(this,this.dom.find('.box.goals-main'),{widget:this.widget},{app:options.app}),
		goals_add:new tc.gam.project_widgets.goals_add(this,this.dom.find('.box.goals-add'),{widget:this.widget},{app:options.app}),
		conversation:new tc.gam.project_widgets.conversation(this,this.dom.find('.box.conversation'),{widget:this.widget},{app:options.app}),
		members:new tc.gam.project_widgets.members(this,this.dom.find('.box.members'),{widget:this.widget},{app:options.app})
	};

	if (tc.gam.project_widgets.fresh_ideas) {
		this.components.related_ideas = new tc.gam.project_widgets.fresh_ideas(this,this.dom.find('.box.fresh-ideas'),{widget:this.widget},{app:options.app});
	}

	if(tc.gam.project_widgets.goals_stack){
		this.components.goals_stack = new tc.gam.project_widgets.goals_stack(this,this.dom.find('.box.goals-stack-holder'),{widget:this.widget},{app:options.app});
	}

	// return project page to initial state
	function go_home(e) {
		if(e){
			e.data.project.components.goals_main.show(false);
			e.data.project.components.conversation.show(false);

			if (tc.gam.project_widgets.goals_stack) {
				e.data.project.components.goals_stack.hide(false);
			}
			e.data.project.components.goals_add.hide(false);
			e.data.project.components.add_link.hide(false);
			e.data.project.components.related_resources.hide(false);
		} else {
			this.components.goals_main.show(false);
			this.components.conversation.show(false);
		}
	}

	this.handlers = {
		widget_show:function(e,d){
			tc.util.dump(d.name);
			switch(d.name){
				case 'members':
					e.data.project.components.goals_main.hide(false);
					if (tc.gam.project_widgets.goals_stack) {
						e.data.project.components.goals_stack.hide(false);
					}
					e.data.project.components.goals_add.hide(false);
					e.data.project.components.conversation.hide(false);
					e.data.project.components.add_link.hide(false);
					break;
				case 'goals_add':
					e.data.project.components.goals_main.hide(false);
					break;
				case 'goals_stack':
					e.data.project.components.goals_add.hide(false);
					e.data.project.components.goals_main.hide(false);
					break;
				case 'related_resources':
					e.data.project.components.goals_main.hide(false);
					if (tc.gam.project_widgets.goals_stack) {
						e.data.project.components.goals_stack.hide(false);
					}
					e.data.project.components.members.hide(false);
					e.data.project.components.conversation.hide(false);
					e.data.project.components.add_link.hide(false);
					break;
				case 'add_link':
					e.data.project.components.goals_main.hide(false);
					if (tc.gam.project_widgets.goals_stack) {
						e.data.project.components.goals_stack.hide(false);
					}
					e.data.project.components.members.hide(false);
					e.data.project.components.conversation.hide(false);
					e.data.project.components.related_resources.hide(false);
					break;
			}
		},
		widget_hide:function(e,d){
			tc.util.dump('project.widget_hide');
			switch(d.name){
				case 'members':
				case 'goals_add':
				case 'goals_stack':
				case 'related_resources':
				case 'add_link':
					go_home(e);
					break;
			}
		},
		hashchange:function(e){
			tc.util.log('tc.project.handlers.hashchange');
			var hash;
			hash = window.location.hash.substring(1,window.location.hash.length);
			if(hash == 'project-home'){
				e.preventDefault();
				go_home(e);
				return;
			}
			switch(hash.split(',')[0]){
				case 'show':
					e.preventDefault();
					tc.util.dump(hash.split(',')[1]);
					if(e.data.project.components[hash.split(',')[1]]){
						e.data.project.components[hash.split(',')[1]].show();
					}
					break;
				case 'hide':
					e.preventDefault();
					if(e.data.project.components[hash.split(',')[1]]){
						e.data.project.components[hash.split(',')[1]].hide();
					}
					break;
			}
		},
		idea_remove: function(e, d) {
			if (e.data.project.components.related_ideas) {
				e.data.project.components.related_ideas.remove_idea(d.id);
			}
			e.data.project.components.members.remove_idea(d.id);
		}
	};

	tc.jQ(window).bind('hashchange',this.event_data,this.handlers.hashchange);
	this.dom.bind('project-widget-show',this.event_data,this.handlers.widget_show);
	this.dom.bind('project-widget-hide',this.event_data,this.handlers.widget_hide);
	this.dom.bind('project-idea-remove', this.event_data, this.handlers.idea_remove);

	window.location.hash = hash_onload;
	tc.jQ(window).trigger('hashchange');
};

tc.gam.widget = function(inheritor,project){
	if(!inheritor){ return; }

	inheritor.show = function(propagate){
		if(inheritor.dom){ inheritor.dom.show(); }
		if(propagate !== false){
			project.dom.trigger('project-widget-show',{name:inheritor.options.name});
		}
	};

	inheritor.hide = function(propagate){
		if(inheritor.dom){ inheritor.dom.hide(); }
		if(propagate !== false){
			project.dom.trigger('project-widget-hide',{name:inheritor.options.name});
		}
	};

	return inheritor;
};

if(!tc.gam.project_widgets){
	tc.gam.project_widgets = {};
}
<commit_msg>should fix #1936 - "Members" Portion of Project Page Gets Stuck There- Live Site<commit_after>if(!tc){ var tc = {}; }
if(!tc.gam){ tc.gam = {}; }

tc.gam.project = function(options){
	var me, hash_onload;
	me = this;
	tc.util.log("tc.gam.project");

	this.options = tc.jQ.extend({

	},options);

	this.dom = this.options.dom;
	this.event_data = { project:this };
	this.data = this.options.data;
	this.widget = new tc.gam.widget(null,this);

	hash_onload = window.location.hash;

	this.components = {
		infopane:new tc.gam.project_widgets.infopane(this,this.dom.find('.box.mission'),{widget:this.widget},{app:options.app}),
		resources:new tc.gam.project_widgets.resources(this,this.dom.find('.box.resources'),{widget:this.widget},{app:options.app}),
		related_resources:new tc.gam.project_widgets.related_resources(this,this.dom.find('.box.related-resources'),{widget:this.widget},{app:options.app}),
		add_link:new tc.gam.project_widgets.add_link(this,this.dom.find('.box.add-link'),{widget:this.widget},{app:options.app}),
		goals_main:new tc.gam.project_widgets.goals_main(this,this.dom.find('.box.goals-main'),{widget:this.widget},{app:options.app}),
		goals_add:new tc.gam.project_widgets.goals_add(this,this.dom.find('.box.goals-add'),{widget:this.widget},{app:options.app}),
		conversation:new tc.gam.project_widgets.conversation(this,this.dom.find('.box.conversation'),{widget:this.widget},{app:options.app}),
		members:new tc.gam.project_widgets.members(this,this.dom.find('.box.members'),{widget:this.widget},{app:options.app})
	};

	if (tc.gam.project_widgets.fresh_ideas) {
		this.components.related_ideas = new tc.gam.project_widgets.fresh_ideas(this,this.dom.find('.box.fresh-ideas'),{widget:this.widget},{app:options.app});
	}

	if(tc.gam.project_widgets.goals_stack){
		this.components.goals_stack = new tc.gam.project_widgets.goals_stack(this,this.dom.find('.box.goals-stack-holder'),{widget:this.widget},{app:options.app});
	}

	// return project page to initial state
	function go_home(e) {
		if(e){
			e.data.project.components.goals_main.show(false);
			e.data.project.components.conversation.show(false);

			if (tc.gam.project_widgets.goals_stack) {
				e.data.project.components.goals_stack.hide(false);
			}
			if(tc.gam.project_widgets.members){
				e.data.project.components.members.hide(false);
			}
			e.data.project.components.goals_add.hide(false);
			e.data.project.components.add_link.hide(false);
			e.data.project.components.related_resources.hide(false);
		} else {
			this.components.goals_main.show(false);
			this.components.conversation.show(false);
		}
	}

	this.handlers = {
		widget_show:function(e,d){
			tc.util.dump(d.name);
			switch(d.name){
				case 'members':
					e.data.project.components.goals_main.hide(false);
					if (tc.gam.project_widgets.goals_stack) {
						e.data.project.components.goals_stack.hide(false);
					}
					e.data.project.components.goals_add.hide(false);
					e.data.project.components.conversation.hide(false);
					e.data.project.components.add_link.hide(false);
					break;
				case 'goals_add':
					e.data.project.components.goals_main.hide(false);
					break;
				case 'goals_stack':
					e.data.project.components.goals_add.hide(false);
					e.data.project.components.goals_main.hide(false);
					break;
				case 'related_resources':
					e.data.project.components.goals_main.hide(false);
					if (tc.gam.project_widgets.goals_stack) {
						e.data.project.components.goals_stack.hide(false);
					}
					e.data.project.components.members.hide(false);
					e.data.project.components.conversation.hide(false);
					e.data.project.components.add_link.hide(false);
					break;
				case 'add_link':
					e.data.project.components.goals_main.hide(false);
					if (tc.gam.project_widgets.goals_stack) {
						e.data.project.components.goals_stack.hide(false);
					}
					e.data.project.components.members.hide(false);
					e.data.project.components.conversation.hide(false);
					e.data.project.components.related_resources.hide(false);
					break;
			}
		},
		widget_hide:function(e,d){
			tc.util.dump('project.widget_hide');
			switch(d.name){
				case 'members':
				case 'goals_add':
				case 'goals_stack':
				case 'related_resources':
				case 'add_link':
					go_home(e);
					break;
			}
		},
		hashchange:function(e){
			tc.util.log('tc.project.handlers.hashchange');
			var hash;
			hash = window.location.hash.substring(1,window.location.hash.length);
			if(hash == 'project-home'){
				e.preventDefault();
				go_home(e);
				return;
			}
			switch(hash.split(',')[0]){
				case 'show':
					e.preventDefault();
					tc.util.dump(hash.split(',')[1]);
					if(e.data.project.components[hash.split(',')[1]]){
						e.data.project.components[hash.split(',')[1]].show();
					}
					break;
				case 'hide':
					e.preventDefault();
					if(e.data.project.components[hash.split(',')[1]]){
						e.data.project.components[hash.split(',')[1]].hide();
					}
					break;
			}
		},
		idea_remove: function(e, d) {
			if (e.data.project.components.related_ideas) {
				e.data.project.components.related_ideas.remove_idea(d.id);
			}
			e.data.project.components.members.remove_idea(d.id);
		}
	};

	tc.jQ(window).bind('hashchange',this.event_data,this.handlers.hashchange);
	this.dom.bind('project-widget-show',this.event_data,this.handlers.widget_show);
	this.dom.bind('project-widget-hide',this.event_data,this.handlers.widget_hide);
	this.dom.bind('project-idea-remove', this.event_data, this.handlers.idea_remove);

	window.location.hash = hash_onload;
	tc.jQ(window).trigger('hashchange');
};

tc.gam.widget = function(inheritor,project){
	if(!inheritor){ return; }

	inheritor.show = function(propagate){
		if(inheritor.dom){ inheritor.dom.show(); }
		if(propagate !== false){
			project.dom.trigger('project-widget-show',{name:inheritor.options.name});
		}
	};

	inheritor.hide = function(propagate){
		if(inheritor.dom){ inheritor.dom.hide(); }
		if(propagate !== false){
			project.dom.trigger('project-widget-hide',{name:inheritor.options.name});
		}
	};

	return inheritor;
};

if(!tc.gam.project_widgets){
	tc.gam.project_widgets = {};
}
<|endoftext|>


<commit_before>( function( M, $ ) {
	var api = M.require( 'api' ),
		popup = M.require( 'toast' ),
		schema = M.require( 'loggingSchemas/MobileWebClickTracking' );

	function thankUser( name, revision, gender ) {
		var d = $.Deferred();
		api.getToken( 'edit' ).done( function( token ) {
			api.post( {
				'action' : 'thank',
				'rev' : revision,
				'source' : 'mobilediff',
				'token' : token
			} )
			.done( function() {
				popup.show( mw.msg( 'thanks-thanked-notice', name, gender ) );
				d.resolve();
			} )
			.fail( function( errorCode ) {
				switch( errorCode ) {
					case 'invalidrevision':
						popup.show( mw.msg( 'thanks-error-invalidrevision' ) );
						break;
					case 'ratelimited':
						popup.show( mw.msg( 'thanks-error-ratelimited', gender ) );
						break;
					default:
						popup.show( mw.msg( 'thanks-error-undefined' ) );
				}
				d.reject();
			} );
		} );
		return d;
	}

	/**
	 * Create a thank button for a given edit
	 *
	 * @param name String The username of the user who made the edit
	 * @param rev String The revision the user created
	 * @param gender String The gender of the user who made the edit
	 */
	function createThankLink( name, rev, gender ) {
		var thankImg = mw.config.get( 'wgExtensionAssetsPath' ) + '/Thanks/WhiteSmiley.png',
			thankImgTag = '',
			$thankBtn;
		// Don't make thank button for self
		if ( name !== mw.config.get( 'wgUserName' ) ) {
			// See if user has already been thanked for this edit
			if ( mw.config.get( 'wgThanksAlreadySent' ) ) {
				$thankBtn = $( '<button class="mw-mf-action-button mw-ui-button mw-ui-constructive thanked">' )
					.attr( 'disabled', true )
					.html( thankImgTag + mw.message( 'thanks-button-thanked', mw.user ).escaped() );
			} else {
				$thankBtn = $( '<button class="mw-mf-action-button mw-ui-button mw-ui-constructive">' )
					.html( thankImgTag + mw.message( 'thanks-button-thank', mw.user ).escaped()
					)
					.on( 'click', function() {
						var $this = $( this );
						schema.log( 'diff-thank', name );
						if ( !$this.hasClass( 'thanked' ) ) {
							thankUser( name, rev, gender  ).done( function() {
								$this.addClass( 'thanked' ).attr( 'disabled', true )
									.html( thankImgTag + mw.message( 'thanks-button-thanked', mw.user ).escaped() );
							} );
						}
					} );
			}
			return $thankBtn;
		}
	}

	$( function() {
		var $user = $( '.mw-mf-user' ),
			username = $user.data( 'user-name' ),
			rev = $user.data( 'revision-id' ),
			gender = $user.data( 'user-gender' ),
			$thankBtn;

		if ( !$user.hasClass( 'mw-mf-anon' ) ) {
			$thankBtn = createThankLink( username, rev, gender );
			if ( $thankBtn ) {
				$thankBtn.prependTo( '#mw-mf-userinfo' );
			}
		}
	} );
} )( mw.mobileFrontend, jQuery );
<commit_msg>Match changed MobileWebClickingSchema<commit_after>( function( M, $ ) {
	var api = M.require( 'api' ),
		popup = M.require( 'toast' ),
		schema = M.require( 'loggingSchemas/MobileWebClickTracking' );

	function thankUser( name, revision, gender ) {
		var d = $.Deferred();
		api.getToken( 'edit' ).done( function( token ) {
			api.post( {
				'action' : 'thank',
				'rev' : revision,
				'source' : 'mobilediff',
				'token' : token
			} )
			.done( function() {
				popup.show( mw.msg( 'thanks-thanked-notice', name, gender ) );
				d.resolve();
			} )
			.fail( function( errorCode ) {
				switch( errorCode ) {
					case 'invalidrevision':
						popup.show( mw.msg( 'thanks-error-invalidrevision' ) );
						break;
					case 'ratelimited':
						popup.show( mw.msg( 'thanks-error-ratelimited', gender ) );
						break;
					default:
						popup.show( mw.msg( 'thanks-error-undefined' ) );
				}
				d.reject();
			} );
		} );
		return d;
	}

	/**
	 * Create a thank button for a given edit
	 *
	 * @param name String The username of the user who made the edit
	 * @param rev String The revision the user created
	 * @param gender String The gender of the user who made the edit
	 */
	function createThankLink( name, rev, gender ) {
		var thankImg = mw.config.get( 'wgExtensionAssetsPath' ) + '/Thanks/WhiteSmiley.png',
			thankImgTag = '',
			$thankBtn;
		// Don't make thank button for self
		if ( name !== mw.config.get( 'wgUserName' ) ) {
			// See if user has already been thanked for this edit
			if ( mw.config.get( 'wgThanksAlreadySent' ) ) {
				$thankBtn = $( '<button class="mw-mf-action-button mw-ui-button mw-ui-constructive thanked">' )
					.attr( 'disabled', true )
					.html( thankImgTag + mw.message( 'thanks-button-thanked', mw.user ).escaped() );
			} else {
				$thankBtn = $( '<button class="mw-mf-action-button mw-ui-button mw-ui-constructive">' )
					.html( thankImgTag + mw.message( 'thanks-button-thank', mw.user ).escaped()
					)
					.on( 'click', function() {
						var $this = $( this );
						schema.log( 'Diff', 'diff-thank', name );
						if ( !$this.hasClass( 'thanked' ) ) {
							thankUser( name, rev, gender  ).done( function() {
								$this.addClass( 'thanked' ).attr( 'disabled', true )
									.html( thankImgTag + mw.message( 'thanks-button-thanked', mw.user ).escaped() );
							} );
						}
					} );
			}
			return $thankBtn;
		}
	}

	$( function() {
		var $user = $( '.mw-mf-user' ),
			username = $user.data( 'user-name' ),
			rev = $user.data( 'revision-id' ),
			gender = $user.data( 'user-gender' ),
			$thankBtn;

		if ( !$user.hasClass( 'mw-mf-anon' ) ) {
			$thankBtn = createThankLink( username, rev, gender );
			if ( $thankBtn ) {
				$thankBtn.prependTo( '#mw-mf-userinfo' );
			}
		}
	} );
} )( mw.mobileFrontend, jQuery );
<|endoftext|>


<commit_before>export default /* glsl */`
#ifdef USE_TRANSMISSION

	float transmissionFactor = transmission;
	float thicknessFactor = thickness;

	#ifdef USE_TRANSMISSIONMAP

		transmissionFactor *= texture2D( transmissionMap, vUv ).r;

	#endif

	#ifdef USE_THICKNESSMAP

		thicknessFactor *= texture2D( thicknessMap, vUv ).g;

	#endif

	vec3 pos = vWorldPosition.xyz / vWorldPosition.w;
	vec3 v = normalize( cameraPosition - pos );
	float ior = ( 1.0 + 0.4 * reflectivity ) / ( 1.0 - 0.4 * reflectivity );

	vec3 transmission = transmissionFactor * getIBLVolumeRefraction(
		normal, v, roughnessFactor, material.diffuseColor, totalSpecular,
		pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,
		attenuationColor, attenuationDistance );

	totalDiffuse = mix( totalDiffuse, transmission, transmissionFactor );
#endif
`;
<commit_msg>ShaderChunk: Fixed overblown color in transmission_fragment (#22125)<commit_after>export default /* glsl */`
#ifdef USE_TRANSMISSION

	float transmissionFactor = transmission;
	float thicknessFactor = thickness;

	#ifdef USE_TRANSMISSIONMAP

		transmissionFactor *= texture2D( transmissionMap, vUv ).r;

	#endif

	#ifdef USE_THICKNESSMAP

		thicknessFactor *= texture2D( thicknessMap, vUv ).g;

	#endif

	vec3 pos = vWorldPosition.xyz / vWorldPosition.w;
	vec3 v = normalize( cameraPosition - pos );
	float ior = ( 1.0 + 0.4 * reflectivity ) / ( 1.0 - 0.4 * reflectivity );

	vec3 transmission = transmissionFactor * getIBLVolumeRefraction(
		normal, v, roughnessFactor, material.diffuseColor, material.specularColor,
		pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,
		attenuationColor, attenuationDistance );

	totalDiffuse = mix( totalDiffuse, transmission, transmissionFactor );
#endif
`;
<|endoftext|>


<commit_before>var redis      = require('redis');
var SerialPort = require('serialport');

var subscriber = redis.createClient(6379, 'localhost');
subscriber.subscribe('/dbc/webui2uart');
subscriber.on("message", function(channel, message) {
  console.log('message=<',message,'>');
});

var serialPort = new SerialPort("/dev/tty.usbmodem1411", {
 baudrate: 112500
});

serialPort.on("open", function () {
  console.log('open');
 });

serialPort.on('data', function(data) {
  console.log('received data =<',data,'>');
});

serialPort.on('error', function(err) {
  console.log('err =<',err,'>');
});
<commit_msg>Update app.js<commit_after>var redis      = require('redis');
var SerialPort = require('serialport');

var subscriber = redis.createClient(6379, 'localhost');
subscriber.subscribe('/dbc/webui2uart');
subscriber.on("message", function(channel, message) {
  console.log('message=<',message,'>');
});

var serialPort = new SerialPort("/dev/ttyS0", {
 baudrate: 112500
});

serialPort.on("open", function () {
  console.log('open');
 });

serialPort.on('data', function(data) {
  console.log('received data =<',data,'>');
});

serialPort.on('error', function(err) {
  console.log('err =<',err,'>');
});
<|endoftext|>