<commit_before>import app from '../app';
import $ from 'jquery';
import { Events } from 'backbone';

const events = {
  ...Events,
};

export { events };

/**
 * Converts the amount from a decimal to an integer. If the
 * currency code is BTC, it will convert to Satoshi.
 */
export function decimalToInteger(amount, isBtc = false) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number.');
  }

  let updatedAmount = amount;

  if (isBtc) {
    updatedAmount = Math.round(amount * 100000000);
  } else {
    updatedAmount = Math.round(amount * 100);
  }

  return updatedAmount;
}

/**
 * Converts the amount from an integer to a decimal, rounding
 * to 2 decimal places. If the currency code is BTC, it will
 * convert from Satoshi to BTC.
 */
export function integerToDecimal(amount, isBtc = false) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number.');
  }

  let updatedAmount = amount;

  if (isBtc) {
    updatedAmount = Number((amount / 100000000).toFixed(8));
  } else {
    updatedAmount = Number((amount / 100).toFixed(2));
  }

  return updatedAmount;
}

/**
 * Will take a number and return a string version of the number
 * with the appropriate number of decimal places based on whether
 * the number represents a BTC or fiat price.
 *
 * This differs from formatCurrency in that this does not localize
 * the number at all. It simply returns the value with the
 * appropriate number of decimal place, e.g:
 *
 * formatPrice(123.456, false) // "123.46"
 * formatPrice(123.456, true)  // "123.45600000"
 *
 * It is more useful for <input>'s because we are not
 * localizing the numbers in them.
 *
 * todo: add this as a template helper; perhaps there's
 * a better name for this function?
 */
export function formatPrice(price, isBtc = false) {
  if (typeof price !== 'number') {
    throw new Error('Please provide a price as a number');
  }

  if (isNaN(price)) {
    throw new Error('Please provide a price that is not NaN');
  }

  const decimalPlaces = isBtc ? 8 : 2;

  return price.toFixed(decimalPlaces);
}

// todo: check currency is one of our currencies
export function formatCurrency(amount, currency, locale = app.settings.get('language')) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number');
  }

  if (isNaN(amount)) {
    throw new Error('Please provide an amount that is not NaN');
  }

  if (typeof locale !== 'string') {
    throw new Error('Please provide a locale as a string');
  }

  if (typeof currency !== 'string') {
    throw new Error('Please provide a currency as a string');
  }

  let formattedCurrency;

  if (currency !== 'BTC') {
    formattedCurrency = new Intl.NumberFormat(locale, {
      style: 'currency',
      currency,
      minimumFractionDigits: 2,
    }).format(amount);
  } else {
    // going to use USD just to know the localized placement of the $, which we'll swap
    // out with the Bitcoin symbol
    formattedCurrency = new Intl.NumberFormat(locale, {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 8,
    }).format(amount);

    // Using the ฿ char for the Bitcoin symbol which will be replaced by the real Bitcoin symbol
    // once we bring in a Bitcoin font, e.g:
    // http://www.righto.com/2015/02/how-to-display-bitcoin-symbol-using_14.html
    formattedCurrency = formattedCurrency.replace('$', '฿');
  }

  return formattedCurrency;
}

let exchangeRates = {};

export function fetchExchangeRates(options = {}) {
  const xhr = $.get(app.getServerUrl('ob/exchangerates/'), options)
    .done((data) => (exchangeRates = data));

  events.trigger('fetching-exchange-rates', { xhr });

  return xhr;
}

export function getExchangeRate(currency) {
  if (!currency) {
    throw new Error('Please provide a currency.');
  }

  return exchangeRates[currency];
}

export function NoExchangeRateDataError(message) {
  this.message = message || 'Missing exchange rate data';
  this.name = 'NoExchangeRateDataError';
  this.stack = (new Error()).stack;
}

NoExchangeRateDataError.prototype = Object.create(Error.prototype);
NoExchangeRateDataError.prototype.constructor = NoExchangeRateDataError;

// todo: unit test me
// probably need sinon to stub / mock fetchExchangeRates
export function convertCurrency(amount, fromCur, toCur) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number');
  }

  if (isNaN(amount)) {
    throw new Error('Please provide an amount that is not NaN');
  }

  if (typeof fromCur !== 'string') {
    throw new Error('Please provide a fromCur as a string');
  }

  if (typeof toCur !== 'string') {
    throw new Error('Please provide a toCur as a string');
  }

  if (fromCur === toCur) {
    return amount;
  }

  if (!exchangeRates[fromCur]) {
    throw new NoExchangeRateDataError(`We do not have exchange rate data for ${fromCur}.`);
  }

  if (!exchangeRates[toCur]) {
    throw new NoExchangeRateDataError(`We do not have exchange rate data for ${toCur}.`);
  }

  return amount / (getExchangeRate(fromCur) / getExchangeRate(toCur));
}

// todo: unit test me
// probably need sinon to stub / mock fetchExchangeRates
export function convertAndFormatCurrency(amount, fromCur, toCur, options = {}) {
  const opts = {
    locale: app.settings.get('language'),
    skipConvertIfNoExchangeRateData: true,
    ...options,
  };

  let convertedAmt;
  let outputFormat = toCur;

  try {
    convertedAmt = convertCurrency(amount, fromCur, toCur);
  } catch (e) {
    if (e instanceof NoExchangeRateDataError && opts.skipConvertIfNoExchangeRateData) {
      // We'll use an unconverted amount
      convertedAmt = amount;
      outputFormat = fromCur;
    } else {
      throw e;
    }
  }

  return formatCurrency(convertedAmt, outputFormat, opts.locale);
}
<commit_msg>added some comments to currency.js<commit_after>import app from '../app';
import $ from 'jquery';
import { Events } from 'backbone';

const events = {
  ...Events,
};

export { events };

/**
 * Converts the amount from a decimal to an integer. If the
 * currency code is BTC, it will convert to Satoshi.
 */
export function decimalToInteger(amount, isBtc = false) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number.');
  }

  let updatedAmount = amount;

  if (isBtc) {
    updatedAmount = Math.round(amount * 100000000);
  } else {
    updatedAmount = Math.round(amount * 100);
  }

  return updatedAmount;
}

/**
 * Converts the amount from an integer to a decimal, rounding
 * to 2 decimal places. If the currency code is BTC, it will
 * convert from Satoshi to BTC.
 */
export function integerToDecimal(amount, isBtc = false) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number.');
  }

  let updatedAmount = amount;

  if (isBtc) {
    updatedAmount = Number((amount / 100000000).toFixed(8));
  } else {
    updatedAmount = Number((amount / 100).toFixed(2));
  }

  return updatedAmount;
}

/**
 * Will take a number and return a string version of the number
 * with the appropriate number of decimal places based on whether
 * the number represents a BTC or fiat price.
 *
 * This differs from formatCurrency in that this does not localize
 * the number at all. It simply returns the value with the
 * appropriate number of decimal place, e.g:
 *
 * formatPrice(123.456, false) // "123.46"
 * formatPrice(123.456, true)  // "123.45600000"
 *
 * It is more useful for <input>'s because we are not
 * localizing the numbers in them.
 *
 * todo: add this as a template helper; perhaps there's
 * a better name for this function?
 */
export function formatPrice(price, isBtc = false) {
  if (typeof price !== 'number') {
    throw new Error('Please provide a price as a number');
  }

  if (isNaN(price)) {
    throw new Error('Please provide a price that is not NaN');
  }

  const decimalPlaces = isBtc ? 8 : 2;

  return price.toFixed(decimalPlaces);
}

/**
 * Will format an amount in the given currency into the format
 * appropriate for the given locale.
 */
// todo: check currency is one of our currencies
export function formatCurrency(amount, currency, locale = app.settings.get('language')) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number');
  }

  if (isNaN(amount)) {
    throw new Error('Please provide an amount that is not NaN');
  }

  if (typeof locale !== 'string') {
    throw new Error('Please provide a locale as a string');
  }

  if (typeof currency !== 'string') {
    throw new Error('Please provide a currency as a string');
  }

  let formattedCurrency;

  if (currency !== 'BTC') {
    formattedCurrency = new Intl.NumberFormat(locale, {
      style: 'currency',
      currency,
      minimumFractionDigits: 2,
    }).format(amount);
  } else {
    // going to use USD just to know the localized placement of the $, which we'll swap
    // out with the Bitcoin symbol
    formattedCurrency = new Intl.NumberFormat(locale, {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 8,
    }).format(amount);

    // Using the ฿ char for the Bitcoin symbol which will be replaced by the real Bitcoin symbol
    // once we bring in a Bitcoin font, e.g:
    // http://www.righto.com/2015/02/how-to-display-bitcoin-symbol-using_14.html
    formattedCurrency = formattedCurrency.replace('$', '฿');
  }

  return formattedCurrency;
}

let exchangeRates = {};

/**
 * Will fetch exchange rate data from the server. This is already called
 * on an interval via exchangeRateSyncer.js, so it's unlikely you would
 * need to call this method. Instead access cached values via getExchangeRate()
 * or more commonly convertCurrency().
 */
export function fetchExchangeRates(options = {}) {
  const xhr = $.get(app.getServerUrl('ob/exchangerates/'), options)
    .done((data) => (exchangeRates = data));

  events.trigger('fetching-exchange-rates', { xhr });

  return xhr;
}

export function getExchangeRate(currency) {
  if (!currency) {
    throw new Error('Please provide a currency.');
  }

  return exchangeRates[currency];
}

export function NoExchangeRateDataError(message) {
  this.message = message || 'Missing exchange rate data';
  this.name = 'NoExchangeRateDataError';
  this.stack = (new Error()).stack;
}

NoExchangeRateDataError.prototype = Object.create(Error.prototype);
NoExchangeRateDataError.prototype.constructor = NoExchangeRateDataError;

/**
 * Converts an amount from one currency to another based on exchange
 * rate data.
 */
// todo: unit test me
// probably need sinon to stub / mock fetchExchangeRates
export function convertCurrency(amount, fromCur, toCur) {
  if (typeof amount !== 'number') {
    throw new Error('Please provide an amount as a number');
  }

  if (isNaN(amount)) {
    throw new Error('Please provide an amount that is not NaN');
  }

  if (typeof fromCur !== 'string') {
    throw new Error('Please provide a fromCur as a string');
  }

  if (typeof toCur !== 'string') {
    throw new Error('Please provide a toCur as a string');
  }

  if (fromCur === toCur) {
    return amount;
  }

  if (!exchangeRates[fromCur]) {
    throw new NoExchangeRateDataError(`We do not have exchange rate data for ${fromCur}.`);
  }

  if (!exchangeRates[toCur]) {
    throw new NoExchangeRateDataError(`We do not have exchange rate data for ${toCur}.`);
  }

  return amount / (getExchangeRate(fromCur) / getExchangeRate(toCur));
}

/**
 * Convenience function to both convert and format a currency amount using
 * convertCurrency() and formatCurrency().
 */
// todo: unit test me
// probably need sinon to stub / mock fetchExchangeRates
export function convertAndFormatCurrency(amount, fromCur, toCur, options = {}) {
  const opts = {
    locale: app.settings.get('language'),
    skipConvertIfNoExchangeRateData: true,
    ...options,
  };

  let convertedAmt;
  let outputFormat = toCur;

  try {
    convertedAmt = convertCurrency(amount, fromCur, toCur);
  } catch (e) {
    if (e instanceof NoExchangeRateDataError && opts.skipConvertIfNoExchangeRateData) {
      // We'll use an unconverted amount
      convertedAmt = amount;
      outputFormat = fromCur;
    } else {
      throw e;
    }
  }

  return formatCurrency(convertedAmt, outputFormat, opts.locale);
}
<|endoftext|>


<commit_before>define(['../lang/isFunction', '../object/hasOwn'], function(isFunction, hasOwn){

    /**
     * Creates a function that memoizes the result of `fn`. If `resolver` is
     * provided it determines the cache key for storing the result based on the
     * arguments provided to the memoized function. By default, the first argument
     * provided to the memoized function is coerced to a string and used as the
     * cache key. The `fn` is invoked with the `this` binding of the memoized
     * function.
     *
     * @param {Function} fn Function to have its output memoized.
     * @param {Function} context Function to resolve the cache key.
     * @return {Function} Returns the new memoized function.
     */
    function memoize(fn, resolver) {
        if (!isFunction(fn) || (resolver && !isFunction(resolver))) {
            throw new TypeError('Expected a function');
        }

        var memoized = function() {
            var cache = memoized.cache,
                key = resolver ? resolver.apply(this, arguments) : arguments[0];

            if (hasOwn(cache, key)) {
                return cache[key];
            }
            var result = fn.apply(this, arguments);
            cache[key] = result;
            return result;
        };

        memoized.cache = {};

        return memoized;
    }

    return memoize;
});

<commit_msg>Attribution.<commit_after>define(['../lang/isFunction', '../object/hasOwn'], function(isFunction, hasOwn){

    /**
     * Creates a function that memoizes the result of `fn`. If `resolver` is
     * provided it determines the cache key for storing the result based on the
     * arguments provided to the memoized function. By default, the first argument
     * provided to the memoized function is coerced to a string and used as the
     * cache key. The `fn` is invoked with the `this` binding of the memoized
     * function. Modified from lodash.
     *
     * @param {Function} fn Function to have its output memoized.
     * @param {Function} context Function to resolve the cache key.
     * @return {Function} Returns the new memoized function.
     */
    function memoize(fn, resolver) {
        if (!isFunction(fn) || (resolver && !isFunction(resolver))) {
            throw new TypeError('Expected a function');
        }

        var memoized = function() {
            var cache = memoized.cache,
                key = resolver ? resolver.apply(this, arguments) : arguments[0];

            if (hasOwn(cache, key)) {
                return cache[key];
            }
            var result = fn.apply(this, arguments);
            cache[key] = result;
            return result;
        };

        memoized.cache = {};

        return memoized;
    }

    return memoize;
});

<|endoftext|>


<commit_before>'use strict';

// Declare app level module which depends on filters, and services
angular.module('hyphe', [
  'ngRoute'
  ,'ui.bootstrap'
  // ,'angulartics'
  // ,'angulartics.google.analytics'
  ,'hyphe.conf'
  ,'hyphe.filters'
  ,'hyphe.services'
  ,'hyphe.service_utils'
  ,'hyphe.service_hyphe_api'
  ,'hyphe.service_glossary'
  ,'hyphe.directives'
  ,'hyphe.controllers'
])

// Route
.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/login', {templateUrl: 'views/login.html', controller: 'Login'});
  $routeProvider.when('/login2', {templateUrl: 'views/login2.html', controller: 'Login2'});
  $routeProvider.when('/overview', {templateUrl: 'views/overview.html', controller: 'Overview'});
  $routeProvider.when('/importurls', {templateUrl: 'views/importurls.html', controller: 'ImportUrls'});
  $routeProvider.when('/definewebentities', {templateUrl: 'views/definewebentities.html', controller: 'DefineWebEntities'});
  $routeProvider.when('/newCrawl', {templateUrl: 'views/newCrawl.html', controller: 'NewCrawl'});
  $routeProvider.when('/checkStartPages', {templateUrl: 'views/checkStartPages.html', controller: 'CheckStartPages'});
  $routeProvider.when('/scheduleCrawls', {templateUrl: 'views/scheduleCrawls.html', controller: 'scheduleCrawls'});
  $routeProvider.when('/monitorCrawls', {templateUrl: 'views/monitorCrawls.html', controller: 'monitorCrawls'});
  $routeProvider.when('/listWebentities', {templateUrl: 'views/listWebentities.html', controller: 'listWebentities'});
  $routeProvider.when('/export', {templateUrl: 'views/export.html', controller: 'export'});
  $routeProvider.when('/settings', {templateUrl: 'views/settings.html', controller: 'settings'});
  $routeProvider.when('/network', {templateUrl: 'views/network.html', controller: 'network'});
  $routeProvider.when('/prospect', {templateUrl: 'views/prospect.html', controller: 'prospect'});
  $routeProvider.otherwise({redirectTo: '/login'});
}])

/*// Analytics
.config(['$analyticsProvider', function ($analyticsProvider) {
  $analyticsProvider.virtualPageviews(true);
  console.log('Analytics provider', $analyticsProvider)
}]);*/

angular.module('hyphe.analytics', [])
.run(['googleAnalyticsId', function(googleAnalyticsId) {

  if(googleAnalyticsId) {
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', googleAnalyticsId, 'auto');
    ga('send', 'pageview');
  }
}])

/*.run(['$analytics', function($analytics) {
  window.a = $analytics
  $analytics.pageTrack('/test/url');
  console.log('Analytics', $analytics)
}])*/
  <commit_msg>analytics fixed<commit_after>'use strict';

// Declare app level module which depends on filters, and services
angular.module('hyphe', [
  'ngRoute'
  ,'ui.bootstrap'
  ,'angulartics'
  ,'angulartics.google.analytics'
  ,'hyphe.analytics'
  ,'hyphe.conf'
  ,'hyphe.filters'
  ,'hyphe.services'
  ,'hyphe.service_utils'
  ,'hyphe.service_hyphe_api'
  ,'hyphe.service_glossary'
  ,'hyphe.directives'
  ,'hyphe.controllers'
])

// Route
.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/login', {templateUrl: 'views/login.html', controller: 'Login'});
  $routeProvider.when('/login2', {templateUrl: 'views/login2.html', controller: 'Login2'});
  $routeProvider.when('/overview', {templateUrl: 'views/overview.html', controller: 'Overview'});
  $routeProvider.when('/importurls', {templateUrl: 'views/importurls.html', controller: 'ImportUrls'});
  $routeProvider.when('/definewebentities', {templateUrl: 'views/definewebentities.html', controller: 'DefineWebEntities'});
  $routeProvider.when('/newCrawl', {templateUrl: 'views/newCrawl.html', controller: 'NewCrawl'});
  $routeProvider.when('/checkStartPages', {templateUrl: 'views/checkStartPages.html', controller: 'CheckStartPages'});
  $routeProvider.when('/scheduleCrawls', {templateUrl: 'views/scheduleCrawls.html', controller: 'scheduleCrawls'});
  $routeProvider.when('/monitorCrawls', {templateUrl: 'views/monitorCrawls.html', controller: 'monitorCrawls'});
  $routeProvider.when('/listWebentities', {templateUrl: 'views/listWebentities.html', controller: 'listWebentities'});
  $routeProvider.when('/export', {templateUrl: 'views/export.html', controller: 'export'});
  $routeProvider.when('/settings', {templateUrl: 'views/settings.html', controller: 'settings'});
  $routeProvider.when('/network', {templateUrl: 'views/network.html', controller: 'network'});
  $routeProvider.when('/prospect', {templateUrl: 'views/prospect.html', controller: 'prospect'});
  $routeProvider.otherwise({redirectTo: '/login'});
}])

// Analytics
.config(['$analyticsProvider', function ($analyticsProvider) {
  $analyticsProvider.virtualPageviews(true);
}])

angular.module('hyphe.analytics', [])
.run(['googleAnalyticsId', function(googleAnalyticsId) {

  if(googleAnalyticsId) {
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', googleAnalyticsId, 'auto');
  }

}])

  <|endoftext|>


<commit_before>var View = require('ampersand-view');
var NProgress = require('nprogress');

//------------------------------------------------------------------------------

NProgress.configure({
  minimum: 0.4,
  trickleRate: 0.1,
  trickleSpeed: 800
});

//------------------------------------------------------------------------------

var InputView = View.extend({
  template: function() { return this.el.outerHTML },

  events: {
    'input': 'valueChanged',
    'change': 'valueChanged'
  },

  bindings: {
    'model.min': {
      type: 'attribute',
      name: 'min'
    },
    'model.max': {
      type: 'attribute',
      name: 'max'
    },
    'model.boundedValue': {
      type: 'value',
    },
  },

  valueChanged: function() {
    this.model.value = +this.el.value;
  }
});

var ControlsView = View.extend({
  template: require('../templates/controls.hbs'),

  autoRender: true,
  alreadyWarned: false,

  initialize: function() {
    this.model.subject.on('loading', function() {
      NProgress.start();
    });

    this.model.subject.on('done', function() {
      NProgress.done();
    });
  },

  events: {
    "click #phi-link": "selectSubject",
    "click #pi-link": "selectSubject",
    "click #e-link": "selectSubject",

    'click #digits-radio input': 'onDigitsClick',
    'change #digits-radio input': 'onDigitsChange'
  },

  bindings: {
    "model.subject.name": {
      type: "switchClass",
      name: "active",
      cases: {
        "phi": "#phi-link",
        "pi": "#pi-link",
        "e": "#e-link"
      }
    }
  },

  subviews: {
    rowsLabelInput: {
      selector: "#rows-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.rows });
      }
    },
    columnsLabelInput: {
      selector: "#columns-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.columns });
      }
    },
    radiusLabelInput: {
      selector: "#radius-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.radius });
      }
    },
    spacingLabelInput: {
      selector: "#spacing-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.spacing });
      }
    },
    columnsSlider: {
      selector: '#columns-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.columns });
      }
    },
    rowsSlider: {
      selector: '#rows-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.rows });
      }
    },
    spacingSlider: {
      selector: '#spacing-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.spacing });
      }
    },
    radiusSlider: {
      selector: '#radius-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.radius });
      }
    }
  },

  selectSubject: function(e) {
    e.preventDefault();

    switch (this, e.target.hash) {
      case '#phi':
        this.model.subject.setPhi();
        break;
      case '#pi':
        this.model.subject.setPi();
				break;
			case '#e':
        this.model.subject.setE();
				break;
      default:
        console.log('selectSubject: error');
    }
  },

  onDigitsClick: function(e) {
    var value = +e.target.value;
    var warning = 'Displaying 100k digits or more, can be very resource ' +
      'intensive, even on a powerfull computer. Are you sure you would like ' +
      'to proceed?';

    if (value > 4 && !this.alreadyWarned) {
      if (confirm(warning)) {
        this.alreadyWarned = true;
      } else {
        e.preventDefault();
        return false;
      }
    }
  },

  onDigitsChange: function(e) {
    var value = +e.target.value;

    this.model.subject.setDigits(value);
  }
});

module.exports = ControlsView;
<commit_msg>Updates ControlsView<commit_after>var View = require('ampersand-view');
var NProgress = require('nprogress');

//------------------------------------------------------------------------------

NProgress.configure({
  minimum: 0.4,
  trickleRate: 0.1,
  trickleSpeed: 800
});

//------------------------------------------------------------------------------

var InputView = View.extend({
  template: function() { return this.el.outerHTML },

  events: {
    'input': 'valueChanged',
    'change': 'valueChanged'
  },

  bindings: {
    'model.min': {
      type: 'attribute',
      name: 'min'
    },
    'model.max': {
      type: 'attribute',
      name: 'max'
    },
    'model.boundedValue': {
      type: 'value',
    },
  },

  valueChanged: function() {
    this.model.value = +this.el.value;
  }
});

var ControlsView = View.extend({
  template: require('../templates/controls.hbs'),

  autoRender: true,
  alreadyWarned: false,

  initialize: function() {
    this.model.subject.on('loading', function() {
      NProgress.start();
    });

    this.model.subject.on('done', function() {
      NProgress.done();
    });
  },

  events: {
    "click #phi-link": "selectSubject",
    "click #pi-link": "selectSubject",
    "click #e-link": "selectSubject",

    'click #digits-radio input': 'onDigitsClick',
    'change #digits-radio input': 'onDigitsChange'
  },

  bindings: {
    "model.subject.name": {
      type: "switchClass",
      name: "active",
      cases: {
        "phi": "#phi-link",
        "pi": "#pi-link",
        "e": "#e-link"
      }
    }
  },

  subviews: {
    rowsLabelInput: {
      selector: "#rows-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.rows });
      }
    },
    columnsLabelInput: {
      selector: "#columns-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.columns });
      }
    },
    radiusLabelInput: {
      selector: "#radius-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.radius });
      }
    },
    spacingLabelInput: {
      selector: "#spacing-label-input input",
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.spacing });
      }
    },
    columnsSlider: {
      selector: '#columns-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.columns });
      }
    },
    rowsSlider: {
      selector: '#rows-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.rows });
      }
    },
    spacingSlider: {
      selector: '#spacing-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.spacing });
      }
    },
    radiusSlider: {
      selector: '#radius-slider',
      prepareView: function(el) {
        return new InputView({ el: el, model: this.model.radius });
      }
    }
  },

  selectSubject: function(e) {
    e.preventDefault();

    switch (this, e.target.hash) {
      case '#phi':
        this.model.subject.setPhi();
        break;
      case '#pi':
        this.model.subject.setPi();
				break;
			case '#e':
        this.model.subject.setE();
				break;
      default:
        console.log('selectSubject: error');
    }
  },

  onDigitsClick: function(e) {
    var value = +e.target.value;
    var warning = 'Displaying 100k digits or more, can be very resource ' +
      'intensive, even on a powerfull computer. Are you sure you would like ' +
      'to proceed?';

    if (value > 4 && !this.alreadyWarned) {
      if (confirm(warning)) {
        this.alreadyWarned = true;
      } else {
        e.preventDefault();
        return false;
      }
    }
  },

  onDigitsChange: function(e) {
    this.model.subject.digits = +e.target.value;
  }
});

module.exports = ControlsView;
<|endoftext|>


<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Displays a page as a modal dialog with inset appearance and overlay background
//>>label: Dialogs
//>>group: Widgets
//>>css.structure: ../css/structure/jquery.mobile.dialog.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery", "../jquery.mobile.widget" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {

$.widget( "mobile.dialog", $.mobile.widget, {
	options: {
		closeBtnText: "Close",
		overlayTheme: "a",
		initSelector: ":jqmData(role='dialog')"
	},
	_create: function() {
		var self = this,
			$el = this.element,
			headerCloseButton = $( ""+ this.options.closeBtnText + "" ),
			dialogWrap = $( "
", {
					"role" : "dialog",
					"class" : "ui-dialog-contain ui-corner-all ui-overlay-shadow"
				});

		$el.addClass( "ui-dialog ui-overlay-" + this.options.overlayTheme );

		// Class the markup for dialog styling
		// Set aria role
		$el
			.wrapInner( dialogWrap )
			.children()
				.find( ":jqmData(role='header')" )
					.prepend( headerCloseButton );

		// this must be an anonymous function so that select menu dialogs can replace
		// the close method. This is a change from previously just defining data-rel=back
		// on the button and letting nav handle it
		//
		// Use click rather than vclick in order to prevent the possibility of unintentionally
		// reopening the dialog if the dialog opening item was directly under the close button.
		headerCloseButton.bind( "click", function() {
			self.close();
		});

		/* bind events
			- clicks and submits should use the closing transition that the dialog opened with
				unless a data-transition is specified on the link/form
			- if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally
		*/
		$el.bind( "vclick submit", function( event ) {
			var $target = $( event.target ).closest( event.type === "vclick" ? "a" : "form" ),
				active;

			if ( $target.length && !$target.jqmData( "transition" ) ) {

				active = $.mobile.urlHistory.getActive() || {};

				$target.attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) )
					.attr( "data-" + $.mobile.ns + "direction", "reverse" );
			}
		})
		.bind( "pagehide", function( e, ui ) {
			$( this ).find( "." + $.mobile.activeBtnClass ).not( ".ui-slider-bg" ).removeClass( $.mobile.activeBtnClass );
		})
		// Override the theme set by the page plugin on pageshow
		.bind( "pagebeforeshow", function() {
			self._isCloseable = true;
			if ( self.options.overlayTheme ) {
				self.element
					.page( "removeContainerBackground" )
					.page( "setContainerBackground", self.options.overlayTheme );
			}
		});
	},

	// Close method goes back in history
	close: function() {
		var dst;

		if ( this._isCloseable ) {
			this._isCloseable = false;
			if ( $.mobile.hashListeningEnabled ) {
				$.mobile.back();
			} else {
				dst = $.mobile.urlHistory.getPrev().url;
				if ( !$.mobile.path.isPath( dst ) ) {
					dst = $.mobile.path.makeUrlAbsolute( "#" + dst );
				}

				$.mobile.changePage( dst, { changeHash: false, fromHashChange: true } );
			}
		}
	}
});

//auto self-init widgets
$( document ).delegate( $.mobile.dialog.prototype.options.initSelector, "pagecreate", function() {
	$.mobile.dialog.prototype.enhance( this );
});

})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>Added option corners for dialogs<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Displays a page as a modal dialog with inset appearance and overlay background
//>>label: Dialogs
//>>group: Widgets
//>>css.structure: ../css/structure/jquery.mobile.dialog.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery", "../jquery.mobile.widget" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {

$.widget( "mobile.dialog", $.mobile.widget, {
	options: {
		closeBtnText: "Close",
		overlayTheme: "a",
		corners: true,
		initSelector: ":jqmData(role='dialog')"
	},
	_create: function() {
		var self = this,
			$el = this.element,
			headerCloseButton = $( ""+ this.options.closeBtnText + "" ),
			cornerClass = !!this.options.corners ? " ui-corner-all" : "",
			dialogWrap = $( "
", {
					"role" : "dialog",
					"class" : "ui-dialog-contain ui-overlay-shadow" + cornerClass
				});

		$el.addClass( "ui-dialog ui-overlay-" + this.options.overlayTheme );

		// Class the markup for dialog styling
		// Set aria role
		$el
			.wrapInner( dialogWrap )
			.children()
				.find( ":jqmData(role='header')" )
					.prepend( headerCloseButton );

		// this must be an anonymous function so that select menu dialogs can replace
		// the close method. This is a change from previously just defining data-rel=back
		// on the button and letting nav handle it
		//
		// Use click rather than vclick in order to prevent the possibility of unintentionally
		// reopening the dialog if the dialog opening item was directly under the close button.
		headerCloseButton.bind( "click", function() {
			self.close();
		});

		/* bind events
			- clicks and submits should use the closing transition that the dialog opened with
				unless a data-transition is specified on the link/form
			- if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally
		*/
		$el.bind( "vclick submit", function( event ) {
			var $target = $( event.target ).closest( event.type === "vclick" ? "a" : "form" ),
				active;

			if ( $target.length && !$target.jqmData( "transition" ) ) {

				active = $.mobile.urlHistory.getActive() || {};

				$target.attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) )
					.attr( "data-" + $.mobile.ns + "direction", "reverse" );
			}
		})
		.bind( "pagehide", function( e, ui ) {
			$( this ).find( "." + $.mobile.activeBtnClass ).not( ".ui-slider-bg" ).removeClass( $.mobile.activeBtnClass );
		})
		// Override the theme set by the page plugin on pageshow
		.bind( "pagebeforeshow", function() {
			self._isCloseable = true;
			if ( self.options.overlayTheme ) {
				self.element
					.page( "removeContainerBackground" )
					.page( "setContainerBackground", self.options.overlayTheme );
			}
		});
	},

	// Close method goes back in history
	close: function() {
		var dst;

		if ( this._isCloseable ) {
			this._isCloseable = false;
			if ( $.mobile.hashListeningEnabled ) {
				$.mobile.back();
			} else {
				dst = $.mobile.urlHistory.getPrev().url;
				if ( !$.mobile.path.isPath( dst ) ) {
					dst = $.mobile.path.makeUrlAbsolute( "#" + dst );
				}

				$.mobile.changePage( dst, { changeHash: false, fromHashChange: true } );
			}
		}
	}
});

//auto self-init widgets
$( document ).delegate( $.mobile.dialog.prototype.options.initSelector, "pagecreate", function() {
	$.mobile.dialog.prototype.enhance( this );
});

})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>var express = require('express'), fs = require('fs');
var _ = require('./underscore')._;
var app = module.exports = express.createServer();
var files = 'project'; // TODO: put in config

function jsonp(obj, req) {
  return req.param('jsoncallback') + '(' + JSON.stringify(obj) + ')';
}

function safePath(path) {
  // return True or path.find('..') == -1 and not re.search('[^\w.-_\/]', path)
}

app.get('/', function(req, res, params) {
  res.send({'api':'basic','version':1.0});
});

app.get('/list', function(req, res) {
  res.send(
    jsonp({
      'status': true,
      'data': _.select(fs.readdirSync(files),
        function(dir) {
          return _.any(
            fs.readdirSync(files + '/' + dir),
            function(filename) {
              return filename.match('.mml')
            }
          )
        }
      )
    }, req)
  );
});

app.get('/file', function(req, res) {
  var path = req.param('filename');
  try {
    res.send(jsonp("" + fs.readFileSync(path), req));
  }
  catch(Exception) {
    res.send(jsonp(
    {
        'status':false,
        'data':'The file (' + req.param('filename') +
      ') could not be found. Exception: ' + Exception
    }, req))
  }
});

/*
app.post('/file', function(req, res) {
  path = os.path.join(options.files, self.get_argument('filename'))
  //if (self.safePath(path)):
  method = req.param('method')
  data = req.param('data')
  if (method == 'delete') {
    this.rm(path);
    res.send(jsonp({ 'status': True }, req))
  }
  else {
    // if (os.path.isdir(os.path.dirname(path))):
    // os.makedirs(os.path.dirname(path))
    if (fs.fstatSync(path))) {
      buffer = fs.writeFile(path, data,
        function() {
          res.send(jsonp({ 'status': true }, req))
        }
      )
    }
    else {
      res.send(jsonp(
      {
        'status': False,
        'data': 'Could not write file'
      }, req)
      )
    }
  }
}
*/

app.get('/mtime', function(req, res) {
  var path = req.param('filename');
  try {
    fstat = fs.statSync(path)
    res.send(jsonp("" + fstat.mtime, req));
  }
  catch(Exception) {
    res.send(jsonp(
    {
        'status':false,
        'data':'The file (' + req.param('filename') +
      ') could not be found. Exception: ' + Exception
    }, req))
  }
});

app.listen(8889);
<commit_msg>Less sync<commit_after>var express = require('express'), fs = require('fs');
var _ = require('./underscore')._;
var app = module.exports = express.createServer();
var files = 'project'; // TODO: put in config

function jsonp(obj, req) {
  return req.param('jsoncallback') + '(' + JSON.stringify(obj) + ')';
}

function safePath(path) {
  // return True or path.find('..') == -1 and not re.search('[^\w.-_\/]', path)
}

app.get('/', function(req, res, params) {
  res.send({'api':'basic','version':1.0});
});

app.get('/list', function(req, res) {
  res.send(
    jsonp({
      'status': true,
      'data': _.select(fs.readdirSync(files),
        function(dir) {
          return _.any(
            fs.readdirSync(files + '/' + dir),
            function(filename) {
              return filename.match('.mml')
            }
          )
        }
      )
    }, req)
  );
});

app.get('/file', function(req, res) {
  var path = req.param('filename');
  try {
    fs.readFile(path, function(err, data) {
      res.send(jsonp("" + data, req));
    })
  }
  catch(Exception) {
    res.send(jsonp(
    {
        'status':false,
        'data':'The file (' + req.param('filename') +
      ') could not be found. Exception: ' + Exception
    }, req))
  }
});

/*
app.post('/file', function(req, res) {
  path = os.path.join(options.files, self.get_argument('filename'))
  //if (self.safePath(path)):
  method = req.param('method')
  data = req.param('data')
  if (method == 'delete') {
    this.rm(path);
    res.send(jsonp({ 'status': True }, req))
  }
  else {
    // if (os.path.isdir(os.path.dirname(path))):
    // os.makedirs(os.path.dirname(path))
    if (fs.fstatSync(path))) {
      buffer = fs.writeFile(path, data,
        function() {
          res.send(jsonp({ 'status': true }, req))
        }
      )
    }
    else {
      res.send(jsonp(
      {
        'status': False,
        'data': 'Could not write file'
      }, req)
      )
    }
  }
}
*/

app.get('/mtime', function(req, res) {
  var path = req.param('filename');
  try {
    fs.stat(path, function(err, stats) {
      res.send(jsonp("" + stats.mtime, req));
    });
  }
  catch(Exception) {
    res.send(jsonp(
    {
        'status':false,
        'data':'The file (' + req.param('filename') +
      ') could not be found. Exception: ' + Exception
    }, req))
  }
});

app.listen(8889);
<|endoftext|>


<commit_before>const Errors = require('common-errors');
const Promise = require('bluebird');
const paypal = require('paypal-rest-sdk');
const key = require('../../redisKey');
const ld = require('lodash');
const paypalPaymentExecute = Promise.promisify(paypal.payment.execute, { context: paypal.payment });

function saleExecute(message) {
  const { _config, redis, amqp } = this;
  const promise = Promise.bind(this);

  function sendRequest() {
    return paypalPaymentExecute(message.payment_id, { payer_id: message.payer_id }, _config.paypal);
  }

  function updateRedis(sale) {
    if (sale.state !== 'approved') {
      throw new Errors.HttpStatusError(412, `paypal returned "${sale.state}" on the sale`);
    }

    const saleKey = key('sales-data', sale.id);

    return redis
      .pipeline()
      .hget(saleKey, 'owner')
      .hmset(saleKey, ld.mapValues({ sale, update_time: sale.update_time }, JSON.stringify, JSON))
      .exec()
      .spread(owner => {
        return { sale, username: owner[1] };
      });
  }

  function updateMetadata({ sale, username }) {
    const models = sale.transactions[0].item_list.items[0].quantity;
    const path = _config.users.prefix + '.' + _config.users.postfix.updateMetadata;

    const updateRequest = {
      username,
      audience: _config.users.audience,
      $incr: {
        models,
      },
    };

    return amqp
      .publishAndWait(path, updateRequest, { timeout: 5000 })
      .return(sale);
  }

  return promise.then(sendRequest).then(updateRedis).then(updateMetadata);
}

module.exports = saleExecute;
<commit_msg>Fix sale updateMetadata<commit_after>const Errors = require('common-errors');
const Promise = require('bluebird');
const paypal = require('paypal-rest-sdk');
const key = require('../../redisKey');
const ld = require('lodash');
const paypalPaymentExecute = Promise.promisify(paypal.payment.execute, { context: paypal.payment });

function saleExecute(message) {
  const { _config, redis, amqp } = this;
  const promise = Promise.bind(this);

  function sendRequest() {
    return paypalPaymentExecute(message.payment_id, { payer_id: message.payer_id }, _config.paypal);
  }

  function updateRedis(sale) {
    if (sale.state !== 'approved') {
      throw new Errors.HttpStatusError(412, `paypal returned "${sale.state}" on the sale`);
    }

    const saleKey = key('sales-data', sale.id);

    return redis
      .pipeline()
      .hget(saleKey, 'owner')
      .hmset(saleKey, ld.mapValues({ sale, update_time: sale.update_time }, JSON.stringify, JSON))
      .exec()
      .spread(owner => {
        return { sale, username: owner[1] };
      });
  }

  function updateMetadata({ sale, username }) {
    const models = sale.transactions[0].item_list.items[0].quantity;
    const path = _config.users.prefix + '.' + _config.users.postfix.updateMetadata;

    const updateRequest = {
      username,
      audience: _config.users.audience,
      metadata: {
        $incr: {
          models,
        },
      },
    };

    return amqp
      .publishAndWait(path, updateRequest, { timeout: 5000 })
      .return(sale);
  }

  return promise.then(sendRequest).then(updateRedis).then(updateMetadata);
}

module.exports = saleExecute;
<|endoftext|>


<commit_before>'use strict';

import querystring from 'querystring';

/**
 * mongodb socket
 */
export default class extends think.adapter.socket {
  /**
   * init
   * @param  {Object} config []
   * @return {}        []
   */
  init(config){
    super.init(config);

    this.config = think.extend({}, {
      host: '127.0.0.1',
      port: 27017
    }, config);
  }
  /**
   * get connection
   * @return {Promise} []
   */
  async getConnection(){
    if(this.connection){
      return this.connection;
    }
    let mongo = await think.npm('mongodb');
    let config = this.config;
    let auth = '';

    this.mongo = mongo;
    if(this.config.user){
      auth = `${config.user}:${config.pwd}@`;
    }
    // connection options
    // http://mongodb.github.io/node-mongodb-native/2.0/tutorials/urls/
    let options = '';
    if(config.options){
      options = '?' + querystring.stringify(config.options);
    }
    let str = `mongodb://${auth}${config.host}:${config.port}/${config.name}${options}`;

    return think.await(str, () => {
      let fn = think.promisify(mongo.MongoClient.connect, mongo.MongoClient);
      let promise = fn(str, this.config).then(connection => {
        //set logger level
        if(config.log_level){
          mongo.Logger.setLevel(config.log_level);
        }
        this.connection = connection;
        return connection;
      })
      let err = new Error(`mongodb://${auth}${config.host}:${config.port}`);
      return think.error(promise, err);
    });
  }
}<commit_msg>add connection information for mongodb<commit_after>'use strict';

import querystring from 'querystring';

/**
 * mongodb socket
 */
export default class extends think.adapter.socket {
  /**
   * init
   * @param  {Object} config []
   * @return {}        []
   */
  init(config){
    super.init(config);

    this.config = think.extend({}, {
      host: '127.0.0.1',
      port: 27017
    }, config);
  }
  /**
   * get connection
   * @return {Promise} []
   */
  async getConnection(){
    if(this.connection){
      return this.connection;
    }
    let mongo = await think.npm('mongodb');
    let config = this.config;
    let auth = '';

    this.mongo = mongo;
    if(this.config.user){
      auth = `${config.user}:${config.pwd}@`;
    }
    // connection options
    // http://mongodb.github.io/node-mongodb-native/2.0/tutorials/urls/
    let options = '';
    if(config.options){
      options = '?' + querystring.stringify(config.options);
    }
    let str = `mongodb://${auth}${config.host}:${config.port}/${config.name}${options}`;

    //log mongodb connection infomation
    if(this.config.log_connect){
      think.log(colors => {
        return `Connect mongodb with ` + colors.magenta(str);
      }, 'SOCKET');
    }

    return think.await(str, () => {
      let fn = think.promisify(mongo.MongoClient.connect, mongo.MongoClient);
      let promise = fn(str, this.config).then(connection => {
        //set logger level
        if(config.log_level){
          mongo.Logger.setLevel(config.log_level);
        }
        this.connection = connection;
        return connection;
      })
      let err = new Error(`mongodb://${auth}${config.host}:${config.port}`);
      return think.error(promise, err);
    });
  }
}<|endoftext|>


<commit_before>import Microcosm      from '../../Microcosm'
import React          from 'react'
import getDisplayName from './get-display-name'
import hoistStatics   from 'hoist-non-react-statics'
import shallowEqual   from './shallow-equal'

const defaults = {
  pure : true
}

export default function connect (mapStateToProps, options) {
  options = { ...defaults, ...options }

  const isPure = !!options.pure

  return function wrapWithConnect(WrappedComponent) {

    class Connect extends React.Component {

      constructor(props, context) {
        super(props, context)

        this.app   = props.app || context.app
        this.state = {}

        this.updatePropMap(props)
      }

      componentWillMount() {
        this.updateState()
      }

      componentDidMount() {
        this.app.listen(this.updateState, this)
      }

      componentWillUnmount() {
        this.app.ignore(this.updateState, this)
      }

      componentWillReceiveProps(nextProps) {
        if (isPure && shallowEqual(nextProps, this.props)) {
          return null
        }

        this.updatePropMap(nextProps)
        this.updateState()
      }

      updatePropMap(props) {
        this.propMap = mapStateToProps ? mapStateToProps(props) : {}
      }

      updateState() {
        let propMap   = this.propMap
        let nextState = {}

        for (let key in propMap) {
          nextState[key] = propMap[key](this.app.state)
        }

        if (isPure && shallowEqual(this.state, nextState)) {
          return null
        }

        this.setState(nextState)
      }

      render() {
        let { app, props, state } = this

        return React.createElement(WrappedComponent, {
          app,
          ref: props.via,
          ...props,
          ...state
        })
      }
    }

    Connect.displayName = `Connect(${getDisplayName(WrappedComponent)})`

    Connect.WrappedComponent = WrappedComponent

    Connect.contextTypes = {
      app: React.PropTypes.instanceOf(Microcosm)
    }

    Connect.propTypes = {
      app: React.PropTypes.instanceOf(Microcosm)
    }

    return hoistStatics(Connect, WrappedComponent)
  }
}
<commit_msg>Revert ref update to connect<commit_after>import Microcosm      from '../../Microcosm'
import React          from 'react'
import getDisplayName from './get-display-name'
import hoistStatics   from 'hoist-non-react-statics'
import shallowEqual   from './shallow-equal'

const defaults = {
  pure : true
}

export default function connect (mapStateToProps, options) {
  options = { ...defaults, ...options }

  const isPure = !!options.pure

  return function wrapWithConnect(WrappedComponent) {

    class Connect extends React.Component {

      constructor(props, context) {
        super(props, context)

        this.app   = props.app || context.app
        this.state = {}

        this.updatePropMap(props)
      }

      componentWillMount() {
        this.updateState()
      }

      componentDidMount() {
        this.app.listen(this.updateState, this)
      }

      componentWillUnmount() {
        this.app.ignore(this.updateState, this)
      }

      componentWillReceiveProps(nextProps) {
        if (isPure && shallowEqual(nextProps, this.props)) {
          return null
        }

        this.updatePropMap(nextProps)
        this.updateState()
      }

      updatePropMap(props) {
        this.propMap = mapStateToProps ? mapStateToProps(props) : {}
      }

      updateState() {
        let propMap   = this.propMap
        let nextState = {}

        for (let key in propMap) {
          nextState[key] = propMap[key](this.app.state)
        }

        if (isPure && shallowEqual(this.state, nextState)) {
          return null
        }

        this.setState(nextState)
      }

      render() {
        let { app, props, state } = this

        return React.createElement(WrappedComponent, {
          app,
          ...props,
          ...state
        })
      }
    }

    Connect.displayName = `Connect(${getDisplayName(WrappedComponent)})`

    Connect.WrappedComponent = WrappedComponent

    Connect.contextTypes = {
      app: React.PropTypes.instanceOf(Microcosm)
    }

    Connect.propTypes = {
      app: React.PropTypes.instanceOf(Microcosm)
    }

    return hoistStatics(Connect, WrappedComponent)
  }
}
<|endoftext|>


<commit_before>
"use strict";

export default angular.module('lollipop.convertValueToDate', [])
    /**
     * Factory returning a method that converts an array of valid date parts (e.g.
     * [yyyy, mm, dd]) into a `Date` object by calling the constructor.
     *
     * @param Array
     * @return Date
     */
    .factory('convertValueToDate', () => value => new (Function.prototype.bind.apply(Date, [null].concat(toConsumableArray(value))))())
    .name
});

function toConsumableArray(arr) {
    if (Array.isArray(arr)) {
        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
            arr2[i] = arr[i];
        }
        return arr2;
    } else {
        return Array.from(arr);
    }
};

<commit_msg>fix typo<commit_after>
"use strict";

export default angular.module('lollipop.convertValueToDate', [])
    /**
     * Factory returning a method that converts an array of valid date parts (e.g.
     * [yyyy, mm, dd]) into a `Date` object by calling the constructor.
     *
     * @param Array
     * @return Date
     */
    .factory('convertValueToDate', () => value => new (Function.prototype.bind.apply(Date, [null].concat(toConsumableArray(value))))())
    .name;

function toConsumableArray(arr) {
    if (Array.isArray(arr)) {
        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
            arr2[i] = arr[i];
        }
        return arr2;
    } else {
        return Array.from(arr);
    }
};

<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	User = mongoose.model('User'),
    Post = mongoose.model('Post'),
	_ = require('lodash');

/**
 * Create a Post
 */
exports.create = function(req, res) {
    var post = new Post(req.body);
    post.user = req.user;
    post.updated = Date.now();
    var message = null;

    post.save(function(err) {
        if (err) {
            return res.status(400).send({
            	message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.send(String(post._id));
        }
    });
};

/**
 * Show the current Post
 */
exports.read = function(req, res) {
    Post.findById(req.params.postId, function(err, post){
        if(!err && post){
            User.findOne({_id : post.user}).select('displayName roles school isActive').exec(function(err, user){
                if(err || !user.isActive){
                   res.status(400).send({ message: 'Post user not found'});
               }
               else{
                    var postObject =
                    {
                        _id: post._id,
                        __v: post.__v,
                        title: post.title,
                        abstract: post.abstract,
                        description: post.description,
                        location: post.location,
                        created: post.created,
                        updated: post.updated,
                        isActive: post.isActive
                    };

                    //user
                    User.findById(post.user).select('_id displayName roles school isActive').exec(function (err, owner) {
                        postObject.user = owner;
                        if (err) res.status(400).send({ message: 'Owner user not found'});
                        //Interested Users
                        User.find({
                            '_id': {$in: post.interestedUsers},
                            'isActive': true
                        }).select('_id displayName roles school isActive').exec(function (err, interestedUsers) {
                            postObject.interestedUsers = interestedUsers;
                            if (err) res.status(400).send({ message: 'Owner user not found'});
                            //Participants
                            User.find({
                                '_id': {$in: post.participants},
                                'isActive': true
                            }).select('_id displayName roles school isActive').exec(function (err, participants) {
                                postObject.participants = participants;
                                if (err) res.status(400).send({ message: 'Owner user not found'});
                                res.jsonp(postObject);
                            });
                        });
                    });
               }
            });
        }
        else{
            res.status(400).send({ message: 'Post not found'});
        }
    });
};

/**
 * Update a Post
 */
exports.update = function(req, res) {
	var post = req.post ;

	post = _.extend(post , req.body);
    post.updated = Date.now();

	post.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(post);
		}
	});
};

/**
 * Delete an Post
 */
exports.delete = function(req, res) {
	var post = req.post;

    post.isActive = false;

	post.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			req.send(Boolean(true));
		}
	});
};

/**
 * List of Posts
 */
exports.list = function(req, res) {
	Post.find().sort('-created').populate('user', 'displayName').exec(function(err, posts) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(posts);
		}
	});
};

/**
 * Post middleware
 */
exports.postByID = function(req, res, next, id) {
	Post.findById(id).populate('user', 'displayName').exec(function(err, post) {
		if (err) return next(err);
		if (! post) return next(new Error('Failed to load Post ' + id));
		req.post = post ;
		next();
	});
};

exports.listLimit = function(req, res, next, limit) {
    if(!isNaN(limit)){
        req.limit = limit;
    }
    else{
        req.limit = 20;
    }
    next();
};

/**
 * Post authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.post.user.id !== req.user.id) {
		return res.status(403).send('User is not authorized');
	}
	next();
};

/**
 * Add interest user to a post
 */
exports.addInterest = function(req, res){
    Post.findOne(req.body.post, function(err, post){
        if(err){
            res.status(400).send('Post not found');
        }
        else{
            if(post.interestedUsers.indexOf(req.user._id) < 0){
                post.interestedUsers.push(req.user._id);
                post.updated = Date.now();
                post.save(function(err) {
                    if (err) {
                        return res.status(400).send({
                        message: errorHandler.getErrorMessage(err)
                    });
                    } else {
                        res.jsonp(post);
                    }
                });
            }
        }
    });
};
<commit_msg>Update post model<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	User = mongoose.model('User'),
    Post = mongoose.model('Post'),
	_ = require('lodash');

/**
 * Create a Post
 */
exports.create = function(req, res) {
    var post = new Post(req.body);
    post.user = req.user;
    post.updated = Date.now();
    var message = null;

    post.save(function(err) {
        if (err) {
            return res.status(400).send({
            	message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.send(String(post._id));
        }
    });
};

/**
 * Show the current Post
 */
exports.read = function(req, res) {
    Post.findById(req.params.postId, function(err, post){
        if(err && !post){ res.status(400).send({ message: 'Post not found'}); }
        else{
            var opt = [
                { path : 'user', model : 'User', select: 'displayName roles school zipCode isActive', match : { isActive : true }},
                { path : 'interestedUsers', model : 'User', select: 'displayName roles school zipCode isActive', match : { isActive : true }},
                { path : 'participants', model : 'User', select: 'displayName roles school zipCode isActive', match : { isActive : true }},
                { path : 'comments', model : 'Comment',  match : { isActive : true }}
            ];

            Post.populate(post, opt, function(err, post) {
                if (err || !post.user.isActive) {
                    res.status(400).send({message: 'Post user not found'});
                }
                else {
                    res.jsonp(post);
                }
            });
        }
    });
};

/**
 * Update a Post
 */
exports.update = function(req, res) {
	var post = req.post ;

	post = _.extend(post , req.body);
    post.updated = Date.now();

	post.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(post);
		}
	});
};

/**
 * Delete an Post
 */
exports.delete = function(req, res) {
	var post = req.post;

    post.isActive = false;

	post.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			req.send(Boolean(true));
		}
	});
};

/**
 * List of Posts
 */
exports.list = function(req, res) {
	Post.find().sort('-created').populate('user', 'displayName school location').exec(function(err, posts) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(posts);
		}
	});
};

/**
 * Post middleware
 */
exports.postByID = function(req, res, next, id) {
	Post.findById(id).populate('user', 'displayName').exec(function(err, post) {
		if (err) return next(err);
		if (! post) return next(new Error('Failed to load Post ' + id));
		req.post = post ;
		next();
	});
};

exports.listLimit = function(req, res, next, limit) {
    if(!isNaN(limit)){
        req.limit = limit;
    }
    else{
        req.limit = 20;
    }
    next();
};

/**
 * Post authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.post.user.id !== req.user.id) {
		return res.status(403).send('User is not authorized');
	}
	next();
};

/**
 * Add interest user to a post
 */
exports.addInterest = function(req, res){
    Post.findOne(req.body.post, function(err, post){
        if(err){
            res.status(400).send('Post not found');
        }
        else{
            if(post.interestedUsers.indexOf(req.user._id) < 0){
                post.interestedUsers.push(req.user._id);
                post.updated = Date.now();
                post.save(function(err) {
                    if (err) {
                        return res.status(400).send({
                        message: errorHandler.getErrorMessage(err)
                    });
                    } else {
                        res.jsonp(post);
                    }
                });
            }
        }
    });
};
<|endoftext|>


<commit_before>var creep_ranger = {

    /** @param {Creep} creep **/
    run: function(creep) {
        if (creep.memory.previousRoom != creep.room.name) {
            //Reset pathfinding memory so a more relevant path gets calculated here.
            creep.memory.previousRoom = creep.room.name;
            creep.memory._trav = undefined;
        }

        let flagName = 'Ranger';
        if (creep.memory.flagName == 'ranger2') {
            flagName = 'Ranger2';
        } else if (creep.memory.flagName == 'PowerGuard') {
            flagName = 'PowerGuard'
        }

        if (flagName == 'PowerGuard' && !Game.flags[creep.memory.homeRoom + "PowerGather"] && Game.flags[creep.memory.homeRoom + "PowerGuard"]) {
            //Gathering disabled, no need to maintain position
            Game.flags[creep.memory.homeRoom + "PowerGuard"].remove();
        }

        if (creep.ticksToLive <= creep.memory.deathWarn && creep.memory.priority != 'rangerNearDeath') {
            creep.memory.priority = 'rangerNearDeath';
        }

        var closeFoe = creep.pos.findClosestByPath(FIND_HOSTILE_CREEPS, {
            filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
        });

        if (creep.memory.destination == creep.pos.roomName) {
            //In target room
            if (Game.time % 2 == 0) {
                creep.say("(=\uFF40\u03C9\u00B4=)", true);
            } else {
                creep.say("(=\u00B4\u2207\uFF40=)", true);
            }

            //Cancel this flag if room is in safe mode
            if (creep.room.controller && creep.room.controller.safeMode && creep.room.controller.owner.username != "Montblanc") {
                if (Game.flags[creep.memory.homeRoom + flagName]) {
                    Game.flags[creep.memory.homeRoom + flagName].remove();
                }
                return;
            }

            if (creep.room.controller && creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc") {
                let somethingNearby = creep.pos.findClosestByRange(FIND_STRUCTURES, {
                    filter: (structure) => (structure.structureType != STRUCTURE_ROAD && structure.structureType != STRUCTURE_POWER_BANK && structure.structureType != STRUCTURE_TERMINAL)
                });
                if (somethingNearby) {
                    creep.attack(somethingNearby);
                    creep.rangedAttack(somethingNearby);
                }
            }

            let eSpawns = creep.pos.findClosestByRange(FIND_HOSTILE_STRUCTURES, {
                filter: (structure) => (structure.structureType == STRUCTURE_SPAWN)
            });
            let eSites = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES, {
                filter: (site) => (site.progress > 0)
            });
            if (eSpawns) {
                creep.travelTo(eSpawns, {
                    ignoreRoads: true,
                    maxRooms: 1,
                    stuckValue: 2,
                    allowSK: true
                });
                creep.attack(eSpawns);
                creep.rangedAttack(eSpawns);
            } else if (eSites && creep.room.controller && creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc") {
                creep.travelTo(eSites, {
                    ignoreRoads: true,
                    maxRooms: 1,
                    stuckValue: 2
                })
            } else if (closeFoe) {
                //Dodge melee threats, else aggressively pursue.
                let meleeThreat = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 3, {
                    filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
                });

                let thisThreat = undefined;
                if (meleeThreat.length) {
                    for (let thisFoe in meleeThreat) {
                        if(determineThreat(meleeThreat[thisFoe])) {
                            thisThreat = meleeThreat[thisFoe];
                            break;
                        }
                    }

                    if (thisThreat) {
                        //Dodge away from foe
                        creep.travelTo(thisThreat, {
                            maxRooms: 1,
                            range: 3
                        }, true);
                    } else {
                        creep.travelTo(closeFoe, {
                            ignoreRoads: true,
                            maxRooms: 1,
                            allowSK: true
                        });
                    }
                } else {
                    creep.travelTo(closeFoe, {
                        ignoreRoads: true,
                        maxRooms: 1,
                        allowSK: true
                    });
                }
            } else {
                let eStructures = creep.pos.findClosestByRange(FIND_HOSTILE_STRUCTURES, {
                    filter: (structure) => (structure.structureType != STRUCTURE_CONTROLLER && structure.structureType != STRUCTURE_WALL && structure.structureType != STRUCTURE_RAMPART && structure.structureType != STRUCTURE_KEEPER_LAIR && structure.structureType != STRUCTURE_EXTRACTOR && structure.structureType != STRUCTURE_TERMINAL)
                });
                if (eStructures) {
                    creep.travelTo(eStructures, {
                        ignoreRoads: true,
                        maxRooms: 1,
                        stuckValue: 2,
                        allowSK: true
                    });
                    creep.attack(eStructures);
                    creep.rangedAttack(eStructures);
                } else if (Game.flags[creep.memory.homeRoom + flagName]) {
                    creep.travelTo(Game.flags[creep.memory.homeRoom + flagName]);
                }
            }
        } else {
            /*if (creep.memory.destination && !creep.memory.usedPortal) {
                creep.travelTo(new RoomPosition(25, 25, creep.memory.destination))
            } else*/
            if (creep.memory.path && creep.memory.path.length) {
                if (creep.memory.path[0] == creep.room.name) {
                    creep.memory.path.splice(0, 1);
                }
                creep.travelTo(new RoomPosition(25, 25, creep.memory.path[0]), {
                    stuckValue: 2,
                    allowSK: true
                });
            } else {
                creep.travelTo(new RoomPosition(25, 25, creep.memory.destination), {
                    stuckValue: 2,
                    allowSK: true
                });
            }

            if (!creep.memory.travelDistance && creep.memory._trav && creep.memory._trav.path) {
                creep.memory.travelDistance = creep.memory._trav.path.length;
                creep.memory.deathWarn = (creep.memory.travelDistance + _.size(creep.body) * 3) + 15;
            }
        }

        if (closeFoe) {
            let closeRange = creep.pos.getRangeTo(closeFoe);
            if (closeRange <= 3) {
                var lookResult = closeFoe.pos.lookFor(LOOK_STRUCTURES);
                let inRampart = false;
                if (lookResult.length) {
                    for (let d = 0; d < lookResult.length; d++) {
                        if (lookResult[d].structureType == STRUCTURE_RAMPART) {
                            inRampart = true;
                            break;
                        }
                    }
                    if (inRampart) {
                        creep.rangedMassAttack();
                    } else {
                        creep.rangedAttack(closeFoe);
                        creep.attack(closeFoe);
                    }
                } else {
                    creep.rangedAttack(closeFoe);
                    creep.attack(closeFoe);
                }
                if (closeRange == 1) {
                    creep.rangedMassAttack();
                }
            }
        }

        //Only works with no attack parts
        creep.heal(creep);

    }

};

function targetAttacker(a, b) {
    if (a.getActiveBodyparts(ATTACK) > b.getActiveBodyparts(ATTACK))
        return -1;
    if (a.getActiveBodyparts(ATTACK) < b.getActiveBodyparts(ATTACK))
        return 1;
    return 0;
}

function determineThreat(thisCreep) {
    thisCreep.body.forEach(function(thisPart) {
        if (thisPart.type == ATTACK) {
            return true;
        }
    });
    return false;
}

module.exports = creep_ranger;<commit_msg>rangers won't destroy storage units in order to loot<commit_after>var creep_ranger = {

    /** @param {Creep} creep **/
    run: function(creep) {
        if (creep.memory.previousRoom != creep.room.name) {
            //Reset pathfinding memory so a more relevant path gets calculated here.
            creep.memory.previousRoom = creep.room.name;
            creep.memory._trav = undefined;
        }

        let flagName = 'Ranger';
        if (creep.memory.flagName == 'ranger2') {
            flagName = 'Ranger2';
        } else if (creep.memory.flagName == 'PowerGuard') {
            flagName = 'PowerGuard'
        }

        if (flagName == 'PowerGuard' && !Game.flags[creep.memory.homeRoom + "PowerGather"] && Game.flags[creep.memory.homeRoom + "PowerGuard"]) {
            //Gathering disabled, no need to maintain position
            Game.flags[creep.memory.homeRoom + "PowerGuard"].remove();
        }

        if (creep.ticksToLive <= creep.memory.deathWarn && creep.memory.priority != 'rangerNearDeath') {
            creep.memory.priority = 'rangerNearDeath';
        }

        var closeFoe = creep.pos.findClosestByPath(FIND_HOSTILE_CREEPS, {
            filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
        });

        if (creep.memory.destination == creep.pos.roomName) {
            //In target room
            if (Game.time % 2 == 0) {
                creep.say("(=\uFF40\u03C9\u00B4=)", true);
            } else {
                creep.say("(=\u00B4\u2207\uFF40=)", true);
            }

            //Cancel this flag if room is in safe mode
            if (creep.room.controller && creep.room.controller.safeMode && creep.room.controller.owner.username != "Montblanc") {
                if (Game.flags[creep.memory.homeRoom + flagName]) {
                    Game.flags[creep.memory.homeRoom + flagName].remove();
                }
                return;
            }

            if (creep.room.controller && creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc") {
                let somethingNearby = creep.pos.findClosestByRange(FIND_STRUCTURES, {
                    filter: (structure) => (structure.structureType != STRUCTURE_ROAD && structure.structureType != STRUCTURE_POWER_BANK && structure.structureType != STRUCTURE_TERMINAL && structure.structureType != STRUCTURE_STORAGE)
                });
                if (somethingNearby) {
                    creep.attack(somethingNearby);
                    creep.rangedAttack(somethingNearby);
                }
            }

            let eSpawns = creep.pos.findClosestByRange(FIND_HOSTILE_STRUCTURES, {
                filter: (structure) => (structure.structureType == STRUCTURE_SPAWN)
            });
            let eSites = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES, {
                filter: (site) => (site.progress > 0)
            });
            if (eSpawns) {
                creep.travelTo(eSpawns, {
                    ignoreRoads: true,
                    maxRooms: 1,
                    stuckValue: 2,
                    allowSK: true
                });
                creep.attack(eSpawns);
                creep.rangedAttack(eSpawns);
            } else if (eSites && creep.room.controller && creep.room.controller.owner && creep.room.controller.owner.username != "Montblanc") {
                creep.travelTo(eSites, {
                    ignoreRoads: true,
                    maxRooms: 1,
                    stuckValue: 2
                })
            } else if (closeFoe) {
                //Dodge melee threats, else aggressively pursue.
                let meleeThreat = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 3, {
                    filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
                });

                let thisThreat = undefined;
                if (meleeThreat.length) {
                    for (let thisFoe in meleeThreat) {
                        if(determineThreat(meleeThreat[thisFoe])) {
                            thisThreat = meleeThreat[thisFoe];
                            break;
                        }
                    }

                    if (thisThreat) {
                        //Dodge away from foe
                        creep.travelTo(thisThreat, {
                            maxRooms: 1,
                            range: 3
                        }, true);
                    } else {
                        creep.travelTo(closeFoe, {
                            ignoreRoads: true,
                            maxRooms: 1,
                            allowSK: true
                        });
                    }
                } else {
                    creep.travelTo(closeFoe, {
                        ignoreRoads: true,
                        maxRooms: 1,
                        allowSK: true
                    });
                }
            } else {
                let eStructures = creep.pos.findClosestByRange(FIND_HOSTILE_STRUCTURES, {
                    filter: (structure) => (structure.structureType != STRUCTURE_CONTROLLER && structure.structureType != STRUCTURE_WALL && structure.structureType != STRUCTURE_RAMPART && structure.structureType != STRUCTURE_KEEPER_LAIR && structure.structureType != STRUCTURE_EXTRACTOR && structure.structureType != STRUCTURE_TERMINAL && structure.structureType != STRUCTURE_STORAGE)
                });
                if (eStructures) {
                    creep.travelTo(eStructures, {
                        ignoreRoads: true,
                        maxRooms: 1,
                        stuckValue: 2,
                        allowSK: true
                    });
                    creep.attack(eStructures);
                    creep.rangedAttack(eStructures);
                } else if (Game.flags[creep.memory.homeRoom + flagName]) {
                    creep.travelTo(Game.flags[creep.memory.homeRoom + flagName]);
                }
            }
        } else {
            /*if (creep.memory.destination && !creep.memory.usedPortal) {
                creep.travelTo(new RoomPosition(25, 25, creep.memory.destination))
            } else*/
            if (creep.memory.path && creep.memory.path.length) {
                if (creep.memory.path[0] == creep.room.name) {
                    creep.memory.path.splice(0, 1);
                }
                creep.travelTo(new RoomPosition(25, 25, creep.memory.path[0]), {
                    stuckValue: 2,
                    allowSK: true
                });
            } else {
                creep.travelTo(new RoomPosition(25, 25, creep.memory.destination), {
                    stuckValue: 2,
                    allowSK: true
                });
            }

            if (!creep.memory.travelDistance && creep.memory._trav && creep.memory._trav.path) {
                creep.memory.travelDistance = creep.memory._trav.path.length;
                creep.memory.deathWarn = (creep.memory.travelDistance + _.size(creep.body) * 3) + 15;
            }
        }

        if (closeFoe) {
            let closeRange = creep.pos.getRangeTo(closeFoe);
            if (closeRange <= 3) {
                var lookResult = closeFoe.pos.lookFor(LOOK_STRUCTURES);
                let inRampart = false;
                if (lookResult.length) {
                    for (let d = 0; d < lookResult.length; d++) {
                        if (lookResult[d].structureType == STRUCTURE_RAMPART) {
                            inRampart = true;
                            break;
                        }
                    }
                    if (inRampart) {
                        creep.rangedMassAttack();
                    } else {
                        creep.rangedAttack(closeFoe);
                        creep.attack(closeFoe);
                    }
                } else {
                    creep.rangedAttack(closeFoe);
                    creep.attack(closeFoe);
                }
                if (closeRange == 1) {
                    creep.rangedMassAttack();
                }
            }
        }

        //Only works with no attack parts
        creep.heal(creep);

    }

};

function targetAttacker(a, b) {
    if (a.getActiveBodyparts(ATTACK) > b.getActiveBodyparts(ATTACK))
        return -1;
    if (a.getActiveBodyparts(ATTACK) < b.getActiveBodyparts(ATTACK))
        return 1;
    return 0;
}

function determineThreat(thisCreep) {
    thisCreep.body.forEach(function(thisPart) {
        if (thisPart.type == ATTACK) {
            return true;
        }
    });
    return false;
}

module.exports = creep_ranger;<|endoftext|>


<commit_before>const path = require("path");
const preparePlugins = require("../config/preparePlugins");
const compileGlueStickConfig = require("../config/compileGlueStickConfig");
const compileWebpackConfig = require("../config/compileWebpackConfig");
const logger = require("./logger");

const execHooks = (context, hooks) => {
  if (Array.isArray(hooks)) {
    hooks.forEach(fn => fn(context));
  } else if (typeof hooks === "function") {
    hooks(context);
  }
};

module.exports = exports = (
  func,
  commandArguments,
  { useGSConfig, useWebpackConfig, skipProjectConfig } = {},
  { pre, post }
) => {
  const projectConfig = skipProjectConfig
    ? {}
    : require(path.join(process.cwd(), "package.json")).gluestick;
  const plugins = preparePlugins(projectConfig);
  const GSConfig = useGSConfig ? compileGlueStickConfig(plugins, projectConfig) : null;
  const webpackConfig = useWebpackConfig ? compileWebpackConfig(plugins, projectConfig) : null;
  const context = {
    config: {
      projectConfig,
      GSConfig,
      webpackConfig,
      plugins
    },
    logger
  };
  execHooks(context, pre);
  execHooks(context, post);
  try {
    func(context, ...commandArguments);
  } catch (error) {
    process.stderr.write(error.message);
    process.exit(1);
  }
};
<commit_msg>default hooks<commit_after>const path = require("path");
const preparePlugins = require("../config/preparePlugins");
const compileGlueStickConfig = require("../config/compileGlueStickConfig");
const compileWebpackConfig = require("../config/compileWebpackConfig");
const logger = require("./logger");

const execHooks = (context, hooks) => {
  if (Array.isArray(hooks)) {
    hooks.forEach(fn => fn(context));
  } else if (typeof hooks === "function") {
    hooks(context);
  }
};

module.exports = exports = (
  func,
  commandArguments,
  { useGSConfig, useWebpackConfig, skipProjectConfig } = {},
  { pre, post } = {}
) => {
  const projectConfig = skipProjectConfig
    ? {}
    : require(path.join(process.cwd(), "package.json")).gluestick;
  const plugins = preparePlugins(projectConfig);
  const GSConfig = useGSConfig ? compileGlueStickConfig(plugins, projectConfig) : null;
  const webpackConfig = useWebpackConfig ? compileWebpackConfig(plugins, projectConfig) : null;
  const context = {
    config: {
      projectConfig,
      GSConfig,
      webpackConfig,
      plugins
    },
    logger
  };
  execHooks(context, pre);
  execHooks(context, post);
  try {
    func(context, ...commandArguments);
  } catch (error) {
    process.stderr.write(error.message);
    process.exit(1);
  }
};
<|endoftext|>