<commit_before>define([
    'fossil/core',
    'jquery',
    'underscore',
    'backbone',
    'fossil/mixins/events',
    'fossil/mixins/layoutable',
    'fossil/mixins/elementable',
    'fossil/mixins/fragmentable'
], function (Fossil, $, _, Backbone) {

    var messages = {
        unknown_module: _.template("Unknown module at \"<%- path %>\".")
    };

    var Application = Fossil.Application = function (options) {
        this.options = options || {};
        this.registerEvents();
        initFactories(this);
        // init fragmentable
        this.initFragmentable();
        initModules(this);
        this.initialize.apply(this, arguments);
    };

    _.extend(Application.prototype,
        Fossil.Mixins.Events,
        Fossil.Mixins.Elementable,
        Fossil.Mixins.Layoutable,
        Fossil.Mixins.Fragmentable, {
            // default selector for application to append to.
            selector: 'body',
            currentModule: null,
            template: '

',
            initialize: function () {
            },

            // connect an module at given subpath
            connect: function (path, module) {
                if (_.isFunction(module)) {
                    module = new module(this, path);
                }
                this.modules[path] = module;
                this.trigger('module:connect', module, path, this);

                return this;
            },
            // retreive an module from it's path
            // or returns all modules if no path is given.
            getModule: function (path) {
                if (typeof path === "undefined") {
                    return this.modules;
                }
                if (this.modules[path]) {
                    return this.modules[path];
                }

                throw new Error(messages.unknown_module({path: path}));
            },

            // use a factory
            use: function (id, factory) {
                if (_.isFunction(factory)) {
                    factory = new factory();
                }
                // suspend previously registered factory with this name
                if (this.factories[id]) {
                    this.factories[id].suspendApplication(this, id);
                }
                factory.activateApplication(this, id);
                this.factories[id] = factory;
                this.trigger('factory:use', factory, id, this);

                return this;
            },

            start: function () {
                this.trigger('setup', this);
                this.setElement($(this.selector));
                this.renderLayout();
                this.renderFragments();
                this.trigger('start', this);
            },
            switchModule: function (module) {
                var moduleChange = (this.currentModule !== module);
                if (moduleChange && this.currentModule) {
                    this.trigger('module:teardown', this.currentModule);
                    this.currentModule.detachElement();
                }
                if (moduleChange) {
                    var $el = this.$('[data-fossil-placeholder=module]');
                    this.trigger('module:change', this.currentModule, module);
                    module.deferred();
                    module.setElement($el);
                    module.then(_.bind(function moduleReady () {
                        this.trigger('module:setup', module);
                        this.currentModule = module;
                    }, this));
                    module.resolve();
                }
            }
    });

    function initFactories (application) {
        var factories = _.extend(
            {},
            application.factories || {},
            application.options.factories || {}
        );
        application.factories = {};
        _.each(factories, function (factory, id) {
            application.use(id, factory);
        });
    }

    function initModules (application) {
        var apps = _.extend(
            {},
            application.modules || {},
            application.options.modules || {}
        );
        application.modules = {};
        _.each(apps, function (module, path) {
            application.connect(path, module);
        });
    }

    Application.extend = Backbone.Model.extend;

    return Application;
});
<commit_msg>Application is Deferrable.<commit_after>define([
    'fossil/core',
    'jquery',
    'underscore',
    'backbone',
    'fossil/mixins/events',
    'fossil/mixins/layoutable',
    'fossil/mixins/elementable',
    'fossil/mixins/fragmentable',
    'fossil/mixins/deferrable'
], function (Fossil, $, _, Backbone) {

    var messages = {
        unknown_module: _.template("Unknown module at \"<%- path %>\".")
    };

    var Application = Fossil.Application = function (options) {
        this.options = options || {};
        this.registerEvents();
        initFactories(this);
        // init fragmentable
        this.initFragmentable();
        initModules(this);
        this.initialize.apply(this, arguments);
    };

    _.extend(Application.prototype,
        Fossil.Mixins.Events,
        Fossil.Mixins.Elementable,
        Fossil.Mixins.Layoutable,
        Fossil.Mixins.Fragmentable,
        Fossil.Mixins.Deferrable, {
            // default selector for application to append to.
            selector: 'body',
            currentModule: null,
            template: '

',
            initialize: function () {
            },

            // connect an module at given subpath
            connect: function (path, module) {
                if (_.isFunction(module)) {
                    module = new module(this, path);
                }
                this.modules[path] = module;
                this.trigger('module:connect', module, path, this);

                return this;
            },
            // retreive an module from it's path
            // or returns all modules if no path is given.
            getModule: function (path) {
                if (typeof path === "undefined") {
                    return this.modules;
                }
                if (this.modules[path]) {
                    return this.modules[path];
                }

                throw new Error(messages.unknown_module({path: path}));
            },

            // use a factory
            use: function (id, factory) {
                if (_.isFunction(factory)) {
                    factory = new factory();
                }
                // suspend previously registered factory with this name
                if (this.factories[id]) {
                    this.factories[id].suspendApplication(this, id);
                }
                factory.activateApplication(this, id);
                this.factories[id] = factory;
                this.trigger('factory:use', factory, id, this);

                return this;
            },

            start: function () {
                this.trigger('setup', this);
                this.setElement($(this.selector));
                this.renderLayout();
                this.renderFragments();
                this.trigger('start', this);
            },
            switchModule: function (module) {
                var moduleChange = (this.currentModule !== module);
                if (moduleChange && this.currentModule) {
                    this.trigger('module:teardown', this.currentModule);
                    this.currentModule.detachElement();
                }
                if (moduleChange) {
                    var $el = this.$('[data-fossil-placeholder=module]');
                    this.trigger('module:change', this.currentModule, module);
                    module.deferred();
                    module.setElement($el);
                    module.then(_.bind(function moduleReady () {
                        this.trigger('module:setup', module);
                        this.currentModule = module;
                    }, this));
                    module.resolve();
                }
            }
    });

    function initFactories (application) {
        var factories = _.extend(
            {},
            application.factories || {},
            application.options.factories || {}
        );
        application.factories = {};
        _.each(factories, function (factory, id) {
            application.use(id, factory);
        });
    }

    function initModules (application) {
        var apps = _.extend(
            {},
            application.modules || {},
            application.options.modules || {}
        );
        application.modules = {};
        _.each(apps, function (module, path) {
            application.connect(path, module);
        });
    }

    Application.extend = Backbone.Model.extend;

    return Application;
});
<|endoftext|>


<commit_before>module.exports = function () {
  attemptPurchase = function (user, points, callback) {
    getDbUserFromSiteUser(user, function (row) {
      if (!row || row.custom_points < points) {
        console.log("[POINTS] Purchase failed: " + row.username + " only has " + row.custom_points + " points (" + points + " needed)");
        bot.sendChat("Sorry @" + row.username + ", you need " + points + config.customPointName + " for that.");
        callback(false);
        return;
      }

      // Deduct the points from the sender's balance and add to the recipient
      models.User.update(
        {
          custom_points: Sequelize.literal("(custom_points - " + points + ")"),
        },
        { where: { site_id: row.site_id } }
      );
      console.log("[POINTS] " + row.username + " spent " + points + " points");
      callback(true);
    });
    return;
  };

  transferCustomPoints = function (fromUser, toUser, points) {
    // Create them out of thin air!
    if (fromUser === null) {
      fromUser = bot.getSelf();

      models.User.update(
        {
          custom_points: Sequelize.literal("(custom_points + " + points + ")"),
        },
        { where: { site_id: toUser.id.toString() } }
      );
      console.log("[GIFT] " + fromUser.username + " awarded " + points + " points to " + toUser.username);
      bot.sendChat(":gift: " + fromUser.username + " awarded " + points + " " + config.customPointName + " to @" + toUser.username);

      return;
    } else {
      getDbUserFromSiteUser(fromUser, function (row) {
        if (!row || row.custom_points < points) {
          console.log("Gift failed");
          return false;
        }

        // Deduct the points from the sender's balance and add to the recipient
        models.User.update(
          {
            custom_points: Sequelize.literal("(custom_points - " + points + ")"),
          },
          { where: { site_id: fromUser.id.toString() } }
        );
        models.User.update(
          {
            custom_points: Sequelize.literal("(custom_points + " + points + ")"),
          },
          { where: { site_id: toUser.id.toString() } }
        );

        console.log("[GIFT] " + fromUser.username + " gave " + points + " points to " + toUser.username);
        bot.sendChat(":gift: @" + fromUser.username + " gave " + points + " " + config.customPointName + " to @" + toUser.username + " :gift:");
      });
    }
  };
};
<commit_msg>Continued port work for ttfm<commit_after>module.exports = function () {
  attemptPurchase = function (user, points, callback) {
    getDbUserFromSiteUser(user, function (row) {
      if (!row || row.custom_points < points) {
        console.log("[POINTS] Purchase failed: " + row.username + " only has " + row.custom_points + " points (" + points + " needed)");
        bot.sendChat("Sorry @" + row.username + ", you need " + points + config.customPointName + " for that.");
        callback(false);
        return;
      }

      // Deduct the points from the sender's balance and add to the recipient
      models.User.update(
        {
          custom_points: Sequelize.literal("(custom_points - " + points + ")"),
        },
        { where: { site_id: row.site_id } }
      );
      console.log("[POINTS] " + row.username + " spent " + points + " points");
      callback(true);
    });
    return;
  };

  transferCustomPoints = function (fromUser, toUser, points) {
    // Create them out of thin air!
    if (fromUser === null) {
      fromUser = getDbUserFromSiteUser(bot.user.id);

      models.User.update(
        {
          custom_points: Sequelize.literal("(custom_points + " + points + ")"),
        },
        { where: { site_id: toUser.id.toString() } }
      );
      console.log("[GIFT] " + fromUser.username + " awarded " + points + " points to " + toUser.username);
      bot.sendChat(":gift: " + fromUser.username + " awarded " + points + " " + config.customPointName + " to @" + toUser.username);

      return;
    } else {
      getDbUserFromSiteUser(fromUser, function (row) {
        if (!row || row.custom_points < points) {
          console.log("Gift failed");
          return false;
        }

        // Deduct the points from the sender's balance and add to the recipient
        models.User.update(
          {
            custom_points: Sequelize.literal("(custom_points - " + points + ")"),
          },
          { where: { site_id: fromUser.id.toString() } }
        );
        models.User.update(
          {
            custom_points: Sequelize.literal("(custom_points + " + points + ")"),
          },
          { where: { site_id: toUser.id.toString() } }
        );

        console.log("[GIFT] " + fromUser.username + " gave " + points + " points to " + toUser.username);
        bot.sendChat(":gift: @" + fromUser.username + " gave " + points + " " + config.customPointName + " to @" + toUser.username + " :gift:");
      });
    }
  };
};
<|endoftext|>


<commit_before>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

(function(window, angular, undefined) {
  'use strict';

  angular.module('ngAuth', [])
    .provider('Auth', function() {

      var config = this.config = {
        logoutRedirect: '/',
        loginRedirect: '/',
        loginUrl: '/auth/login',
        signupUrl: '/auth/signup',
        signupRedirect: '/login',
        userGlobal: 'currentUser',
        providers: {
          facebook: {
            url: '/auth/facebook',
            authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
            redirectUri: 'http://localhost:3000',
            scope: 'email',
            requiredUrlParams: ['display'],
            display: 'popup'
          },
          google: {
            url: '/auth/google',
            authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
            redirectUri: 'http://localhost:3000',
            scope: 'email',
            requiredUrlParams: ['state'],
            state: 'STATE'
          },
          linkedin: {
            authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
            redirectUri: 'http://localhost:3000',
            requiredUrlParams: ['state'],
            state: 'STATE'
          }
        }
      };

      // TODO: $state = md5(rand());
      // TODO: Use requiredUrlParams instead of passing all properties
      // TODO: pass scope delimiter
      // TODO: default responseType to code if token is obtained on server

      return {
        setProvider: function(params) {
          config.providers[params.name] = config.providers[params.name] || {};
          angular.extend(config.providers[params.name], params);
        },

        $get: function($interval, $timeout, $http, $location, $rootScope, $alert, $q, $injector, $window) {

          // BEGIN OAUTH

          // Popup window.
          var Popup = function() {
            this.popup = null;
          };

          Popup.prototype.open = function(url, keys, options) {
            console.log(url)
            var deferred = $q.defer();
            // TODO: refactor
            // todo wildcard star
            var optionsString = stringifyOptions(prepareOptions(options || {}));
            this.popup = $window.open(url, '*', optionsString);
            this.popup.focus();

            this.createPostMessageHandler(deferred);
            this.pollPopup(deferred);

            return deferred.promise;
          };

          Popup.prototype.pollPopup = function(deferred) {
            var intervalHandler = function() {
              if (this.popup.closed) {
                $interval.cancel(this.polling);
                deferred.reject('Popup was closed by the user.');
              }
              this.requestAuthorizationCode();
            }.bind(this);
            this.polling = $interval(intervalHandler, 35);
          };

          Popup.prototype.requestAuthorizationCode = function() {
            var query = this.popup.location.search.substring(1);
            if (query.indexOf('code') > -1) {
              var code = this.parseQueryString(query).code;
              $window.postMessage(code, $window.location.origin);
              $interval.cancel(this.polling);
              this.popup.close();
            }
          };

          Popup.prototype.createPostMessageHandler = function(deferred) {
            $window.addEventListener('message', function(event) {
              deferred.resolve(event.data);
            }, false);
          };

          Popup.prototype.parseQueryString = function(keyValue) {
            var obj = {}, key, value;
            angular.forEach((keyValue || '').split('&'), function(keyValue) {
              if (keyValue) {
                value = keyValue.split('=');
                key = decodeURIComponent(value[0]);
                obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
              }
            });
            return obj;
          };

          Popup.prototype.close = function() {
            if (this.popup) {
              this.popup.close();
              this.popup = null;
            }
          };

          function prepareOptions(options) {
            var width = options.width || 500;
            var height = options.height || 500;
            return angular.extend({
              left: ((screen.width / 2) - (width / 2)),
              top: ((screen.height / 2) - (height / 2)),
              width: width,
              height: height
            }, options);
          }

          function stringifyOptions(options) {
            var optionsStrings = [];
            for (var key in options) {
              if (options.hasOwnProperty(key)) {
                var value;
                switch (options[key]) {
                  case true:
                    value = '1';
                    break;
                  case false:
                    value = '0';
                    break;
                  default:
                    value = options[key];
                }
                optionsStrings.push(
                  key + '=' + value
                );
              }
            }
            return optionsStrings.join(',');
          }

          var defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];

          var Oauth2 = function(config) {
            //if (this instanceof CustomObject)

            this.name = config.name;
            this.clientId = config.clientId;
            this.scope = config.scope;
            this.authorizationEndpoint = config.authorizationEndpoint;
            this.redirectUri = config.redirectUri;
            this.responseType = 'code';
            this.requiredUrlParams = defaultUrlParams.concat(config.requiredUrlParams);
            this.optionalUrlParams = ['scope'];
          };

          Oauth2.prototype.camelCase = function(name) {
            return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
              return offset ? letter.toUpperCase() : letter;
            });
          };

          Oauth2.prototype.open = function() {
            var deferred = $q.defer();
            var url = this.buildUrl();
            var popup = new Popup();

            popup.open(url).then(function(code) {
              this.exchangeForToken(code).then(function(response) {
                deferred.resolve(response.data);
              });
            }.bind(this));

            return deferred.promise;
          };

          Oauth2.prototype.exchangeForToken = function(code) {
            var params = {
              clientId: config.providers[this.name].clientId,
              redirectUri: $window.location.origin + '/',
              code: code
            };

            return $http.post('/auth/facebook', params);
          };

          Oauth2.prototype.buildUrl = function() {
            var baseUrl = this.authorizationEndpoint;
            var qs = this.buildQueryString();
            return [baseUrl, qs].join('?');
          };

          Oauth2.prototype.buildQueryString = function() {
            var obj = this;
            var keyValuePairs = [];

            angular.forEach(this.requiredUrlParams, function(paramName) {
              var camelizedName = obj.camelCase(paramName);
              var paramValue = obj[camelizedName];
              keyValuePairs.push([paramName, paramValue]);
            });

            angular.forEach(this.optionalUrlParams, function(paramName) {
              var camelizedName = obj.camelCase(paramName);
              var paramValue = obj[camelizedName];
              keyValuePairs.push([paramName, paramValue]);
            });

            return keyValuePairs.map(function(pair) {
              return pair.join('=');
            }).join('&');
          };

          Oauth2.createProvider = function(providerName) {
            var providerOptions = config.providers[providerName];
            var provider = new Oauth2(providerOptions);
            return provider;
          };

          // END OAUTH

          var token = $window.localStorage.token;
          if (token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $rootScope[config.userGlobal] = payload.user;
          }

          return {
            authenticate: function(providerName, options) {
              if (!providerName) {
                return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
              }

              var provider = Oauth2.createProvider(providerName);

              var deferred = $q.defer();

              provider.open(options).then(function(data) {
                console.log('OPENED')
                deferred.resolve(data);
              });

              return deferred.promise;
            },

            loginOauth: function(provider) {
              provider = provider.trim().toLowerCase();

              switch (provider) {
                case 'facebook':
                  var scope = config.providers.facebook.scope.join(',');
                  FB.login(function(response) {
                    FB.api('/me', function(profile) {
                      // TODO normalize return properties like passport
                      var data = {
                        accessToken: response.authResponse.accessToken,
                        signedRequest: response.authResponse.signedRequest,
                        profile: profile
                      };
                      $http.post(config.providers.facebook.url, data).success(function(token) {
                        var payload = JSON.parse($window.atob(token.split('.')[1]));
                        $window.localStorage.token = token;
                        $rootScope[config.userGlobal] = payload.user;
                        $location.path(config.loginRedirect);
                      });
                    });
                  }, {scope: scope});
                  break;
                case 'google':

                  break;
                case 'linkedin':
                  break;
                default:
                  break;
              }
            },
            login: function(user) {
              return $http.post(config.loginUrl, user).success(function(data) {
                $window.localStorage.token = data.token;
                var payload = JSON.parse($window.atob(data.token.split('.')[1]));
                $rootScope[config.userGlobal] = payload.user;
                $location.path(config.loginRedirect);
              });
            },
            signup: function(user) {
              return $http.post(config.signupUrl, user).success(function() {
                $location.path(config.signupRedirect);
              });
            },
            logout: function() {
              delete $window.localStorage.token;
              $rootScope[config.userGlobal] = null;
              $location.path(config.logoutRedirect);
            },
            isAuthenticated: function() {
              return $rootScope[config.userGlobal];
            }
          };
        }
      };
    })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.token) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $location) {
      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope.currentUser &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope.currentUser) {
          $location.path('/login');
        }
      });
    });
})(window, window.angular);

<commit_msg>updated google provider configuration<commit_after>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

(function(window, angular, undefined) {
  'use strict';

  angular.module('ngAuth', [])
    .provider('Auth', function() {

      var config = this.config = {
        logoutRedirect: '/',
        loginRedirect: '/',
        loginUrl: '/auth/login',
        signupUrl: '/auth/signup',
        signupRedirect: '/login',
        userGlobal: 'currentUser',
        providers: {
          facebook: {
            url: '/auth/facebook',
            authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
            redirectUri: 'http://localhost:3000',
            scope: 'email',
            requiredUrlParams: ['display'],
            display: 'popup'
          },
          google: {
            url: '/auth/google',
            authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
            redirectUri: 'http://localhost:3000',
            scope: 'openid profile email',
            requiredUrlParams: ['display'],
            display: 'popup'
          },
          linkedin: {
            authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
            redirectUri: 'http://localhost:3000',
            requiredUrlParams: ['state'],
            state: 'STATE'
          }
        }
      };

      // TODO: defineProperty setter on scope
      // TODO: $state = md5(rand());
      // TODO: Use requiredUrlParams instead of passing all properties
      // TODO: pass scope delimiter
      // TODO: default responseType to code if token is obtained on server

      return {
        setProvider: function(params) {
          config.providers[params.name] = config.providers[params.name] || {};
          angular.extend(config.providers[params.name], params);
        },

        $get: function($interval, $timeout, $http, $location, $rootScope, $alert, $q, $injector, $window) {

          // BEGIN OAUTH

          // Popup window.
          var Popup = function() {
            this.popup = null;
          };

          Popup.prototype.open = function(url, keys, options) {
            console.log(url)
            var deferred = $q.defer();
            // TODO: refactor
            // todo wildcard star
            var optionsString = stringifyOptions(prepareOptions(options || {}));
            this.popup = $window.open(url, '*', optionsString);
            this.popup.focus();

            this.createPostMessageHandler(deferred);
            this.pollPopup(deferred);

            return deferred.promise;
          };

          Popup.prototype.pollPopup = function(deferred) {
            var intervalHandler = function() {
              if (this.popup.closed) {
                $interval.cancel(this.polling);
                deferred.reject('Popup was closed by the user.');
              }
              this.requestAuthorizationCode();
            }.bind(this);
            this.polling = $interval(intervalHandler, 35);
          };

          Popup.prototype.requestAuthorizationCode = function() {
            var query = this.popup.location.search.substring(1);
            if (query.indexOf('code') > -1) {
              var code = this.parseQueryString(query).code;
              $window.postMessage(code, $window.location.origin);
              $interval.cancel(this.polling);
              this.popup.close();
            }
          };

          Popup.prototype.createPostMessageHandler = function(deferred) {
            $window.addEventListener('message', function(event) {
              deferred.resolve(event.data);
            }, false);
          };

          Popup.prototype.parseQueryString = function(keyValue) {
            var obj = {}, key, value;
            angular.forEach((keyValue || '').split('&'), function(keyValue) {
              if (keyValue) {
                value = keyValue.split('=');
                key = decodeURIComponent(value[0]);
                obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
              }
            });
            return obj;
          };

          Popup.prototype.close = function() {
            if (this.popup) {
              this.popup.close();
              this.popup = null;
            }
          };

          function prepareOptions(options) {
            var width = options.width || 500;
            var height = options.height || 500;
            return angular.extend({
              left: ((screen.width / 2) - (width / 2)),
              top: ((screen.height / 2) - (height / 2)),
              width: width,
              height: height
            }, options);
          }

          function stringifyOptions(options) {
            var optionsStrings = [];
            for (var key in options) {
              if (options.hasOwnProperty(key)) {
                var value;
                switch (options[key]) {
                  case true:
                    value = '1';
                    break;
                  case false:
                    value = '0';
                    break;
                  default:
                    value = options[key];
                }
                optionsStrings.push(
                  key + '=' + value
                );
              }
            }
            return optionsStrings.join(',');
          }

          var defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];

          var Oauth2 = function(config) {
            //if (this instanceof CustomObject)

            this.name = config.name;
            this.clientId = config.clientId;
            this.scope = config.scope;
            this.authorizationEndpoint = config.authorizationEndpoint;
            this.redirectUri = config.redirectUri;
            this.responseType = 'code';
            this.requiredUrlParams = defaultUrlParams.concat(config.requiredUrlParams);
            this.optionalUrlParams = ['scope'];
          };

          Oauth2.prototype.camelCase = function(name) {
            return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
              return offset ? letter.toUpperCase() : letter;
            });
          };

          Oauth2.prototype.open = function() {
            var deferred = $q.defer();
            var url = this.buildUrl();
            var popup = new Popup();

            popup.open(url).then(function(code) {
              this.exchangeForToken(code).then(function(response) {
                deferred.resolve(response.data);
              });
            }.bind(this));

            return deferred.promise;
          };

          Oauth2.prototype.exchangeForToken = function(code) {
            var params = {
              clientId: config.providers[this.name].clientId,
              redirectUri: $window.location.origin + '/',
              code: code
            };

            return $http.post('/auth/facebook', params);
          };

          Oauth2.prototype.buildUrl = function() {
            var baseUrl = this.authorizationEndpoint;
            var qs = this.buildQueryString();
            return [baseUrl, qs].join('?');
          };

          Oauth2.prototype.buildQueryString = function() {
            var obj = this;
            var keyValuePairs = [];

            angular.forEach(this.requiredUrlParams, function(paramName) {
              var camelizedName = obj.camelCase(paramName);
              var paramValue = obj[camelizedName];
              keyValuePairs.push([paramName, paramValue]);
            });

            angular.forEach(this.optionalUrlParams, function(paramName) {
              var camelizedName = obj.camelCase(paramName);
              var paramValue = obj[camelizedName];
              keyValuePairs.push([paramName, paramValue]);
            });

            return keyValuePairs.map(function(pair) {
              return pair.join('=');
            }).join('&');
          };

          Oauth2.createProvider = function(providerName) {
            var providerOptions = config.providers[providerName];
            var provider = new Oauth2(providerOptions);
            return provider;
          };

          // END OAUTH

          var token = $window.localStorage.token;
          if (token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $rootScope[config.userGlobal] = payload.user;
          }

          return {
            authenticate: function(providerName, options) {
              if (!providerName) {
                return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
              }

              var provider = Oauth2.createProvider(providerName);

              var deferred = $q.defer();

              provider.open(options).then(function(data) {
                console.log('OPENED')
                deferred.resolve(data);
              });

              return deferred.promise;
            },

            loginOauth: function(provider) {
              provider = provider.trim().toLowerCase();

              switch (provider) {
                case 'facebook':
                  var scope = config.providers.facebook.scope.join(',');
                  FB.login(function(response) {
                    FB.api('/me', function(profile) {
                      // TODO normalize return properties like passport
                      var data = {
                        accessToken: response.authResponse.accessToken,
                        signedRequest: response.authResponse.signedRequest,
                        profile: profile
                      };
                      $http.post(config.providers.facebook.url, data).success(function(token) {
                        var payload = JSON.parse($window.atob(token.split('.')[1]));
                        $window.localStorage.token = token;
                        $rootScope[config.userGlobal] = payload.user;
                        $location.path(config.loginRedirect);
                      });
                    });
                  }, {scope: scope});
                  break;
                case 'google':

                  break;
                case 'linkedin':
                  break;
                default:
                  break;
              }
            },
            login: function(user) {
              return $http.post(config.loginUrl, user).success(function(data) {
                $window.localStorage.token = data.token;
                var payload = JSON.parse($window.atob(data.token.split('.')[1]));
                $rootScope[config.userGlobal] = payload.user;
                $location.path(config.loginRedirect);
              });
            },
            signup: function(user) {
              return $http.post(config.signupUrl, user).success(function() {
                $location.path(config.signupRedirect);
              });
            },
            logout: function() {
              delete $window.localStorage.token;
              $rootScope[config.userGlobal] = null;
              $location.path(config.logoutRedirect);
            },
            isAuthenticated: function() {
              return $rootScope[config.userGlobal];
            }
          };
        }
      };
    })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.token) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $location) {
      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope.currentUser &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope.currentUser) {
          $location.path('/login');
        }
      });
    });
})(window, window.angular);

<|endoftext|>


<commit_before>"use strict";

var replaceWithSmart = require("../libs/utils.js").replaceWithSmart;
var replaceWith = require("../libs/utils.js").replaceWith;
var loadConfigSection = require("../libs/utils.js").loadConfigSection;
var requireDir = require("../libs/utils.js").requireDir;
var logger = require("../libs/utils.js").logger;
var Ajv = require('ajv');
var ajv = new Ajv({allErrors: true});

class Execution {
  constructor(process) {

    var _this = this;

    var params = Object.keys(process.exec);
    var paramsLength = params.length;

    while (paramsLength--) {
      _this[params[paramsLength]] = process.exec[params[paramsLength]];
    }

    _this.replaceWith = replaceWith;
    _this.logger = logger;

    return new Promise((resolve) => {
      loadConfigSection(global.config, 'executors', _this.id)
        .then((configValues) => {
          if (!_this.type && configValues.type) {
            _this.type = configValues.type;
          }
          _this.config = configValues;

          // ADD NOTIFICATORS SCHEMAS:
          requireDir('/../executors/', 'schema.json')
            .then((res) => {
              var keys = Object.keys(res);
              var keysLength = keys.length;
              while (keysLength--) {
                if (_this.type === keys[keysLength]) {

                  if (res[keys[keysLength]].hasOwnProperty('definitions') && res[keys[keysLength]].definitions.hasOwnProperty('params')) {

                    if (!ajv.getSchema('exec_' + keys[keysLength])) {
                      ajv.addSchema(res[keys[keysLength]].definitions.params, 'exec_' + keys[keysLength]);
                    }

                    var valid = ajv.validate('exec_' + keys[keysLength], _this);
                    if (!valid) {
                      logger.log('error', `Invalid params for executor ${_this.type}:`, ajv.errors);
                      throw new Error(`Invalid params for executor ${_this.type}:`, ajv.errors);
                      //resolve();
                    } else {
                      resolve(_this);
                    }
                    keysLength = 0;
                  }
                }
              }
              resolve(_this);
            })
            .catch((err) => {
              console.error(err);
              logger.log('warning', `Schema params for executor ${_this.type} not found`, err);
              resolve(_this);
            });
        })
        .catch(function (err) {
          logger.log('error', 'Executor loadConfig ', err);
          resolve();
        });
    });
  }

  exec(process) {
    return new Promise(function (resolve, reject) {
      logger.log('error', 'Method exec (execution) must be rewrite in child class');
      process.execute_err_return = `Method exec (execution) must be rewrite in child class`;
      process.execute_return = '';
      process.error();
      reject(process);
    });
  }

  kill(process) {
    return new Promise(function (resolve) {
      logger.log('error', 'Method kill (execution) must be rewrite in child class');
      process.execute_err_return = `Method kill (execution) must be rewrite in child class`;
      process.execute_return = '';
      process.stop();
      resolve();
    });
  }

  // Return config and params values:
  getValues(process) {
    return new Promise(function (resolve) {
      process.loadExecutorConfig()
        .then((configValues) => {
          var values = Object.assign(configValues, process.exec);
          replaceWithSmart(values, process.values())
            .then(function(res){
              resolve(res);
            })
            .catch(function(err){
              logger.log('error', 'Method getValues:',err);
              process.execute_err_return = 'Method getValues:' + err;
              process.execute_return = '';
              process.error();
              resolve();
            });
        });
    });
  }

  getParamValues(process) {
    return new Promise(function (resolve) {
      replaceWithSmart(process.exec, process.values())
        .then(function(res){
          resolve(res);
        })
        .catch(function(err){
          logger.log('error', 'Method getParamValues:',err);
          process.execute_err_return = 'Method getParamValues:' + err;
          process.execute_return = '';
          process.error();
          resolve();
        });
    });
  }

  getConfigValues(process) {
    return new Promise(function (resolve) {
      process.loadExecutorConfig()
        .then((configValues) => {
          replaceWithSmart(configValues, process.values())
            .then(function(res){
              resolve(res);
            })
            .catch(function(err){
              logger.log('error', 'Method getConfigValues:',err);
              process.execute_err_return = 'Method getConfigValues:' + err;
              process.execute_return = '';
              process.error();
              resolve();
            });
        });
    });
  }

}

module.exports = Execution;<commit_msg>Refactoring executors<commit_after>"use strict";

var replaceWithSmart = require("../libs/utils.js").replaceWithSmart;
var replaceWith = require("../libs/utils.js").replaceWith;
var requireDir = require("../libs/utils.js").requireDir;
var logger = require("../libs/utils.js").logger;
var Ajv = require('ajv');
var ajv = new Ajv({allErrors: true});

class Execution {
  constructor(process) {

    var _this = this;

    var params = Object.keys(process.exec);
    var paramsLength = params.length;

    while (paramsLength--) {
      _this[params[paramsLength]] = process.exec[params[paramsLength]];
    }

    _this.replaceWith = replaceWith;
    _this.logger = logger;

    return new Promise((resolve) => {
      process.loadExecutorConfig()
        .then((configValues) => {
          if (!_this.type && configValues.type) {
            _this.type = configValues.type;
          }
          _this.config = configValues;

          // ADD NOTIFICATORS SCHEMAS:
          requireDir('/../executors/', 'schema.json')
            .then((res) => {
              var keys = Object.keys(res);
              var keysLength = keys.length;
              while (keysLength--) {
                if (_this.type === keys[keysLength]) {

                  if (res[keys[keysLength]].hasOwnProperty('definitions') && res[keys[keysLength]].definitions.hasOwnProperty('params')) {

                    if (!ajv.getSchema('exec_' + keys[keysLength])) {
                      ajv.addSchema(res[keys[keysLength]].definitions.params, 'exec_' + keys[keysLength]);
                    }

                    var valid = ajv.validate('exec_' + keys[keysLength], _this);
                    if (!valid) {
                      logger.log('error', `Invalid params for executor ${_this.type}:`, ajv.errors);
                      throw new Error(`Invalid params for executor ${_this.type}:`, ajv.errors);
                      //resolve();
                    } else {
                      resolve(_this);
                    }
                    keysLength = 0;
                  }
                }
              }
              resolve(_this);
            })
            .catch((err) => {
              console.error(err);
              logger.log('warning', `Schema params for executor ${_this.type} not found`, err);
              resolve(_this);
            });
        })
        .catch(function (err) {
          logger.log('error', 'Executor loadConfig ', err);
          resolve();
        });
    });
  }

  exec(process) {
    return new Promise(function (resolve, reject) {
      logger.log('error', 'Method exec (execution) must be rewrite in child class');
      process.execute_err_return = `Method exec (execution) must be rewrite in child class`;
      process.execute_return = '';
      process.error();
      reject(process);
    });
  }

  kill(process) {
    return new Promise(function (resolve) {
      logger.log('error', 'Execution - Method kill must be rewrite in child class');
      process.execute_err_return = `Execution - Method kill must be rewrite in child class`;
      process.execute_return = '';
      process.stop();
      resolve();
    });
  }

  // Return config and params values:
  getValues(process) {
    return new Promise(function (resolve) {
      process.loadExecutorConfig()
        .then((configValues) => {
          var values = Object.assign(configValues, process.exec);
          replaceWithSmart(values, process.values())
            .then(function(res){
              resolve(res);
            })
            .catch(function(err){
              logger.log('error', 'Execution - Method getValues:',err);
              process.execute_err_return = 'Execution - Method getValues:' + err;
              process.execute_return = '';
              process.error();
              resolve();
            });
        });
    });
  }

  getParamValues(process) {
    return new Promise(function (resolve) {
      replaceWithSmart(process.exec, process.values())
        .then(function(res){
          resolve(res);
        })
        .catch(function(err){
          logger.log('error', 'Execution - Method getParamValues:',err);
          process.execute_err_return = 'Execution - Method getParamValues:' + err;
          process.execute_return = '';
          process.error();
          resolve();
        });
    });
  }

  getConfigValues(process) {
    return new Promise(function (resolve) {
      process.loadExecutorConfig()
        .then((configValues) => {
          replaceWithSmart(configValues, process.values())
            .then(function(res){
              resolve(res);
            })
            .catch(function(err){
              logger.log('error', 'Execution - Method getConfigValues:',err);
              process.execute_err_return = 'Execution - Method getConfigValues:' + err;
              process.execute_return = '';
              process.error();
              resolve();
            });
        });
    });
  }

}

module.exports = Execution;<|endoftext|>


<commit_before>import React from 'react';
import ItemLink from 'common/ItemLink';
import ITEM_QUALITIES from 'common/ITEM_QUALITIES';

import Module from 'Parser/Core/Module';
import Combatants from 'Parser/Core/Modules/Combatants';
import SUGGESTION_IMPORTANCE from 'Parser/Core/ISSUE_IMPORTANCE';

// Make sure to push this once we get to 1000!
const MAX_LEGENDARY_ILVL = 970;

class Legendaries extends Module {
  static dependencies = {
    combatants: Combatants,
  };

  legendaries = [];
  debug = false;

  on_finished() {
    const slots = this.combatants.selected._gearItemsBySlotId;
    for(let index = 0; index < Object.keys(slots).length; index++) {
      const item = slots[index];
      if (item.quality < ITEM_QUALITIES.LEGENDARY) {
        this.legendaries.push(item);
      }
    }
  }

  suggestions(when) {
    for(const item of this.legendaries) {
      if (this.debug) {
        console.log(`Legendary ${item.id} is ${item.itemLevel}`);
      }

      when(item.itemLevel === MAX_LEGENDARY_ILVL).isTrue().addSuggestion((suggest) => {
        return suggest(You should consider upgrading <ItemLink id={item.id} /> to the maximum item level for legendaries (currently {MAX_LEGENDARY_ILVL}).)
          .icon(item.icon)
          .staticImportance(SUGGESTION_IMPORTANCE.MAJOR);
      });
    }
  }
}

export default Legendaries;
<commit_msg>check equality on legendary quality and that ilvl is lower than max, not the other way around<commit_after>import React from 'react';
import ItemLink from 'common/ItemLink';
import ITEM_QUALITIES from 'common/ITEM_QUALITIES';

import Module from 'Parser/Core/Module';
import Combatants from 'Parser/Core/Modules/Combatants';
import SUGGESTION_IMPORTANCE from 'Parser/Core/ISSUE_IMPORTANCE';

// Make sure to push this once we get to 1000!
const MAX_LEGENDARY_ILVL = 970;

class Legendaries extends Module {
  static dependencies = {
    combatants: Combatants,
  };

  legendaries = [];
  debug = false;

  on_finished() {
    const slots = this.combatants.selected._gearItemsBySlotId;
    for(let index = 0; index < Object.keys(slots).length; index++) {
      const item = slots[index];
      if (item.quality === ITEM_QUALITIES.LEGENDARY) {
        this.legendaries.push(item);
      }
    }
  }

  suggestions(when) {
    for(const item of this.legendaries) {
      if (this.debug) {
        console.log(`Legendary ${item.id} is ${item.itemLevel}`);
      }

      when(item.itemLevel < MAX_LEGENDARY_ILVL).isTrue().addSuggestion((suggest) => {
        return suggest(You should consider upgrading <ItemLink id={item.id} /> to the maximum item level for legendaries (currently {MAX_LEGENDARY_ILVL}).)
          .icon(item.icon)
          .staticImportance(SUGGESTION_IMPORTANCE.MAJOR);
      });
    }
  }
}

export default Legendaries;
<|endoftext|>


<commit_before>define([
	'goo/math/Vector2',
	'goo/util/PromiseUtils',
	'goo/util/ObjectUtils'
], function (
	Vector2,
	PromiseUtils,
	ObjectUtils
) {
	'use strict';

	/**
	 * Texture defines a texture object to be used to display an image on a piece of geometry. The image to be displayed is
	 *        defined by the Image class. All attributes required for texture mapping are contained within this class. This includes
	 *        mipmapping if desired, magnificationFilter options, apply options and correction options. Default values are as follows:
	 *        minificationFilter - NearestNeighborNoMipMaps, magnificationFilter - NearestNeighbor, wrap - EdgeClamp on S, T and R, apply - Modulate,
	 *        environment - None.
	 * @param {Image} image Image to use as base for texture
	 * @param {Object} settings Texturing settings
	 * @param {string} [settings.wrapS='Repeat'] possible values:
	 *

	 *
'Repeat' = Repeat texture (ignore integer part of texture coords)
	 *
'MirroredRepeat' = Repeat with reversed direction on odd integer part of texture coords
	 *
'EdgeClamp' = Clamp texture coord range to 0..1 and use edge color
	 *

	 * @param {string} [settings.wrapT='Repeat'] possible values:
	 *

	 *
'Repeat' = Repeat texture (ignore integer part of texture coords)
	 *
'MirroredRepeat' = Repeat with reversed direction on odd integer part of texture coords
	 *
'EdgeClamp' = Clamp texture coord range to 0..1 and use edge color
	 *

	 * @param {string} [settings.magFilter='Bilinear'] possible values:
	 *

	 *
'NearestNeighbor' =
	 *
'Bilinear' =
	 *

	 * @param {string} [settings.minFilter='TriLinear'] possible values:
	 *

	 *
'NearestNeighborNoMipMaps' =
	 *
'NearestNeighborNearestMipMap' =
	 *
'NearestNeighborLinearMipMap' =
	 *
'BilinearNoMipMaps' =
	 *
'BilinearNearestMipMap' =
	 *
'Trilinear' =
	 *

	 * @param {number} [settings.anisotropy=1] Amount of anisotropic filtering (1=1x, 4=4x etc, max usually 4 or 16. Card max in Capabilities.maxAnisotropy)
	 * @param {string} [settings.format='RGBA'] possible values:
	 *

	 *
'RGBA' =
	 *
'RGB' =
	 *
'Alpha' =
	 *
'Luminance' =
	 *
'LuminanceAlpha' =
	 *

	 * @param {string} [settings.type='UnsignedByte'] possible values:
	 *

	 *
'UnsignedByte' =
	 *
'UnsignedShort565' =
	 *
'UnsignedShort4444' =
	 *
'UnsignedShort5551' =
	 *
'Float' =
	 *

	 * @param {Array} [settings.offset=(0, 0)] Texture offset
	 * @param {Array} [settings.repeat=(1, 1)] Texture repeat/scale
	 * @param {boolean} [settings.generateMipmaps='true'] Automatically generate mipmaps
	 * @param {boolean} [settings.premultiplyAlpha='false'] Premultiply alpha
	 * @param {number} [settings.unpackAlignment=1] Unpack alignment setting
	 * @param {boolean} [settings.flipY='true'] Flip texture in y-axis
	 * @param {number} width Width of the texture
	 * @param {number} height Height of the texture
	 */
	function Texture(image, settings, width, height) {
		this.glTexture = null;

		settings = settings || {};

		ObjectUtils.copyOptions(this, settings, {
			wrapS: 'Repeat',
			wrapT: 'Repeat',
			magFilter: 'Bilinear',
			minFilter: 'Trilinear',
			format: 'RGBA',
			type: 'UnsignedByte',
			generateMipmaps: true,
			premultiplyAlpha: false,
			unpackAlignment: 1,
			flipY: true
		});

		/**
		 * The anisotropic filtering level.
		 * @example-link http://code.gooengine.com/latest/visual-test/goo/renderer/texture/AnisotropicFiltering/Anisotropic-vtest.html Working example
		 * @type {number}
		 */
		this.anisotropy = settings.anisotropy !== undefined ? settings.anisotropy : 1;

		this.variant = '2D'; // CUBE

		this.offset = settings.offset ?	Vector2.fromAny(settings.offset) : new Vector2(0, 0);
		this.repeat = settings.repeat ? Vector2.fromAny(settings.repeat) : new Vector2(1, 1);

		this.lodBias = 0.0;

		this.hasBorder = false;

		this.needsUpdate = false;
		this.updateCallback = null;
		this.readyCallback = null;

		this._originalImage = null;
		this._originalWidth = 0;
		this._originalHeight = 0;

		this.image = null;
		if (image) {
			this.setImage(image, width, height, settings);
		}

		this.loadImage = PromiseUtils.resolve.bind(null, this);

		this.textureRecord = {};

		// #ifdef DEBUG
		Object.seal(this);
		// #endif
	}

	/**
	* Checks if the texture's data is ready.
	* @returns {boolean} True if ready.
	*/
	Texture.prototype.checkDataReady = function () {
		return this.image && (this.image.dataReady || this.image instanceof HTMLImageElement) || this.readyCallback !== null && this.readyCallback();
	};

	/**
	* Checks if the texture needs an update.
	* @returns {boolean} True if needed.
	*/
	Texture.prototype.checkNeedsUpdate = function () {
		//! AT: what's the precedence here? || first and then && or the other way around?
		return this.needsUpdate || this.updateCallback !== null && this.updateCallback();
	};

	/**
	 * Marks the texture as needing to be updated by the engine.
	 */
	Texture.prototype.setNeedsUpdate = function () {
		this.needsUpdate = true;
	};

	//! AT: this takes the same parameters as the Texture function but in a different order!
	/**
	 * Sets an image on the texture object.
	 *
	 * @param {Image} image The image to set. Can be an Image, TypedArray or an array of Images (for cubemaps)
	 * @param {number} [width]
	 * @param {number} [height]
	 */
	Texture.prototype.setImage = function (image, width, height, settings) {
		//! AT: this is not a general pattern; it is applied here only because of the complexity of this function
		this._originalImage = image;

		this.image = image; //! AT: is this always overriden? if so then why set it?

		var data = image instanceof Array ? image[0] : image;
		if (data instanceof Uint8Array || data instanceof Uint8ClampedArray || data instanceof Uint16Array || data instanceof Float32Array) {
			width = width || image.width;
			height = height || image.height;
			if (width !== undefined && height !== undefined) {
				this.image = {
					data: image,
					width: width,
					height: height,
					isData: true,
					dataReady: true
				};

				if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) {
					this.type = settings.type || 'UnsignedByte';
				} else if (data instanceof Uint16Array) {
					this.type = settings.type || 'UnsignedShort565';
					this.format = settings.format || 'RGB';
				} else if (data instanceof Float32Array) {
					this.type = settings.type || 'Float';
					this.format = settings.format || 'RGBA';
				}
			} else {
				throw new Error('Data textures need width and height');
			}
		} else {
			if (image instanceof Array) {
				this.image = {
					data: image
				};
			}
			if (data instanceof HTMLCanvasElement) {
				this.image.dataReady = true;
			}
		}
		this.setNeedsUpdate();

		//! AT: this is not a general pattern; it is applied here only because of the complexity of this function
		// these are delayed here in case width and height are modified in this function
		this._originalWidth = width;
		this._originalHeight = height;
	};

	/**
	 * Releases the allocated texture
	 * @param {WebGLRenderingContext} context
	 */
	Texture.prototype.destroy = function (context) {
		context.deleteTexture(this.glTexture);
		this.glTexture = null;
	};

	/**
	 * Returns the number of bytes this texture occupies in memory
	 * @returns {number}
	 */
	Texture.prototype.getSizeInMemory = function () {
		var size;

		if (!this.image) { return 0; }
		var width = this.image.width || this.image.length;
		var height = this.image.height || 1;

		size = width * height;

		if (this.format === 'Luminance' || this.format === 'Alpha') {
			size *= 1;
		} else if (this.format === 'Lumin`anceAlpha') {
			size *= 2;
		} else if (this.format === 'RGB') {
			size *= 3; // some dubious video cards may use 4 bits anyway
		} else if (this.format === 'RGBA') {
			size *= 4;
		} else if (this.format === 'PrecompressedDXT1') {
			size *= 4 / 8; // 8 : 1 ratio
		} else if (this.format === 'PrecompressedDXT1A') {
			size *= 4 / 6; // 6 : 1 ratio
		} else if (this.format === 'PrecompressedDXT3' || this.format === 'PrecompressedDXT5') {
			size *= 4 / 4; // 4 : 1 ratio
		}

		// account for mip maps
		if (this.generateMipmaps) {
			size = Math.ceil(size * 4 / 3);
		}

		return size;
	};

	/**
	 * Returns a clone of this plane
	 * @returns {Texture}
	 */
	Texture.prototype.clone = function () {
		// reconstructing original settings object passed to the constructor
		var settings = {
			wrapS: this.wrapS,
			wrapT: this.wrapT,
			magFilter: this.magFilter,
			minFilter: this.minFilter,
			anisotropy: this.anisotropy,
			format: this.format,
			type: this.type,
			offset: this.offset,
			repeat: this.repeat,
			generateMipmaps: this.generateMipmaps,
			premultiplyAlpha: this.premultiplyAlpha,
			unpackAlignment: this.unpackAlignment,
			flipY: this.flipY
		};

		var clone = new Texture(this._originalImage, settings, this._originalWidth, this._originalHeight);
		clone.variant = this.variant;
		clone.lodBias = this.lodBias;
		clone.hasBorder = this.hasBorder;
		return clone;
	};

	Texture.CUBE_FACES = ['PositiveX', 'NegativeX', 'PositiveY', 'NegativeY', 'PositiveZ', 'NegativeZ'];

	return Texture;
});<commit_msg>lazy load texture docs<commit_after>define([
	'goo/math/Vector2',
	'goo/util/PromiseUtils',
	'goo/util/ObjectUtils'
], function (
	Vector2,
	PromiseUtils,
	ObjectUtils
) {
	'use strict';

	/**
	 * Texture defines a texture object to be used to display an image on a piece of geometry. The image to be displayed is
	 *        defined by the Image class. All attributes required for texture mapping are contained within this class. This includes
	 *        mipmapping if desired, magnificationFilter options, apply options and correction options. Default values are as follows:
	 *        minificationFilter - NearestNeighborNoMipMaps, magnificationFilter - NearestNeighbor, wrap - EdgeClamp on S, T and R, apply - Modulate,
	 *        environment - None.
	 * @param {Image} image Image to use as base for texture
	 * @param {Object} settings Texturing settings
	 * @param {string} [settings.wrapS='Repeat'] possible values:
	 *

	 *
'Repeat' = Repeat texture (ignore integer part of texture coords)
	 *
'MirroredRepeat' = Repeat with reversed direction on odd integer part of texture coords
	 *
'EdgeClamp' = Clamp texture coord range to 0..1 and use edge color
	 *

	 * @param {string} [settings.wrapT='Repeat'] possible values:
	 *

	 *
'Repeat' = Repeat texture (ignore integer part of texture coords)
	 *
'MirroredRepeat' = Repeat with reversed direction on odd integer part of texture coords
	 *
'EdgeClamp' = Clamp texture coord range to 0..1 and use edge color
	 *

	 * @param {string} [settings.magFilter='Bilinear'] possible values:
	 *

	 *
'NearestNeighbor' =
	 *
'Bilinear' =
	 *

	 * @param {string} [settings.minFilter='TriLinear'] possible values:
	 *

	 *
'NearestNeighborNoMipMaps' =
	 *
'NearestNeighborNearestMipMap' =
	 *
'NearestNeighborLinearMipMap' =
	 *
'BilinearNoMipMaps' =
	 *
'BilinearNearestMipMap' =
	 *
'Trilinear' =
	 *

	 * @param {number} [settings.anisotropy=1] Amount of anisotropic filtering (1=1x, 4=4x etc, max usually 4 or 16. Card max in Capabilities.maxAnisotropy)
	 * @param {string} [settings.format='RGBA'] possible values:
	 *

	 *
'RGBA' =
	 *
'RGB' =
	 *
'Alpha' =
	 *
'Luminance' =
	 *
'LuminanceAlpha' =
	 *

	 * @param {string} [settings.type='UnsignedByte'] possible values:
	 *

	 *
'UnsignedByte' =
	 *
'UnsignedShort565' =
	 *
'UnsignedShort4444' =
	 *
'UnsignedShort5551' =
	 *
'Float' =
	 *

	 * @param {Array} [settings.offset=(0, 0)] Texture offset
	 * @param {Array} [settings.repeat=(1, 1)] Texture repeat/scale
	 * @param {boolean} [settings.generateMipmaps='true'] Automatically generate mipmaps
	 * @param {boolean} [settings.premultiplyAlpha='false'] Premultiply alpha
	 * @param {number} [settings.unpackAlignment=1] Unpack alignment setting
	 * @param {boolean} [settings.flipY='true'] Flip texture in y-axis
	 * @param {number} width Width of the texture
	 * @param {number} height Height of the texture
	 */
	function Texture(image, settings, width, height) {
		this.glTexture = null;

		settings = settings || {};

		ObjectUtils.copyOptions(this, settings, {
			wrapS: 'Repeat',
			wrapT: 'Repeat',
			magFilter: 'Bilinear',
			minFilter: 'Trilinear',
			format: 'RGBA',
			type: 'UnsignedByte',
			generateMipmaps: true,
			premultiplyAlpha: false,
			unpackAlignment: 1,
			flipY: true
		});

		/**
		 * The anisotropic filtering level.
		 * @example-link http://code.gooengine.com/latest/visual-test/goo/renderer/texture/AnisotropicFiltering/Anisotropic-vtest.html Working example
		 * @type {number}
		 */
		this.anisotropy = settings.anisotropy !== undefined ? settings.anisotropy : 1;

		this.variant = '2D'; // CUBE

		this.offset = settings.offset ?	Vector2.fromAny(settings.offset) : new Vector2(0, 0);
		this.repeat = settings.repeat ? Vector2.fromAny(settings.repeat) : new Vector2(1, 1);

		this.lodBias = 0.0;

		this.hasBorder = false;

		this.needsUpdate = false;
		this.updateCallback = null;
		this.readyCallback = null;

		this._originalImage = null;
		this._originalWidth = 0;
		this._originalHeight = 0;

		this.image = null;
		if (image) {
			this.setImage(image, width, height, settings);
		}

		/**
		 * If the Texture was set to load lazily in the TextureHandler, then this method can be used to load the image at a later point. This function returns a promise that resolves when the image was loaded.
		 * @type {Function}
		 */
		this.loadImage = PromiseUtils.resolve.bind(null, this);

		this.textureRecord = {};

		// #ifdef DEBUG
		Object.seal(this);
		// #endif
	}

	/**
	* Checks if the texture's data is ready.
	* @returns {boolean} True if ready.
	*/
	Texture.prototype.checkDataReady = function () {
		return this.image && (this.image.dataReady || this.image instanceof HTMLImageElement) || this.readyCallback !== null && this.readyCallback();
	};

	/**
	* Checks if the texture needs an update.
	* @returns {boolean} True if needed.
	*/
	Texture.prototype.checkNeedsUpdate = function () {
		//! AT: what's the precedence here? || first and then && or the other way around?
		return this.needsUpdate || this.updateCallback !== null && this.updateCallback();
	};

	/**
	 * Marks the texture as needing to be updated by the engine.
	 */
	Texture.prototype.setNeedsUpdate = function () {
		this.needsUpdate = true;
	};

	//! AT: this takes the same parameters as the Texture function but in a different order!
	/**
	 * Sets an image on the texture object.
	 *
	 * @param {Image} image The image to set. Can be an Image, TypedArray or an array of Images (for cubemaps)
	 * @param {number} [width]
	 * @param {number} [height]
	 */
	Texture.prototype.setImage = function (image, width, height, settings) {
		//! AT: this is not a general pattern; it is applied here only because of the complexity of this function
		this._originalImage = image;

		this.image = image; //! AT: is this always overriden? if so then why set it?

		var data = image instanceof Array ? image[0] : image;
		if (data instanceof Uint8Array || data instanceof Uint8ClampedArray || data instanceof Uint16Array || data instanceof Float32Array) {
			width = width || image.width;
			height = height || image.height;
			if (width !== undefined && height !== undefined) {
				this.image = {
					data: image,
					width: width,
					height: height,
					isData: true,
					dataReady: true
				};

				if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) {
					this.type = settings.type || 'UnsignedByte';
				} else if (data instanceof Uint16Array) {
					this.type = settings.type || 'UnsignedShort565';
					this.format = settings.format || 'RGB';
				} else if (data instanceof Float32Array) {
					this.type = settings.type || 'Float';
					this.format = settings.format || 'RGBA';
				}
			} else {
				throw new Error('Data textures need width and height');
			}
		} else {
			if (image instanceof Array) {
				this.image = {
					data: image
				};
			}
			if (data instanceof HTMLCanvasElement) {
				this.image.dataReady = true;
			}
		}
		this.setNeedsUpdate();

		//! AT: this is not a general pattern; it is applied here only because of the complexity of this function
		// these are delayed here in case width and height are modified in this function
		this._originalWidth = width;
		this._originalHeight = height;
	};

	/**
	 * Releases the allocated texture
	 * @param {WebGLRenderingContext} context
	 */
	Texture.prototype.destroy = function (context) {
		context.deleteTexture(this.glTexture);
		this.glTexture = null;
	};

	/**
	 * Returns the number of bytes this texture occupies in memory
	 * @returns {number}
	 */
	Texture.prototype.getSizeInMemory = function () {
		var size;

		if (!this.image) { return 0; }
		var width = this.image.width || this.image.length;
		var height = this.image.height || 1;

		size = width * height;

		if (this.format === 'Luminance' || this.format === 'Alpha') {
			size *= 1;
		} else if (this.format === 'Lumin`anceAlpha') {
			size *= 2;
		} else if (this.format === 'RGB') {
			size *= 3; // some dubious video cards may use 4 bits anyway
		} else if (this.format === 'RGBA') {
			size *= 4;
		} else if (this.format === 'PrecompressedDXT1') {
			size *= 4 / 8; // 8 : 1 ratio
		} else if (this.format === 'PrecompressedDXT1A') {
			size *= 4 / 6; // 6 : 1 ratio
		} else if (this.format === 'PrecompressedDXT3' || this.format === 'PrecompressedDXT5') {
			size *= 4 / 4; // 4 : 1 ratio
		}

		// account for mip maps
		if (this.generateMipmaps) {
			size = Math.ceil(size * 4 / 3);
		}

		return size;
	};

	/**
	 * Returns a clone of this plane
	 * @returns {Texture}
	 */
	Texture.prototype.clone = function () {
		// reconstructing original settings object passed to the constructor
		var settings = {
			wrapS: this.wrapS,
			wrapT: this.wrapT,
			magFilter: this.magFilter,
			minFilter: this.minFilter,
			anisotropy: this.anisotropy,
			format: this.format,
			type: this.type,
			offset: this.offset,
			repeat: this.repeat,
			generateMipmaps: this.generateMipmaps,
			premultiplyAlpha: this.premultiplyAlpha,
			unpackAlignment: this.unpackAlignment,
			flipY: this.flipY
		};

		var clone = new Texture(this._originalImage, settings, this._originalWidth, this._originalHeight);
		clone.variant = this.variant;
		clone.lodBias = this.lodBias;
		clone.hasBorder = this.hasBorder;
		return clone;
	};

	Texture.CUBE_FACES = ['PositiveX', 'NegativeX', 'PositiveY', 'NegativeY', 'PositiveZ', 'NegativeZ'];

	return Texture;
});<|endoftext|>


<commit_before>var chalk = require('chalk')
var path = require('path')
var utils = require('./utils')
var shell = require('shelljs')
var os = require('os')
var fs = require('fs')
// var debug = require('depurar')('lanyon')

var yes = chalk.green('✓ ')
// var no = chalk.red('✗ ')

module.exports = function (runtime, cb) {
  var envPrefix = ''
  var passEnv = {}
  var rubyProvider = ''

  if (runtime.lanyonReset) {
    console('--> Removing existing shims')
    shell.rm('-f', runtime.binDir + '/*')
  }

  if (!utils.satisfied(runtime, 'node')) {
    shell.exit(1)
  }

  // Detmine optimal rubyProvider and adjust shim configuration
  if (utils.satisfied(runtime, 'ruby', '' + runtime.binDir + '/ruby -v', 'ruby-shim')) {
    var buff = fs.readFileSync(runtime.binDir + '/ruby', 'utf-8').trim()
    if (buff.indexOf('docker') !== -1) {
      rubyProvider = 'docker'
    } else if (buff.indexOf('rvm') !== -1) {
      rubyProvider = 'rvm'
    } else if (buff.indexOf('rbenv') !== -1) {
      rubyProvider = 'rbenv'
    } else {
      rubyProvider = 'system'
    }
    console.log('--> Found a working shim - determined to be a "' + rubyProvider + '" rubyProvider')
    runtime.prerequisites.ruby.exe = fs.readFileSync(runtime.binDir + '/ruby', 'utf-8').trim().replace(' $*', '')
    runtime.prerequisites.ruby.writeShim = false
    runtime.prerequisites.ruby.versionCheck = runtime.prerequisites.ruby.exe + ' -v' + runtime.prerequisites.ruby.exeSuffix
    runtime.prerequisites.gem.exe = fs.readFileSync(runtime.binDir + '/gem', 'utf-8').trim().replace(' $*', '')
    runtime.prerequisites.gem.writeShim = false
    runtime.prerequisites.bundler.exe = runtime.binDir + '/bundler' // <-- not a lanyon shim, it's a real gem bin
    runtime.prerequisites.bundler.writeShim = false
  } else if (utils.satisfied(runtime, 'ruby', undefined, 'system')) {
    rubyProvider = 'system'
    runtime.prerequisites.gem.exe = shell.which('gem').stdout
    runtime.prerequisites.bundler.exe = shell.which('bundler').stdout
  } else if (utils.satisfied(runtime, 'docker')) {
    rubyProvider = 'docker'
    if (process.env.DOCKER_BUILD === '1') {
      utils.fatalExe('docker build -t kevinvz/lanyon:' + runtime.lanyonVersion + ' .')
      utils.fatalExe('docker push kevinvz/lanyon:' + runtime.lanyonVersion + '')
    }
    runtime.prerequisites.sh.exe = utils.dockerCmd(runtime, 'sh', '--interactive --tty')
    runtime.prerequisites.ruby.exe = utils.dockerCmd(runtime, 'ruby')
    runtime.prerequisites.jekyll.exe = utils.dockerCmd(runtime, 'bundler exec jekyll')
  } else if (utils.satisfied(runtime, 'rbenv') && shell.exec('rbenv install --help', { 'silent': false }).code === 0) {
    // rbenv does not offer installing of rubies by default, it will also require the install plugin --^
    rubyProvider = 'rbenv'
    utils.fatalExe('bash -c "rbenv install --skip-existing \'' + runtime.prerequisites.ruby.preferred + '\'"')
    runtime.prerequisites.ruby.exe = 'bash -c "eval $(rbenv init -) && rbenv shell \'' + runtime.prerequisites.ruby.preferred + '\' &&'
    runtime.prerequisites.ruby.exeSuffix = '"'
    runtime.prerequisites.ruby.versionCheck = runtime.prerequisites.ruby.exe + 'ruby -v' + runtime.prerequisites.ruby.exeSuffix
  } else if (utils.satisfied(runtime, 'rvm')) {
    rubyProvider = 'rvm'
    utils.fatalExe('bash -c "rvm install \'' + runtime.prerequisites.ruby.preferred + '\'"')
    runtime.prerequisites.ruby.exe = 'bash -c "rvm \'' + runtime.prerequisites.ruby.preferred + '\' exec'
    runtime.prerequisites.ruby.exeSuffix = '"'
    runtime.prerequisites.ruby.versionCheck = runtime.prerequisites.ruby.exe + ' ruby -v' + runtime.prerequisites.ruby.exeSuffix
  } else {
    console.error('Ruby version not satisfied, and exhausted ruby version installer helpers (rvm, rbenv, brew)')
    process.exit(1)
  }

  // Verify Ruby
  if (!utils.satisfied(runtime, 'ruby', runtime.prerequisites.ruby.versionCheck, 'verify')) {
    console.error('Ruby should have been installed but still not satisfied')
    process.exit(1)
  }

  if (rubyProvider !== 'docker') {
    // Install Bundler
    runtime.prerequisites.bundler.exe = runtime.prerequisites.ruby.exe + ' ' + runtime.prerequisites.bundler.exe
    if (!utils.satisfied(runtime, 'bundler', runtime.prerequisites.bundler.exe + ' -v' + runtime.prerequisites.ruby.exeSuffix)) {
      var bunderInstaller = []

      bunderInstaller.push('cd')
      bunderInstaller.push(runtime.cacheDir)
      bunderInstaller.push('&&')
      bunderInstaller.push(runtime.prerequisites.ruby.exe + ' ' + runtime.prerequisites.gem.exe + ' install')
      if (rubyProvider === 'system') {
        bunderInstaller.push('--binDir ' + runtime.binDir + '')
        bunderInstaller.push('--install-dir vendor/gem_home')
      }
      bunderInstaller.push('--no-rdoc')
      bunderInstaller.push('--no-ri')
      bunderInstaller.push('bundler')
      bunderInstaller.push('-v \'' + runtime.prerequisites.bundler.preferred + '\'' + runtime.prerequisites.ruby.exeSuffix)

      utils.fatalExe(bunderInstaller)

      if (rubyProvider === 'system') {
        runtime.prerequisites.bundler.exe = '' + runtime.binDir + '/bundler'
        passEnv.GEM_HOME = 'vendor/gem_home'
        passEnv.GEM_PATH = 'vendor/gem_home'

        if (Object.keys(passEnv).length > 0) {
          var vals = []
          for (var key in passEnv) {
            var val = passEnv[key]
            vals.push(key + '=' + val)
          }
          envPrefix = 'env ' + vals.join(' ') + ' '
        }

        runtime.prerequisites.bundler.exe = envPrefix + runtime.prerequisites.bundler.exe
      }
    }

    // Configure Bundler (nokogiri)
    process.stdout.write('--> Configuring: Bundler ... ')
    if (os.platform() === 'darwin' && shell.exec('brew -v', { 'silent': true }).code === 0) {
      utils.fatalExe([
        'cd',
        runtime.cacheDir,
        '&&',
        '(',
        'brew install libxml2;',
        runtime.prerequisites.bundler.exe,
        'config build.nokogiri',
        '--use-system-libraries',
        '--with-xml2-include=$(brew --prefix libxml2)/include/libxml2' + runtime.prerequisites.ruby.exeSuffix,
        ')'
      ])
    } else {
      utils.fatalExe([
        'cd',
        runtime.cacheDir,
        '&&',
        runtime.prerequisites.bundler.exe,
        'config build.nokogiri',
        '--use-system-libraries' + runtime.prerequisites.ruby.exeSuffix
      ])
    }

    runtime.prerequisites.jekyll.exe = runtime.prerequisites.bundler.exe + ' exec jekyll'

    // Install Gems from Gemfile bundle
    process.stdout.write('--> Installing: Gems ... ')
    utils.fatalExe([
      'cd',
      runtime.cacheDir,
      '&&',
      '(',
      runtime.prerequisites.bundler.exe,
      'install',
      '--binstubs=\'' + runtime.binDir + '\'',
      '--path \'vendor/bundler\'' + runtime.prerequisites.ruby.exeSuffix,
      '||',
      runtime.prerequisites.bundler.exe,
      'update' + runtime.prerequisites.ruby.exeSuffix,
      ')'
    ])
  }

  // Write shims
  for (var name in runtime.prerequisites) {
    var p = runtime.prerequisites[name]
    if (p.writeShim) {
      var shim = envPrefix + p.exe.trim() + ' $*' + runtime.prerequisites.ruby.exeSuffix + '\n'
      if (name === 'dash') {
        shim = envPrefix + p.exe.trim() + ' $*' + runtime.prerequisites.dash.exeSuffix + '\n'
      }
      var shimPath = path.join(runtime.binDir, name)
      process.stdout.write('--> Installing: ' + name + ' shim to: ' + shimPath + ' ... ')
      fs.writeFileSync(shimPath, shim, { 'encoding': 'utf-8', 'mode': '755' })
      console.log(yes)
    }
  }

  shimPath = path.join(runtime.binDir, 'deploy')
  process.stdout.write('--> Installing: ' + 'deploy' + ' shim to: ' + shimPath + ' ... ')
  fs.writeFileSync(shimPath, '#!/bin/sh\nnpm run build:production && npm run deploy', { 'encoding': 'utf-8', 'mode': '755' })
  console.log(yes)

  cb(null)
}
<commit_msg>Fix typo<commit_after>var chalk = require('chalk')
var path = require('path')
var utils = require('./utils')
var shell = require('shelljs')
var os = require('os')
var fs = require('fs')
// var debug = require('depurar')('lanyon')

var yes = chalk.green('✓ ')
// var no = chalk.red('✗ ')

module.exports = function (runtime, cb) {
  var envPrefix = ''
  var passEnv = {}
  var rubyProvider = ''

  if (runtime.lanyonReset) {
    console.log('--> Removing existing shims')
    shell.rm('-f', runtime.binDir + '/*')
  }

  if (!utils.satisfied(runtime, 'node')) {
    shell.exit(1)
  }

  // Detmine optimal rubyProvider and adjust shim configuration
  if (utils.satisfied(runtime, 'ruby', '' + runtime.binDir + '/ruby -v', 'ruby-shim')) {
    var buff = fs.readFileSync(runtime.binDir + '/ruby', 'utf-8').trim()
    if (buff.indexOf('docker') !== -1) {
      rubyProvider = 'docker'
    } else if (buff.indexOf('rvm') !== -1) {
      rubyProvider = 'rvm'
    } else if (buff.indexOf('rbenv') !== -1) {
      rubyProvider = 'rbenv'
    } else {
      rubyProvider = 'system'
    }
    console.log('--> Found a working shim - determined to be a "' + rubyProvider + '" rubyProvider')
    runtime.prerequisites.ruby.exe = fs.readFileSync(runtime.binDir + '/ruby', 'utf-8').trim().replace(' $*', '')
    runtime.prerequisites.ruby.writeShim = false
    runtime.prerequisites.ruby.versionCheck = runtime.prerequisites.ruby.exe + ' -v' + runtime.prerequisites.ruby.exeSuffix
    runtime.prerequisites.gem.exe = fs.readFileSync(runtime.binDir + '/gem', 'utf-8').trim().replace(' $*', '')
    runtime.prerequisites.gem.writeShim = false
    runtime.prerequisites.bundler.exe = runtime.binDir + '/bundler' // <-- not a lanyon shim, it's a real gem bin
    runtime.prerequisites.bundler.writeShim = false
  } else if (utils.satisfied(runtime, 'ruby', undefined, 'system')) {
    rubyProvider = 'system'
    runtime.prerequisites.gem.exe = shell.which('gem').stdout
    runtime.prerequisites.bundler.exe = shell.which('bundler').stdout
  } else if (utils.satisfied(runtime, 'docker')) {
    rubyProvider = 'docker'
    if (process.env.DOCKER_BUILD === '1') {
      utils.fatalExe('docker build -t kevinvz/lanyon:' + runtime.lanyonVersion + ' .')
      utils.fatalExe('docker push kevinvz/lanyon:' + runtime.lanyonVersion + '')
    }
    runtime.prerequisites.sh.exe = utils.dockerCmd(runtime, 'sh', '--interactive --tty')
    runtime.prerequisites.ruby.exe = utils.dockerCmd(runtime, 'ruby')
    runtime.prerequisites.jekyll.exe = utils.dockerCmd(runtime, 'bundler exec jekyll')
  } else if (utils.satisfied(runtime, 'rbenv') && shell.exec('rbenv install --help', { 'silent': false }).code === 0) {
    // rbenv does not offer installing of rubies by default, it will also require the install plugin --^
    rubyProvider = 'rbenv'
    utils.fatalExe('bash -c "rbenv install --skip-existing \'' + runtime.prerequisites.ruby.preferred + '\'"')
    runtime.prerequisites.ruby.exe = 'bash -c "eval $(rbenv init -) && rbenv shell \'' + runtime.prerequisites.ruby.preferred + '\' &&'
    runtime.prerequisites.ruby.exeSuffix = '"'
    runtime.prerequisites.ruby.versionCheck = runtime.prerequisites.ruby.exe + 'ruby -v' + runtime.prerequisites.ruby.exeSuffix
  } else if (utils.satisfied(runtime, 'rvm')) {
    rubyProvider = 'rvm'
    utils.fatalExe('bash -c "rvm install \'' + runtime.prerequisites.ruby.preferred + '\'"')
    runtime.prerequisites.ruby.exe = 'bash -c "rvm \'' + runtime.prerequisites.ruby.preferred + '\' exec'
    runtime.prerequisites.ruby.exeSuffix = '"'
    runtime.prerequisites.ruby.versionCheck = runtime.prerequisites.ruby.exe + ' ruby -v' + runtime.prerequisites.ruby.exeSuffix
  } else {
    console.error('Ruby version not satisfied, and exhausted ruby version installer helpers (rvm, rbenv, brew)')
    process.exit(1)
  }

  // Verify Ruby
  if (!utils.satisfied(runtime, 'ruby', runtime.prerequisites.ruby.versionCheck, 'verify')) {
    console.error('Ruby should have been installed but still not satisfied')
    process.exit(1)
  }

  if (rubyProvider !== 'docker') {
    // Install Bundler
    runtime.prerequisites.bundler.exe = runtime.prerequisites.ruby.exe + ' ' + runtime.prerequisites.bundler.exe
    if (!utils.satisfied(runtime, 'bundler', runtime.prerequisites.bundler.exe + ' -v' + runtime.prerequisites.ruby.exeSuffix)) {
      var bunderInstaller = []

      bunderInstaller.push('cd')
      bunderInstaller.push(runtime.cacheDir)
      bunderInstaller.push('&&')
      bunderInstaller.push(runtime.prerequisites.ruby.exe + ' ' + runtime.prerequisites.gem.exe + ' install')
      if (rubyProvider === 'system') {
        bunderInstaller.push('--binDir ' + runtime.binDir + '')
        bunderInstaller.push('--install-dir vendor/gem_home')
      }
      bunderInstaller.push('--no-rdoc')
      bunderInstaller.push('--no-ri')
      bunderInstaller.push('bundler')
      bunderInstaller.push('-v \'' + runtime.prerequisites.bundler.preferred + '\'' + runtime.prerequisites.ruby.exeSuffix)

      utils.fatalExe(bunderInstaller)

      if (rubyProvider === 'system') {
        runtime.prerequisites.bundler.exe = '' + runtime.binDir + '/bundler'
        passEnv.GEM_HOME = 'vendor/gem_home'
        passEnv.GEM_PATH = 'vendor/gem_home'

        if (Object.keys(passEnv).length > 0) {
          var vals = []
          for (var key in passEnv) {
            var val = passEnv[key]
            vals.push(key + '=' + val)
          }
          envPrefix = 'env ' + vals.join(' ') + ' '
        }

        runtime.prerequisites.bundler.exe = envPrefix + runtime.prerequisites.bundler.exe
      }
    }

    // Configure Bundler (nokogiri)
    process.stdout.write('--> Configuring: Bundler ... ')
    if (os.platform() === 'darwin' && shell.exec('brew -v', { 'silent': true }).code === 0) {
      utils.fatalExe([
        'cd',
        runtime.cacheDir,
        '&&',
        '(',
        'brew install libxml2;',
        runtime.prerequisites.bundler.exe,
        'config build.nokogiri',
        '--use-system-libraries',
        '--with-xml2-include=$(brew --prefix libxml2)/include/libxml2' + runtime.prerequisites.ruby.exeSuffix,
        ')'
      ])
    } else {
      utils.fatalExe([
        'cd',
        runtime.cacheDir,
        '&&',
        runtime.prerequisites.bundler.exe,
        'config build.nokogiri',
        '--use-system-libraries' + runtime.prerequisites.ruby.exeSuffix
      ])
    }

    runtime.prerequisites.jekyll.exe = runtime.prerequisites.bundler.exe + ' exec jekyll'

    // Install Gems from Gemfile bundle
    process.stdout.write('--> Installing: Gems ... ')
    utils.fatalExe([
      'cd',
      runtime.cacheDir,
      '&&',
      '(',
      runtime.prerequisites.bundler.exe,
      'install',
      '--binstubs=\'' + runtime.binDir + '\'',
      '--path \'vendor/bundler\'' + runtime.prerequisites.ruby.exeSuffix,
      '||',
      runtime.prerequisites.bundler.exe,
      'update' + runtime.prerequisites.ruby.exeSuffix,
      ')'
    ])
  }

  // Write shims
  for (var name in runtime.prerequisites) {
    var p = runtime.prerequisites[name]
    if (p.writeShim) {
      var shim = envPrefix + p.exe.trim() + ' $*' + runtime.prerequisites.ruby.exeSuffix + '\n'
      if (name === 'dash') {
        shim = envPrefix + p.exe.trim() + ' $*' + runtime.prerequisites.dash.exeSuffix + '\n'
      }
      var shimPath = path.join(runtime.binDir, name)
      process.stdout.write('--> Installing: ' + name + ' shim to: ' + shimPath + ' ... ')
      fs.writeFileSync(shimPath, shim, { 'encoding': 'utf-8', 'mode': '755' })
      console.log(yes)
    }
  }

  shimPath = path.join(runtime.binDir, 'deploy')
  process.stdout.write('--> Installing: ' + 'deploy' + ' shim to: ' + shimPath + ' ... ')
  fs.writeFileSync(shimPath, '#!/bin/sh\nnpm run build:production && npm run deploy', { 'encoding': 'utf-8', 'mode': '755' })
  console.log(yes)

  cb(null)
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name        Github Timeline
// @namespace   https://github.com/MyKiwi/github-timeline
// @description Filter your github timeline
// @include     https://github.com/
// @version     1.0
// @downloadURL https://github.com/MyKiwi/github-timeline
// @run-at      document-end
// @grant       none
// ==/UserScript==

// Main class

githubTimeline = {
    css: {
        dashboard: 'div.container div#dashboard div.news',
        menu: {
            base: 'div#github-timeline-menu',
            child: 'a'
        },

        getMenu: function() {
            'use strict';
            return this.dashboard + ' ' + this.menu.base;
        },

        getItems: function() {
            'use strict';
            return this.getMenu() + ' ' + this.menu.child;
        },

        getItemSelected: function() {
            'use strict';
            return githubTimeline.css.getItems() + '.selected';
        }
    },

    template: {
        menu: '' +
            '
' +
            '
' +
            '    All' +
            '    Pull Requests' +
            '    Issues' +
            '    Stars' +
            '    Others' +
            '
' +
            '
'
    },

    menu: {
        select: function(child) {
            'use strict';
            $(githubTimeline.css.getItems() + '.selected').removeClass('selected');
            child.addClass('selected');
            githubTimeline.dashboard.refresh();
        }
    },

    dashboard: {
        refresh: function() {
            'use strict';
            var $button = $(githubTimeline.css.getItemSelected());

            $dashboard.find('.alert').each(function(index, line) {
                var $line = $(line);
                $line.css('display', 'none');

                var issueRegexp = new RegExp('issue', 'g');
                var pullRequestRegexp = new RegExp('pull request', 'g');
                switch ($button.html()) {
                    case 'All':
                        $line.css('display', 'block');

                        break;
                    case 'Pull Requests':
                        if (pullRequestRegexp.test($line.find('div.title').html())) {
                            $line.css('display', 'block');
                        }

                        break;
                    case 'Issues':
                        if (issueRegexp.test($line.find('div.title').html())) {
                            $line.css('display', 'block');
                        }

                        break;
                    case 'Stars':
                        if ($line.hasClass('watch_started')) {
                            $line.css('display', 'block');
                        }

                        break;
                    case 'Others':
                        if (!pullRequestRegexp.test($line.find('div.title').html()) && !issueRegexp.test($line.find('div.title').html()) && !$line.hasClass('watch_started')) {
                            $line.css('display', 'block');
                        }

                        break;
                }

            });
        }
    }
};

// Workflow

window.addEventListener('load', function() {

    $dashboard = $(githubTimeline.css.dashboard);

    $(githubTimeline.template.menu).prependTo($dashboard);
    $menu = $(githubTimeline.css.getMenu());

    $(document).on('click', githubTimeline.css.getItems(), function() {
        githubTimeline.menu.select($(this));
    });

    $(document).ajaxComplete(function(event, request, options) {
        var urlMore = /\/dashboard\/index\/\d+/g
        if (urlMore.test(options.url)) {
            githubTimeline.dashboard.refresh();
        }
    });

});<commit_msg>improved issue and pull request detection<commit_after>// ==UserScript==
// @name        Github Timeline
// @namespace   https://github.com/MyKiwi/github-timeline
// @description Filter your github timeline
// @include     https://github.com/
// @version     1.0
// @downloadURL https://github.com/MyKiwi/github-timeline
// @run-at      document-end
// @grant       none
// ==/UserScript==

// Main class

githubTimeline = {
    css: {
        dashboard: 'div.container div#dashboard div.news',
        menu: {
            base: 'div#github-timeline-menu',
            child: 'a'
        },

        getMenu: function() {
            'use strict';
            return this.dashboard + ' ' + this.menu.base;
        },

        getItems: function() {
            'use strict';
            return this.getMenu() + ' ' + this.menu.child;
        },

        getItemSelected: function() {
            'use strict';
            return githubTimeline.css.getItems() + '.selected';
        }
    },

    template: {
        menu: '' +
            '
' +
            '
' +
            '    All' +
            '    Pull Requests' +
            '    Issues' +
            '    Stars' +
            '    Others' +
            '
' +
            '
'
    },

    menu: {
        select: function(child) {
            'use strict';
            $(githubTimeline.css.getItems() + '.selected').removeClass('selected');
            child.addClass('selected');
            githubTimeline.dashboard.refresh();
        }
    },

    dashboard: {
        refresh: function() {
            'use strict';
            var $button = $(githubTimeline.css.getItemSelected());

            $dashboard.find('.alert').each(function(index, line) {
                var $line = $(line);
                $line.css('display', 'none');

                var issueRegexp = new RegExp(' issue ', 'g');
                var pullRequestRegexp = new RegExp(' pull request ', 'g');
                switch ($button.html()) {
                    case 'All':
                        $line.css('display', 'block');

                        break;
                    case 'Pull Requests':
                        if (pullRequestRegexp.test($line.find('div.title').html())) {
                            $line.css('display', 'block');
                        }

                        break;
                    case 'Issues':
                        if (issueRegexp.test($line.find('div.title').html())) {
                            $line.css('display', 'block');
                        }

                        break;
                    case 'Stars':
                        if ($line.hasClass('watch_started')) {
                            $line.css('display', 'block');
                        }

                        break;
                    case 'Others':
                        if (!pullRequestRegexp.test($line.find('div.title').html()) && !issueRegexp.test($line.find('div.title').html()) && !$line.hasClass('watch_started')) {
                            $line.css('display', 'block');
                        }

                        break;
                }

            });
        }
    }
};

// Workflow

window.addEventListener('load', function() {

    $dashboard = $(githubTimeline.css.dashboard);

    $(githubTimeline.template.menu).prependTo($dashboard);
    $menu = $(githubTimeline.css.getMenu());

    $(document).on('click', githubTimeline.css.getItems(), function() {
        githubTimeline.menu.select($(this));
    });

    $(document).ajaxComplete(function(event, request, options) {
        var urlMore = /\/dashboard\/index\/\d+/g
        if (urlMore.test(options.url)) {
            githubTimeline.dashboard.refresh();
        }
    });

});
<|endoftext|>