<commit_before>'use strict'

const events = require('events')
const httpreq = require('httpreq')

const radioTypes = ['gsm', 'lte', 'cdma', 'wcdma']

let defaults = {
  mcc: '515',
  mnc: '03',
  radioType: radioTypes[0],
  timeout: 3000
}

const Geolocation360 = {
  initialize: (params) => {
    for (let key in params) {
      defaults[key] = params[key]
    }
  },

  lacksParams: (params, provider) => {
    let requiredKeys = ['mcc', 'mnc', 'lac', 'cid']
    if (provider) {
      switch (provider) {
        case 'google':
          requiredKeys.push(`${provider}ApiKey`)
          break
        case 'openCellId':
          requiredKeys.push(`${provider}ApiKey`)
          break
      }
    }
    for (let key in requiredKeys) {
      if (!params[requiredKeys[key]]) {
        if (!defaults[requiredKeys[key]]) {
          return new Error(`Parameter ${requiredKeys[key]} is required`)
        } else {
          params[requiredKeys[key]] = defaults[requiredKeys[key]]
        }
      } else {
        if (requiredKeys[key] == 'lac' || requiredKeys[key] == 'cid') {
          if (!params.isChecked) params[requiredKeys[key]] = parseInt(params[requiredKeys[key]],16)
        }
      }
    }
    params.isChecked = true
    return undefined
  },

  requestGoogle: (params, callback) => {
    let lacks = Geolocation360.lacksParams(params, 'google')
    if (lacks) return callback(lacks)
    let requestBody = {
      radioType: params.radioType,
      cellTowers: [{
        cellId: params.cid,
        locationAreaCode: params.lac,
        mobileCountryCode: params.mcc,
        mobileNetworkCode: params.mnc
      }]
    }

    let options = {
      timeout: params.timeout || defaults.timeout,
      method: 'POST',
      url: `https://www.googleapis.com/geolocation/v1/geolocate${params.googleApiKey ? '?key=' + params.googleApiKey : ''}`,
      json: requestBody,
    }

    httpreq.doRequest(options, (err, res) => {
      let data = res && res.body || ''
      let error = null
      let parsedData = null

      try {
        parsedData = JSON.parse(data)
        data = {
          provider: 'Google',
          latitude: parsedData.location.lat,
          longitude: parsedData.location.lng,
          accuracy: parsedData.accuracy
        }
      } catch (e) {
        error = new Error('Google: invalid response')
        error.error = e
      }

      if (err) {
        error = new Error('Google: request failed')
        error.error = err
      }

      if (parsedData && parsedData.error) {
        if (parsedData.error.errors) {
          error = new Error(`Google: ${parsedData.error.errors[0].domain}`)
        } else {
          error = new Error(`Google: api error`)
        }
        error.error = parsedData.error.errors
      }

      if (error) {
        error.statusCode = res && res.statusCode
        callback(error)
      } else {
        callback(null, data)
      }
    })
  },

  requestOpenCellId: (params, callback) => {
    let lacks = Geolocation360.lacksParams(params, 'openCellId')
    if (lacks) return callback(lacks)
    let requestBody = {
      token: params.openCellIdApiKey,
      cells: [{
        radio: params.radioType,
        cid: params.cid,
        lac: params.lac,
        mcc: params.mcc,
        mnc: params.mnc
      }],
      fallbacks: {
        lacf: 2
      }
    }

    let options = {
      timeout: params.timeout || defaults.timeout,
      method: 'POST',
      url: 'https://ap1.unwiredlabs.com/v2/process.php',
      json: requestBody,
    }

    httpreq.doRequest(options, (err, res) => {
      let data = res && res.body || ''
      let error = null
      let parsedData = null

      try {
        parsedData = JSON.parse(data)
        data = {
          provider: 'OpenCellId',
          latitude: parsedData.lat,
          longitude: parsedData.lon,
          accuracy: parsedData.accuracy
        }
      } catch (e) {
        error = new Error('OpenCellId: invalid response')
        error.error = e
      }

      if (err) {
        error = new Error('OpenCellId: request failed')
        error.error = err
      }

      if (parsedData && parsedData.status && parsedData.status == 'error') {
        if (parsedData.message) {
          error = new Error(`OpenCellId: ${parsedData.message}`)
        } else {
          error = new Error(`OpenCellId: api error`)
        }
        error.error = parsedData
      }

      if (error) {
        error.statusCode = res && res.statusCode
        callback(error)
      } else {
        callback(null, data)
      }
    })
  },

  request: (params, callback) => {
    let providers = []
    for (let key in params) {
      if (key.indexOf('ApiKey') > -1) {
        let s = key.replace('ApiKey', '')
        s = s[0].toUpperCase() + s.slice(1)
        if (!(providers.indexOf(s) > -1)) providers.push(s)
      }
    }
    for (let key in defaults) {
      if (key.indexOf('ApiKey') > -1) {
        let s = key.replace('ApiKey', '')
        s = s[0].toUpperCase() + s.slice(1)
        if (!(providers.indexOf(s) > -1)) providers.push(s)
      }
    }
    if (providers.length) {
      let count = providers.length
      Geolocation360.processRequest(params, providers, 0, [], callback)
    } else {
      callback(new Error('No api key provided.'))
    }
  },

  processRequest: (params, providers, index, errors, callback) => {
    Geolocation360[`request${providers[index]}`](params, (err, result) => {
      if (result) {
        callback(null, result)
      } else {
        errors.push(err)
        if (index + 1 == providers.length) {
          let error = new Error('No succesful return from providers')
          error.errors = errors
          callback(error)
        } else {
          index++
          Geolocation360.processRequest(params, providers, index, errors, callback)
        }
      }
    })
  }
}

module.exports = Geolocation360<commit_msg>-fix error<commit_after>'use strict'

const events = require('events')
const httpreq = require('httpreq')

const radioTypes = ['gsm', 'lte', 'cdma', 'wcdma']

let defaults = {
  mcc: '515',
  mnc: '03',
  radioType: radioTypes[0],
  timeout: 3000
}

const Geolocation360 = {
  initialize: (params) => {
    for (let key in params) {
      defaults[key] = params[key]
    }
  },

  lacksParams: (params, provider) => {
    let requiredKeys = ['mcc', 'mnc', 'lac', 'cid']
    if (provider) {
      switch (provider) {
        case 'google':
          requiredKeys.push(`${provider}ApiKey`)
          break
        case 'openCellId':
          requiredKeys.push(`${provider}ApiKey`)
          break
      }
    }
    for (let key in requiredKeys) {
      if (!params[requiredKeys[key]]) {
        if (!defaults[requiredKeys[key]]) {
          return new Error(`Parameter ${requiredKeys[key]} is required`)
        } else {
          params[requiredKeys[key]] = defaults[requiredKeys[key]]
        }
      } else {
        if (requiredKeys[key] == 'lac' || requiredKeys[key] == 'cid') {
          if (!params.isChecked) params[requiredKeys[key]] = parseInt(params[requiredKeys[key]],16)
        }
      }
    }
    params.isChecked = true
    return undefined
  },

  requestGoogle: (params, callback) => {
    let lacks = Geolocation360.lacksParams(params, 'google')
    if (lacks) return callback(lacks)
    let requestBody = {
      radioType: params.radioType,
      cellTowers: [{
        cellId: params.cid,
        locationAreaCode: params.lac,
        mobileCountryCode: params.mcc,
        mobileNetworkCode: params.mnc
      }]
    }

    let options = {
      timeout: params.timeout,
      method: 'POST',
      url: `https://www.googleapis.com/geolocation/v1/geolocate${params.googleApiKey ? '?key=' + params.googleApiKey : ''}`,
      json: requestBody,
    }

    httpreq.doRequest(options, (err, res) => {
      let data = res && res.body || ''
      let error = null
      let parsedData = null

      try {
        parsedData = JSON.parse(data)
        data = {
          provider: 'Google',
          latitude: parsedData.location.lat,
          longitude: parsedData.location.lng,
          accuracy: parsedData.accuracy
        }
      } catch (e) {
        error = new Error('Google: invalid response')
        error.error = e
      }

      if (err) {
        error = new Error('Google: request failed')
        error.error = err
      }

      if (parsedData && parsedData.error) {
        if (parsedData.error.errors) {
          error = new Error(`Google: ${parsedData.error.errors[0].domain}`)
        } else {
          error = new Error(`Google: api error`)
        }
        error.error = parsedData.error.errors
      }

      if (error) {
        error.statusCode = res && res.statusCode
        callback(error)
      } else {
        callback(null, data)
      }
    })
  },

  requestOpenCellId: (params, callback) => {
    let lacks = Geolocation360.lacksParams(params, 'openCellId')
    if (lacks) return callback(lacks)
    let requestBody = {
      token: params.openCellIdApiKey,
      cells: [{
        radio: params.radioType,
        cid: params.cid,
        lac: params.lac,
        mcc: params.mcc,
        mnc: params.mnc
      }],
      fallbacks: {
        lacf: 2
      }
    }

    let options = {
      timeout: params.timeout,
      method: 'POST',
      url: 'https://ap1.unwiredlabs.com/v2/process.php',
      json: requestBody,
    }

    httpreq.doRequest(options, (err, res) => {
      let data = res && res.body || ''
      let error = null
      let parsedData = null

      try {
        parsedData = JSON.parse(data)
        data = {
          provider: 'OpenCellId',
          latitude: parsedData.lat,
          longitude: parsedData.lon,
          accuracy: parsedData.accuracy
        }
      } catch (e) {
        error = new Error('OpenCellId: invalid response')
        error.error = e
      }

      if (err) {
        error = new Error('OpenCellId: request failed')
        error.error = err
      }

      if (parsedData && parsedData.status && parsedData.status == 'error') {
        if (parsedData.message) {
          error = new Error(`OpenCellId: ${parsedData.message}`)
        } else {
          error = new Error(`OpenCellId: api error`)
        }
        error.error = parsedData
      }

      if (error) {
        error.statusCode = res && res.statusCode
        callback(error)
      } else {
        callback(null, data)
      }
    })
  },

  request: (params, callback) => {
    let providers = []
    for (let key in params) {
      if (key.indexOf('ApiKey') > -1) {
        let s = key.replace('ApiKey', '')
        s = s[0].toUpperCase() + s.slice(1)
        if (!(providers.indexOf(s) > -1)) providers.push(s)
      }
    }
    for (let key in defaults) {
      if (key.indexOf('ApiKey') > -1) {
        let s = key.replace('ApiKey', '')
        s = s[0].toUpperCase() + s.slice(1)
        if (!(providers.indexOf(s) > -1)) providers.push(s)
      }
    }
    if (providers.length) {
      let count = providers.length
      Geolocation360.processRequest(params, providers, 0, [], callback)
    } else {
      callback(new Error('No api key provided.'))
    }
  },

  processRequest: (params, providers, index, errors, callback) => {
    Geolocation360[`request${providers[index]}`](params, (err, result) => {
      if (result) {
        callback(null, result)
      } else {
        errors.push(err)
        if (index + 1 == providers.length) {
          let error = new Error('No succesful return from providers')
          error.errors = errors
          callback(error)
        } else {
          index++
          Geolocation360.processRequest(params, providers, index, errors, callback)
        }
      }
    })
  }
}

module.exports = Geolocation360<|endoftext|>


<commit_before>module Utils from "./utils";
import Exception from "./exception";

export var VERSION = "2.0.0-alpha.4";
export var COMPILER_REVISION = 6;

export var REVISION_CHANGES = {
  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
  2: '== 1.0.0-rc.3',
  3: '== 1.0.0-rc.4',
  4: '== 1.x.x',
  5: '>= 2.0.0-alpha.x',
  6: '>= 2.0.0-beta.1'
};

var isArray = Utils.isArray,
    isFunction = Utils.isFunction,
    toString = Utils.toString,
    objectType = '[object Object]';

export function HandlebarsEnvironment(helpers, partials) {
  this.helpers = helpers || {};
  this.partials = partials || {};

  registerDefaultHelpers(this);
}

HandlebarsEnvironment.prototype = {
  constructor: HandlebarsEnvironment,

  logger: logger,
  log: log,

  registerHelper: function(name, fn) {
    if (toString.call(name) === objectType) {
      if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
      Utils.extend(this.helpers, name);
    } else {
      this.helpers[name] = fn;
    }
  },
  unregisterHelper: function(name) {
    delete this.helpers[name];
  },

  registerPartial: function(name, str) {
    if (toString.call(name) === objectType) {
      Utils.extend(this.partials,  name);
    } else {
      this.partials[name] = str;
    }
  },
  unregisterPartial: function(name) {
    delete this.partials[name];
  }
};

function registerDefaultHelpers(instance) {
  instance.registerHelper('helperMissing', function(/* [args, ]options */) {
    if(arguments.length === 1) {
      // A missing field in a {{foo}} constuct.
      return undefined;
    } else {
      // Someone is actually trying to call something, blow up.
      throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
    }
  });

  instance.registerHelper('blockHelperMissing', function(context, options) {
    var inverse = options.inverse,
        fn = options.fn;

    if(context === true) {
      return fn(this);
    } else if(context === false || context == null) {
      return inverse(this);
    } else if (isArray(context)) {
      if(context.length > 0) {
        if (options.ids) {
          options.ids = [options.name];
        }

        return instance.helpers.each(context, options);
      } else {
        return inverse(this);
      }
    } else {
      if (options.data && options.ids) {
        var data = createFrame(options.data);
        data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
        options = {data: data};
      }

      return fn(context, options);
    }
  });

  instance.registerHelper('each', function(context, options) {
    if (!options) {
      throw new Exception('Must pass iterator to #each');
    }

    var fn = options.fn, inverse = options.inverse;
    var i = 0, ret = "", data;

    var contextPath;
    if (options.data && options.ids) {
      contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
    }

    if (isFunction(context)) { context = context.call(this); }

    if (options.data) {
      data = createFrame(options.data);
    }

    if(context && typeof context === 'object') {
      if (isArray(context)) {
        for(var j = context.length; i<j; i++) {
          if (data) {
            data.index = i;
            data.first = (i === 0);
            data.last  = (i === (context.length-1));

            if (contextPath) {
              data.contextPath = contextPath + i;
            }
          }
          ret = ret + fn(context[i], { data: data });
        }
      } else {
        for(var key in context) {
          if(context.hasOwnProperty(key)) {
            if(data) {
              data.key = key;
              data.index = i;
              data.first = (i === 0);

              if (contextPath) {
                data.contextPath = contextPath + key;
              }
            }
            ret = ret + fn(context[key], {data: data});
            i++;
          }
        }
      }
    }

    if(i === 0){
      ret = inverse(this);
    }

    return ret;
  });

  instance.registerHelper('if', function(conditional, options) {
    if (isFunction(conditional)) { conditional = conditional.call(this); }

    // Default behavior is to render the positive path if the value is truthy and not empty.
    // The `includeZero` option may be set to treat the condtional as purely not empty based on the
    // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
    if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
      return options.inverse(this);
    } else {
      return options.fn(this);
    }
  });

  instance.registerHelper('unless', function(conditional, options) {
    return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
  });

  instance.registerHelper('with', function(context, options) {
    if (isFunction(context)) { context = context.call(this); }

    var fn = options.fn;

    if (!Utils.isEmpty(context)) {
      if (options.data && options.ids) {
        var data = createFrame(options.data);
        data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
        options = {data:data};
      }

      return fn(context, options);
    } else {
      return options.inverse(this);
    }
  });

  instance.registerHelper('log', function(context, options) {
    var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
    instance.log(level, context);
  });

  instance.registerHelper('lookup', function(obj, field, options) {
    return obj && obj[field];
  });
}

export var logger = {
  methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },

  // State enum
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3,
  level: 3,

  // can be overridden in the host environment
  log: function(level, obj) {
    if (logger.level <= level) {
      var method = logger.methodMap[level];
      if (typeof console !== 'undefined' && console[method]) {
        console[method].call(console, obj);
      }
    }
  }
};

export var log = logger.log;

export var createFrame = function(object) {
  var frame = Utils.extend({}, object);
  frame._parent = object;
  return frame;
};
<commit_msg>Fix compiler version tag<commit_after>module Utils from "./utils";
import Exception from "./exception";

export var VERSION = "2.0.0-alpha.4";
export var COMPILER_REVISION = 6;

export var REVISION_CHANGES = {
  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
  2: '== 1.0.0-rc.3',
  3: '== 1.0.0-rc.4',
  4: '== 1.x.x',
  5: '== 2.0.0-alpha.x',
  6: '>= 2.0.0-beta.1'
};

var isArray = Utils.isArray,
    isFunction = Utils.isFunction,
    toString = Utils.toString,
    objectType = '[object Object]';

export function HandlebarsEnvironment(helpers, partials) {
  this.helpers = helpers || {};
  this.partials = partials || {};

  registerDefaultHelpers(this);
}

HandlebarsEnvironment.prototype = {
  constructor: HandlebarsEnvironment,

  logger: logger,
  log: log,

  registerHelper: function(name, fn) {
    if (toString.call(name) === objectType) {
      if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
      Utils.extend(this.helpers, name);
    } else {
      this.helpers[name] = fn;
    }
  },
  unregisterHelper: function(name) {
    delete this.helpers[name];
  },

  registerPartial: function(name, str) {
    if (toString.call(name) === objectType) {
      Utils.extend(this.partials,  name);
    } else {
      this.partials[name] = str;
    }
  },
  unregisterPartial: function(name) {
    delete this.partials[name];
  }
};

function registerDefaultHelpers(instance) {
  instance.registerHelper('helperMissing', function(/* [args, ]options */) {
    if(arguments.length === 1) {
      // A missing field in a {{foo}} constuct.
      return undefined;
    } else {
      // Someone is actually trying to call something, blow up.
      throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
    }
  });

  instance.registerHelper('blockHelperMissing', function(context, options) {
    var inverse = options.inverse,
        fn = options.fn;

    if(context === true) {
      return fn(this);
    } else if(context === false || context == null) {
      return inverse(this);
    } else if (isArray(context)) {
      if(context.length > 0) {
        if (options.ids) {
          options.ids = [options.name];
        }

        return instance.helpers.each(context, options);
      } else {
        return inverse(this);
      }
    } else {
      if (options.data && options.ids) {
        var data = createFrame(options.data);
        data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
        options = {data: data};
      }

      return fn(context, options);
    }
  });

  instance.registerHelper('each', function(context, options) {
    if (!options) {
      throw new Exception('Must pass iterator to #each');
    }

    var fn = options.fn, inverse = options.inverse;
    var i = 0, ret = "", data;

    var contextPath;
    if (options.data && options.ids) {
      contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
    }

    if (isFunction(context)) { context = context.call(this); }

    if (options.data) {
      data = createFrame(options.data);
    }

    if(context && typeof context === 'object') {
      if (isArray(context)) {
        for(var j = context.length; i<j; i++) {
          if (data) {
            data.index = i;
            data.first = (i === 0);
            data.last  = (i === (context.length-1));

            if (contextPath) {
              data.contextPath = contextPath + i;
            }
          }
          ret = ret + fn(context[i], { data: data });
        }
      } else {
        for(var key in context) {
          if(context.hasOwnProperty(key)) {
            if(data) {
              data.key = key;
              data.index = i;
              data.first = (i === 0);

              if (contextPath) {
                data.contextPath = contextPath + key;
              }
            }
            ret = ret + fn(context[key], {data: data});
            i++;
          }
        }
      }
    }

    if(i === 0){
      ret = inverse(this);
    }

    return ret;
  });

  instance.registerHelper('if', function(conditional, options) {
    if (isFunction(conditional)) { conditional = conditional.call(this); }

    // Default behavior is to render the positive path if the value is truthy and not empty.
    // The `includeZero` option may be set to treat the condtional as purely not empty based on the
    // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
    if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
      return options.inverse(this);
    } else {
      return options.fn(this);
    }
  });

  instance.registerHelper('unless', function(conditional, options) {
    return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
  });

  instance.registerHelper('with', function(context, options) {
    if (isFunction(context)) { context = context.call(this); }

    var fn = options.fn;

    if (!Utils.isEmpty(context)) {
      if (options.data && options.ids) {
        var data = createFrame(options.data);
        data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
        options = {data:data};
      }

      return fn(context, options);
    } else {
      return options.inverse(this);
    }
  });

  instance.registerHelper('log', function(context, options) {
    var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
    instance.log(level, context);
  });

  instance.registerHelper('lookup', function(obj, field, options) {
    return obj && obj[field];
  });
}

export var logger = {
  methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },

  // State enum
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3,
  level: 3,

  // can be overridden in the host environment
  log: function(level, obj) {
    if (logger.level <= level) {
      var method = logger.methodMap[level];
      if (typeof console !== 'undefined' && console[method]) {
        console[method].call(console, obj);
      }
    }
  }
};

export var log = logger.log;

export var createFrame = function(object) {
  var frame = Utils.extend({}, object);
  frame._parent = object;
  return frame;
};
<|endoftext|>


<commit_before>'use strict';
/**
 * @file Update an account from specified access_token
 *
 */

var async = require('async');
var restify = require('restify');
var rarity = require('rarity');

var Token = require('../models/token.js');

/**
 * This handler downloads data for the specified access_token and starts uploading them onto AnyFetch.
 *
 */
module.exports = function(updateAccount, queue, workers) {
  return function(req, res, next) {
    if(!req.params.access_token) {
      console.warn("ERR: Missing access_token parameter.");
      return next(new restify.MissingParameterError("Missing access_token parameter."));
    }
    if(!req.params.api_url) {
      console.warn("ERR: Missing api_url parameter.");
      return next(new restify.MissingParameterError("Missing api_url parameter."));
    }
    if(!req.params.documents_per_update && !req.params.identifier) {
      console.warn("ERR: Missing documents_per_update parameter.");
      return next(new restify.MissingParameterError("Missing documents_per_update parameter."));
    }

    Token.findOne({anyfetchToken: req.params.access_token}, function(err, token) {
      if(err) {
        console.warn("ERR:", err);
        return next(err);
      }
      if(!token) {
        console.warn("ERR: Unknown token.");
        return next(new restify.InvalidArgumentError("Unknown token."));
      }
      if(token.isUpdating && Date.now() - token.lastUpdate.getTime() > 5 * 3600 * 1000) {
        console.warn("ERR: Already processing");
        return next(new restify.TooManyRequestsError('Already processing'));
      }
      else {
        res.send(202);
      }
      next();

      async.waterfall([
        function updateToken(cb) {
          if (req.params.identifier) {
            return cb(null);
          }

          // Update token
          token.lastUpdate = new Date();
          token.isUpdating = true;

          token.save(rarity.slice(1, cb));
        },
        function callUpdateAccount(cb) {
          var queues = {};

          Object.keys(workers).forEach(function(name) {
            queues[name] = [];
          });

          updateAccount(token.data || {}, (req.params.ideatifier) ? null : token.cursor, queues, function(err, newCursor, providerData) {
            cb(err, queues, newCursor, providerData);
          });
        },
        function updateToken(queues, newCursor, providerData, cb) {
          if (req.params.identifier) {
            return cb(null, queues);
          }

          if(providerData) {
            token.data = providerData;
            token.markModified('data');
          }
          token.cursor = newCursor;
          token.isUpdating = false;

          token.save(rarity.carryAndSlice([queues], 2, cb));
        },
        function executeQueue(queues, cb) {
          Object.keys(workers).forEach(function(name) {
            // The limit is applied for each queue. (For Anyfetch's providers, queues are addition and deletion)
            var documentsCount = 0;
            console.log("User `" + token.accountName + "` pushed " + queues[name].length + " tasks onto queue `" + name + "`");
            queues[name].every(function(task) {
              if((documentsCount < req.params.documents_per_update && !req.params.identifier) || (task.identifier === req.params.identifier)) {
                if (req.params.identifier) {
                  console.log("Reproviding", task.title, "(", task.identifier, ")");
                }

                task._anyfetchToken = token.anyfetchToken;
                task._anyfetchApiUrl = req.params.api_url;
                queue.create(name, task).removeOnComplete(true).save();
                documentsCount += 1;
                return (req.params.identifier) ? false : true;
              }
              return (req.params.identifier) ? true : false;
            });
          });
          cb(null);
        }
      ], function(err) {
        if(err) {
          console.warn('ERR:', err);
        }
      });
    });
  };
};
<commit_msg>Add a warn<commit_after>'use strict';
/**
 * @file Update an account from specified access_token
 *
 */

var async = require('async');
var restify = require('restify');
var rarity = require('rarity');

var Token = require('../models/token.js');

/**
 * This handler downloads data for the specified access_token and starts uploading them onto AnyFetch.
 *
 */
module.exports = function(updateAccount, queue, workers) {
  return function(req, res, next) {
    if(!req.params.access_token) {
      console.warn("ERR: Missing access_token parameter.");
      return next(new restify.MissingParameterError("Missing access_token parameter."));
    }
    if(!req.params.api_url) {
      console.warn("ERR: Missing api_url parameter.");
      return next(new restify.MissingParameterError("Missing api_url parameter."));
    }
    if(!req.params.documents_per_update && !req.params.identifier) {
      console.warn("ERR: Missing documents_per_update parameter.");
      return next(new restify.MissingParameterError("Missing documents_per_update parameter."));
    }

    Token.findOne({anyfetchToken: req.params.access_token}, function(err, token) {
      if(err) {
        console.warn("ERR:", err);
        return next(err);
      }
      if(!token) {
        console.warn("ERR: Unknown token.");
        return next(new restify.InvalidArgumentError("Unknown token."));
      }
      if(token.isUpdating) {
        console.warn("ERR: Already processing");

        if(Date.now() - token.lastUpdate.getTime() < 5 * 3600 * 1000) {
          return next(new restify.TooManyRequestsError('Already processing'));
        }
      }
      else {
        res.send(202);
      }
      next();

      async.waterfall([
        function updateToken(cb) {
          if (req.params.identifier) {
            return cb(null);
          }

          // Update token
          token.lastUpdate = new Date();
          token.isUpdating = true;

          token.save(rarity.slice(1, cb));
        },
        function callUpdateAccount(cb) {
          var queues = {};

          Object.keys(workers).forEach(function(name) {
            queues[name] = [];
          });

          updateAccount(token.data || {}, (req.params.ideatifier) ? null : token.cursor, queues, function(err, newCursor, providerData) {
            cb(err, queues, newCursor, providerData);
          });
        },
        function updateToken(queues, newCursor, providerData, cb) {
          if (req.params.identifier) {
            return cb(null, queues);
          }

          if(providerData) {
            token.data = providerData;
            token.markModified('data');
          }
          token.cursor = newCursor;
          token.isUpdating = false;

          token.save(rarity.carryAndSlice([queues], 2, cb));
        },
        function executeQueue(queues, cb) {
          Object.keys(workers).forEach(function(name) {
            // The limit is applied for each queue. (For Anyfetch's providers, queues are addition and deletion)
            var documentsCount = 0;
            console.log("User `" + token.accountName + "` pushed " + queues[name].length + " tasks onto queue `" + name + "`");
            queues[name].every(function(task) {
              if((documentsCount < req.params.documents_per_update && !req.params.identifier) || (task.identifier === req.params.identifier)) {
                if (req.params.identifier) {
                  console.log("Reproviding", task.title, "(", task.identifier, ")");
                }

                task._anyfetchToken = token.anyfetchToken;
                task._anyfetchApiUrl = req.params.api_url;
                queue.create(name, task).removeOnComplete(true).save();
                documentsCount += 1;
                return (req.params.identifier) ? false : true;
              }
              return (req.params.identifier) ? true : false;
            });
          });
          cb(null);
        }
      ], function(err) {
        if(err) {
          console.warn('ERR:', err);
        }
      });
    });
  };
};
<|endoftext|>


<commit_before>module.exports.encode = function (input, n) {
    var output = [];
    var x = Math.pow(2, n) - 1;
    if (input < x) {
        output.push(input);
    } else {
        output.push(x);
        input = input - x;
        while (input >= 128) {
            output.push(input % 128 + 128);
            input = parseInt(input / 128, 10);
        }
        output.push(input);
    }
    return new Buffer(output);
};
module.exports.decode = function (input, offset, n) {
    var i, j = 0, m = 0;
    i = input[offset + 0] & Math.pow(2, n) - 1;
    if (i === Math.pow(2, n) - 1) {
        do {
            j++;
            i += (input[offset + j] & 0x7F) * Math.pow(2, m);
            m += 7;
        } while (input[offset + j] & 0x80);
    }
    return {
        'value': i,
        'len': j + 1
    };
};
<commit_msg>eliminate use of Math.pow<commit_after>module.exports.encode = function (input, n) {
    var output = [];
    var x = (1 << n) - 1;
    if (input < x) {
        output.push(input);
    } else {
        output.push(x);
        input = input - x;
        while (input >= 128) {
            output.push(input % 128 + 128);
            input = parseInt(input / 128, 10);
        }
        output.push(input);
    }
    return new Buffer(output);
};
module.exports.decode = function (input, offset, n) {
    var i, j = 0, m = 0;
    i = input[offset + 0] & Math.pow(2, n) - 1;
    if (i === (1 << n) - 1) {
        do {
            j++;
            i += (input[offset + j] & 0x7F) * (1 << m);
            m += 7;
        } while (input[offset + j] & 0x80);
    }
    return {
        'value': i,
        'len': j + 1
    };
};
<|endoftext|>


<commit_before>var _= require('underscore'),
    async= require('async');

const  _oa = function(o, s)
       {
             s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
             s = s.replace(/^\./, '');           // strip a leading dot
             var a = s.split('.');
             while (a.length) {
                 var n = a.shift();
                 if (n in o) {
                     o = o[n];
                 } else {
                     return;
                 }
             }
             return o;
       };

module.exports= function (dyn,table,fields)
{
     var index= {},
         _fields= _.collect(Object.keys(fields),
                            function (fieldName)
                            {
                                var type= fields[fieldName];

                                if (type.secondary)
                                  return { name: fieldName,
                                           type: type.type,
                                      secondary: true };
                                else
                                  return { name: fieldName,
                                           type: type };
                            }),
         primaryFieldNames= [],
         secondaryFieldNames= [];

     index.name= table._dynamo.TableName+'--'
                 +_.collect(_fields,
                            function (field) { return field.secondary ?
                                                      '__'+field.name :
                                                      field.name; })
                   .join('-').replace(/\$/g,'_');

     var unhandled= false;

     _fields.every(function (field)
     {
         if (field.secondary)
           secondaryFieldNames.push(field.name);
         else
           primaryFieldNames.push(field.name);

         if (!_.contains(['S','N'],field.type))
           return !(unhandled=true);

         return true;
     });

     if (unhandled) return false;

     index.create= function (done)
     {
            var _secondary= function ()
            {
                var secondaryFields= _.filter(_fields,function (field) { return !!field.secondary; });
                return _.collect(secondaryFields,
                       function (field)
                       {
                            return { name: field.name,
                                     key: { name: field.name,
                                            type: field.type },
                                     projection: ['$id','$pos','$version'] };
                       });
            };

            dyn.table(index.name)
               .hash('$hash','S')
               .range('$range','S')
               .create(function indexItems()
               {
                  dyn.table(index.name)
                     .hash('$hash','xx')
                     .query(function ()
                  {
                     done(new Error('Should not find anything!'));
                  })
                  .error(function (err)
                  {
                     if (err.code=='ResourceNotFoundException')
                       setTimeout(indexItems,5000);
                     else
                     if (err.code=='notfound')
                       table.find().results(function (items)
                       {
                           async.forEach(items,index.put,done);
                       })
                       .error(done);
                     else
                       done(err);
                  });
               },{ secondary: _secondary() })
               .error(function (err)
               {
                   if (err.code=='ResourceInUseException')
                     setTimeout(function () { index.ensure(done) },5000);
                   else
                     done(err);
               });
     };

     index.makeHash= function (item)
     {
        return _.collect(primaryFieldNames,
                         function (fieldName) { return _oa(item,fieldName); }).join(':');
     };

     index.makeCondHash= function (cond)
     {
        return _.collect(primaryFieldNames,
                         function (fieldName) { return cond[fieldName]; }).join(':');
     };

     index.makeRange= function (item)
     {
        return item.$id+':'+item.$pos;
     };

     index.indexable= function (item)
     {
        return item&&!_.some(primaryFieldNames,
                       function (fieldName) { return !_oa(item,fieldName); });
     };

     index.usable= function (cond)
     {
        return cond&&!_.some(primaryFieldNames,
                       function (fieldName) { return !cond[fieldName]||(cond[fieldName] instanceof RegExp); });
     };

     index.makeElement= function (item)
     {
        return _.extend(_.pick(item,_.union(['$id','$pos','$version'],
                                            secondaryFieldNames)),
                        { '$hash': index.makeHash(item),
                          '$range': index.makeRange(item) });
     };

     index.find= function (query)
     {
       var p= dyn.promise(['results','count']),
           hash= index.makeCondHash(query.cond),
           tab= dyn.table(index.name)
                   .hash('$hash',hash),
           sort;

       if (query.orderby)
         Object.keys(query.orderby).every(function (field)
         {
             sort= { field: field, asc: query.orderby[field]>0 };
             return false;
         });

       if (sort)
         tab.index(sort.field);

       tab.query(query.count ? p.trigger.count : p.trigger.results,
       { attrs: ['$id','$pos'], desc: sort&&!sort.asc, limit: query.limit, count: query.count })
       .error(p.trigger.error);

       return p;

     };

     return index;
};

<commit_msg>initial support for sub-hash indexes<commit_after>var _= require('underscore'),
    ret= require('ret'),
    async= require('async');

const  _oa = function(o, s)
       {
             s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
             s = s.replace(/^\./, '');           // strip a leading dot
             var a = s.split('.');
             while (a.length) {
                 var n = a.shift();
                 if (n in o) {
                     o = o[n];
                 } else {
                     return;
                 }
             }
             return o;
       };

module.exports= function (dyn,table,fields)
{
     var index= {},
         _fields= _.collect(Object.keys(fields),
                            function (fieldName)
                            {
                                var type= fields[fieldName];

                                if (type.secondary)
                                  return { name: fieldName,
                                           type: type.type,
                                      secondary: true };
                                else
                                  return { name: fieldName,
                                           type: type };
                            }),
         primaryFieldNames= [],
         secondaryFieldNames= [];

     index.name= table._dynamo.TableName+'--'
                 +_.collect(_fields,
                            function (field) { return field.secondary ?
                                                      '__'+field.name :
                                                      field.name; })
                   .join('-').replace(/\$/g,'_');

     var unhandled= false;

     _fields.every(function (field)
     {
         if (field.secondary)
           secondaryFieldNames.push(field.name);
         else
           primaryFieldNames.push(field.name);

         if (!_.contains(['S','N'],field.type)&&!field.secondary)
           return !(unhandled=true);

         return true;
     });

     if (unhandled) return false;

     index.create= function (done)
     {
            var _secondary= function ()
            {
                var secondaryFields= _.filter(_fields,function (field) { return !!field.secondary; });
                return _.collect(secondaryFields,
                       function (field)
                       {
                            return { name: field.name,
                                     key: { name: field.name,
                                            type: field.type=='BW' ? 'S' : field.type },
                                     projection: ['$id','$pos','$version'] };
                       });
            };

            dyn.table(index.name)
               .hash('$hash','S')
               .range('$range','S')
               .create(function indexItems()
               {
                  dyn.table(index.name)
                     .hash('$hash','xx')
                     .query(function ()
                  {
                     done(new Error('Should not find anything!'));
                  })
                  .error(function (err)
                  {
                     if (err.code=='ResourceNotFoundException')
                       setTimeout(indexItems,5000);
                     else
                     if (err.code=='notfound')
                       table.find().results(function (items)
                       {
                           async.forEach(items,index.put,done);
                       })
                       .error(done);
                     else
                       done(err);
                  });
               },{ secondary: _secondary() })
               .error(function (err)
               {
                   if (err.code=='ResourceInUseException')
                     setTimeout(function () { index.ensure(done) },5000);
                   else
                     done(err);
               });
     };

     index.makeHash= function (item)
     {
        return _.collect(primaryFieldNames,
                         function (fieldName) { return _oa(item,fieldName); }).join(':');
     };

     index.makeCondHash= function (cond)
     {
        return _.collect(primaryFieldNames,
                         function (fieldName) { return cond[fieldName]; }).join(':');
     };

     index.makeRange= function (item)
     {
        return item.$id+':'+item.$pos;
     };

     index.indexable= function (item)
     {
        return item&&!_.some(primaryFieldNames,
                       function (fieldName) { return !_oa(item,fieldName); });
     };

     index.usable= function (cond)
     {
        return cond&&!_.some(primaryFieldNames,
                       function (fieldName) { return !cond[fieldName]||(cond[fieldName] instanceof RegExp); });
     };

     index.makeElement= function (item)
     {
        return _.extend(_.pick(item,_.union(['$id','$pos','$version'],
                                            secondaryFieldNames)),
                        { '$hash': index.makeHash(item),
                          '$range': index.makeRange(item) });
     };

     index.find= function (query)
     {
       var p= dyn.promise(['results','count']),
           hash= index.makeCondHash(query.cond),
           tab= dyn.table(index.name)
                   .hash('$hash',hash),
           sort;

       if (secondaryFieldNames[0]&&query.cond[secondaryFieldNames[0]]!==undefined)
       {
            var field= secondaryFieldNames[0],
                val= query.cond[field],
                op= 'EQ';

            tab.index(field);

            if (val instanceof RegExp)
            {
                  var tks= ret(val.source),
                      _chars= function (start)
                      {
                          return _.collect(tks.stack.slice(start),
                                   function (tk) { return String.fromCharCode(tk.value); })
                                  .join('');
                      };

                  if (tks.stack
                      &&tks.stack[0]
                      &&tks.stack[0].type==ret.types.POSITION
                      &&tks.stack[0].value=='^'
                      &&!_.filter(tks.stack.slice(1),function (tk) { return tk.type!=ret.types.CHAR; }).length)
                  {
                    val= _chars(1);
                    op= 'BEGINS_WITH';
                  }
                  else
                    val='';
            }

            if (val!='')
              tab.range(field,val,op);
       }
       else
       {
           if (query.orderby)
             Object.keys(query.orderby).every(function (field)
             {
                 sort= { field: field, asc: query.orderby[field]>0 };
                 return false;
             });

           if (sort)
             tab.index(sort.field);
       }

       tab.query(query.count ? p.trigger.count : p.trigger.results,
       { attrs: ['$id','$pos'], desc: sort&&!sort.asc, limit: query.limit, count: query.count })
       .error(p.trigger.error);

       return p;

     };

     return index;
};

<|endoftext|>


<commit_before>var http        = require('http');
var request     = require('request')
var querystring = require('querystring');
var version     = '0.7.0';
var fs          = require('fs');

module.exports = {
    request: function (secure, auth, method, uri, qs, params, callback) {
        if (auth) {
            if (auth.apiKey !== undefined) {
                auth = 'Basic ' + new Buffer(auth.apiKey + ':magic').toString('base64');
            } else if (auth.username !== undefined) {
                auth = 'Basic ' + new Buffer(auth.username + ':' + auth.password).toString('base64');
            }
        }

        callback = callback || function () {};

        if (qs) {
            uri += '?' + querystring.stringify(qs);
        }

        var options = {
            method: method,
            uri: uri,
            headers: {
                'Authorization': auth,
                'User-Agent': 'node-createsend/v' + version
            },
            body: JSON.stringify(params),
            timeout: 10000
        };

        if (secure) {
            //options.ca = [ fs.readFileSync('./lib/cacert.pem') ];
            //soptions.rejectUnauthorized = true;
        }

        request(
            options,
            function (error, response, body) {
                if (error) { return callback(error); }

                var code = response.statusCode;
                if (code == 200 || code == 201) {
                    if (body) {
                        try {
                            callback(null, JSON.parse(body));
                        } catch (e) {
                            callback(new Error('Unable to parse JSON.  Error: ' + e + '\nBody:\n' + body));
                        }
                    } else {
                        callback(null);
                    }
                } else {
                    callback(JSON.parse(body));
                }
            }
        );
    }
}<commit_msg>Certificate validation is now in place.<commit_after>var http        = require('http');
var request     = require('request')
var querystring = require('querystring');
var version     = '0.7.0';
var fs          = require('fs');

module.exports = {
    request: function (secure, auth, method, uri, qs, params, callback) {
        if (auth) {
            if (auth.apiKey !== undefined) {
                auth = 'Basic ' + new Buffer(auth.apiKey + ':magic').toString('base64');
            } else if (auth.username !== undefined) {
                auth = 'Basic ' + new Buffer(auth.username + ':' + auth.password).toString('base64');
            }
        }

        callback = callback || function () {};

        if (qs) {
            uri += '?' + querystring.stringify(qs);
        }

        var options = {
            method: method,
            uri: uri,
            headers: {
                'Authorization': auth,
                'User-Agent': 'node-createsend/v' + version
            },
            body: JSON.stringify(params),
            timeout: 10000
        };

        if (secure) {
            options.rejectUnauthorized = true;
        }

        request(
            options,
            function (error, response, body) {
                if (error) { return callback(error); }

                var code = response.statusCode;
                if (code == 200 || code == 201) {
                    if (body) {
                        try {
                            callback(null, JSON.parse(body));
                        } catch (e) {
                            callback(new Error('Unable to parse JSON.  Error: ' + e + '\nBody:\n' + body));
                        }
                    } else {
                        callback(null);
                    }
                } else {
                    callback(JSON.parse(body));
                }
            }
        );
    }
}<|endoftext|>


<commit_before>'use babel'

/* @flow */

import MessageAdapter from './message-adapter'
import { Emitter }    from 'atom'

type ResolveHandler = (o: Promise<any> | any) => void
type RejectHandler  = (e: any) => void
type ResultHandler  = {resolve: ResolveHandler, reject: RejectHandler}

export default class InterpreterMi2 {
  emitter: Emitter;
  adapter: MessageAdapter;
  resultHandlerQueue: Array<ResultHandler>;

  constructor() {
    this.emitter            = new Emitter()
    this.adapter            = new MessageAdapter()
    this.resultHandlerQueue = []
  }

  interpret(data: string) {

    const SessionEvent    = require('./main').SessionEvent
    const TargetEvent     = require('./main').TargetEvent

    if (!SessionEvent) {
      throw Error('SessionEvent must not be null')
    }

    if (!TargetEvent) {
      throw Error('TargetEvent must not be null')
    }

    for (let line of data.split('\n')) {

      const resultBegin = line.indexOf(',')
      const result = (resultBegin > 0) ?
        this.convertResult(line.slice(resultBegin+1)) : undefined

      if (/^\*running/.test(line)) {

        this.emitter.emit('session', new SessionEvent('resumed'))
      } else if (/^\*stopped/.test(line)) {

        if (!result || typeof result.reason !== 'string' ) {
          throw new Error('result.reason must be string')
        }

        if (result.reason == 'breakpoint-hit') {

          let message = this.adapter.adaptSessionMessage(result)
          this.emitter.emit('session', new SessionEvent('suspended', 'breakpoint', message))
        } else if (result.reason == 'exited-normally') {

          this.emitter.emit('session', new SessionEvent('will-terminate'))
        }
      } else if (/^\^done|\^running/.test(line)) {

        if (this.resultHandlerQueue.length == 0) { return }

        let handler = this.resultHandlerQueue.shift()

        handler.resolve(result)

      } else if (/^\^error/.test(line)) {

        const message = (result) ? result.msg : 'Unknown error occured'
        atom.notifications.addError(message, { dismissable: true })

        let handler = this.resultHandlerQueue.shift()

        handler.reject(result)
      } else if (/^\^exit/.test(line)) {

        let handler = this.resultHandlerQueue.shift()

        handler.resolve(result)

        this.emitter.emit('session', new SessionEvent('terminated', 'normally'))

      } else if (/^@/.test(line)) {

        if (!line.startsWith('@"')) {
          this.emitter.emit('target', new TargetEvent('output', line.substr(1)))
        }

        let stripped = line.slice(2,-1)

        stripped = stripped.replace('\\r', '\r').replace('\\n', '\n')

        this.emitter.emit('target', new TargetEvent('output', stripped))
      }
    }
  }

  convertValue(value: string): mixed {

    const stripped = value.slice(1,-1)

    if (value.charAt(0) == '"') {

      return stripped
    } else if (value.charAt(0) == '{') {

      return this.convertResult(stripped)
    } else if (value.charAt(0) == '[') {

      const isNamed = (value.indexOf('=') < value.search(/[{("]/))

      let result = []

      let indexStart = 0
      let scopeDepth = 0
      let name

      for (let i=0; i<stripped.length; i++) {
        if (stripped.charAt(i) === '{') {
          scopeDepth++
        } else if (stripped.charAt(i) === '}') {
          scopeDepth--
        } else if (isNamed && stripped.charAt(i) === '=' && scopeDepth === 0) {
          name       = stripped.substring(indexStart, i)
          indexStart = i+1;
        } else if (stripped.charAt(i) === ',' && scopeDepth === 0) {
          const attribute  = stripped.substring(indexStart, i)

          let value
          if (isNamed) {
            value       = new Object
            value[name] = this.convertValue(attribute)
          } else {
            value = this.convertValue(attribute)
          }

          result.push(value)
          indexStart = i+1
        }
      }

      const attribute  = stripped.substring(indexStart)

      if (isNamed) {
        let value   = new Object
        value[name] = this.convertValue(attribute)
        result.push(value)
      } else {
        result.push(this.convertValue(attribute))
      }

      return result
    }
  }

  convertResult(value: string): Object {
    let result = new Object;

    let indexStart = 0
    let scopeDepth = 0
    let isQuoted   = false

    for (let i=0; i<value.length; i++) {
      if (value.charAt(i) === '"') {
        isQuoted = !isQuoted
      } else if (!isQuoted && value.charAt(i) == '{' || value.charAt(i) == '[') {
        scopeDepth++
      } else if (!isQuoted && value.charAt(i) == '}' || value.charAt(i) == ']') {
        scopeDepth--
      } else if (!isQuoted && value.charAt(i) == ',' && scopeDepth == 0) {

        const attribute  = value.substring(indexStart, i)
        const name       = attribute.slice(0, attribute.indexOf('='))
        const val        = attribute.slice(attribute.indexOf('=')+1)

        result[name] = this.convertValue(val)
        indexStart = i+1
      }
    }

    const attribute  = value.substring(indexStart)
    const name       = attribute.slice(0, attribute.indexOf('='))
    const val        = attribute.slice(attribute.indexOf('=')+1)

    result[name] = this.convertValue(val)

    return result
  }

  pushResultHandler(resolve: ResolveHandler, reject: RejectHandler) {
    this.resultHandlerQueue.push({resolve: resolve, reject: reject});
  }
}
<commit_msg>Fix: emit 'end-stepping-range' events<commit_after>'use babel'

/* @flow */

import MessageAdapter from './message-adapter'
import { Emitter }    from 'atom'

type ResolveHandler = (o: Promise<any> | any) => void
type RejectHandler  = (e: any) => void
type ResultHandler  = {resolve: ResolveHandler, reject: RejectHandler}

export default class InterpreterMi2 {
  emitter: Emitter;
  adapter: MessageAdapter;
  resultHandlerQueue: Array<ResultHandler>;

  constructor() {
    this.emitter            = new Emitter()
    this.adapter            = new MessageAdapter()
    this.resultHandlerQueue = []
  }

  interpret(data: string) {

    const SessionEvent    = require('./main').SessionEvent
    const TargetEvent     = require('./main').TargetEvent

    if (!SessionEvent) {
      throw Error('SessionEvent must not be null')
    }

    if (!TargetEvent) {
      throw Error('TargetEvent must not be null')
    }

    for (let line of data.split('\n')) {

      const resultBegin = line.indexOf(',')
      const result = (resultBegin > 0) ?
        this.convertResult(line.slice(resultBegin+1)) : undefined

      if (/^\*running/.test(line)) {

        this.emitter.emit('session', new SessionEvent('resumed'))
      } else if (/^\*stopped/.test(line)) {

        if (!result || typeof result.reason !== 'string' ) {
          throw new Error('result.reason must be string')
        }

        if (result.reason === 'breakpoint-hit') {

          let message = this.adapter.adaptSessionMessage(result)
          this.emitter.emit('session', new SessionEvent('suspended', 'breakpoint', message))
        } else if (result.reason === 'end-stepping-range') {

          let message = this.adapter.adaptSessionMessage(result)
          this.emitter.emit('session', new SessionEvent('suspended', 'step', message))
        } else if (result.reason === 'exited-normally') {

          this.emitter.emit('session', new SessionEvent('will-terminate'))
        }
      } else if (/^\^done|\^running/.test(line)) {

        if (this.resultHandlerQueue.length == 0) { return }

        let handler = this.resultHandlerQueue.shift()

        handler.resolve(result)

      } else if (/^\^error/.test(line)) {
        let handler = this.resultHandlerQueue.shift()

        handler.reject(result)
      } else if (/^\^exit/.test(line)) {

        let handler = this.resultHandlerQueue.shift()

        handler.resolve(result)

        this.emitter.emit('session', new SessionEvent('terminated', 'normally'))

      } else if (/^@/.test(line)) {

        if (!line.startsWith('@"')) {
          this.emitter.emit('target', new TargetEvent('output', line.substr(1)))
        }

        let stripped = line.slice(2,-1)

        stripped = stripped.replace('\\r', '\r').replace('\\n', '\n')

        this.emitter.emit('target', new TargetEvent('output', stripped))
      }
    }
  }

  convertValue(value: string): mixed {

    const stripped = value.slice(1,-1)

    if (value.charAt(0) == '"') {

      return stripped
    } else if (value.charAt(0) == '{') {

      return this.convertResult(stripped)
    } else if (value.charAt(0) == '[') {

      const isNamed = (value.indexOf('=') < value.search(/[{("]/))

      let result = []

      let indexStart = 0
      let scopeDepth = 0
      let name

      for (let i=0; i<stripped.length; i++) {
        if (stripped.charAt(i) === '{') {
          scopeDepth++
        } else if (stripped.charAt(i) === '}') {
          scopeDepth--
        } else if (isNamed && stripped.charAt(i) === '=' && scopeDepth === 0) {
          name       = stripped.substring(indexStart, i)
          indexStart = i+1;
        } else if (stripped.charAt(i) === ',' && scopeDepth === 0) {
          const attribute  = stripped.substring(indexStart, i)

          let value
          if (isNamed) {
            value       = new Object
            value[name] = this.convertValue(attribute)
          } else {
            value = this.convertValue(attribute)
          }

          result.push(value)
          indexStart = i+1
        }
      }

      const attribute  = stripped.substring(indexStart)

      if (attribute === '') {
        return result
      }

      if (isNamed) {
        let value   = new Object
        value[name] = this.convertValue(attribute)
        result.push(value)
      } else {
        result.push(this.convertValue(attribute))
      }

      return result
    }
  }

  convertResult(value: string): Object {
    let result = new Object;

    let indexStart = 0
    let scopeDepth = 0
    let isQuoted   = false

    for (let i=0; i<value.length; i++) {
      if (value.charAt(i) === '"') {
        isQuoted = !isQuoted
      } else if (!isQuoted && value.charAt(i) == '{' || value.charAt(i) == '[') {
        scopeDepth++
      } else if (!isQuoted && value.charAt(i) == '}' || value.charAt(i) == ']') {
        scopeDepth--
      } else if (!isQuoted && value.charAt(i) == ',' && scopeDepth == 0) {

        const attribute  = value.substring(indexStart, i)
        const name       = attribute.slice(0, attribute.indexOf('='))
        const val        = attribute.slice(attribute.indexOf('=')+1)

        result[name] = this.convertValue(val)
        indexStart = i+1
      }
    }

    const attribute  = value.substring(indexStart)
    const name       = attribute.slice(0, attribute.indexOf('='))
    const val        = attribute.slice(attribute.indexOf('=')+1)

    result[name] = this.convertValue(val)

    return result
  }

  pushResultHandler(resolve: ResolveHandler, reject: RejectHandler) {
    this.resultHandlerQueue.push({resolve: resolve, reject: reject});
  }
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

module.exports = angular.module('trafficOps.private.admin.profiles.deliveryServices', [])
	.config(function($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('trafficOps.private.admin.profiles.deliveryServices', {
				url: '/{profileId}/delivery-services',
				views: {
					profilesContent: {
						templateUrl: 'common/modules/table/profileDeliveryServices/table.profileDeliveryServices.tpl.html',
						controller: 'TableProfileDeliveryServicesController',
						resolve: {
							profile: function($stateParams, profileService) {
								return profileService.getProfile($stateParams.profileId);
							},
							deliveryServices: function($stateParams, deliveryServiceService) {
								return deliveryServiceService.getDeliveryServices({ profileId: $stateParams.profileId });
							}
						}
					}
				}
			})
		;
		$urlRouterProvider.otherwise('/');
	});
<commit_msg>filters ds by profile<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

module.exports = angular.module('trafficOps.private.admin.profiles.deliveryServices', [])
	.config(function($stateProvider, $urlRouterProvider) {
		$stateProvider
			.state('trafficOps.private.admin.profiles.deliveryServices', {
				url: '/{profileId}/delivery-services',
				views: {
					profilesContent: {
						templateUrl: 'common/modules/table/profileDeliveryServices/table.profileDeliveryServices.tpl.html',
						controller: 'TableProfileDeliveryServicesController',
						resolve: {
							profile: function($stateParams, profileService) {
								return profileService.getProfile($stateParams.profileId);
							},
							deliveryServices: function($stateParams, deliveryServiceService) {
								return deliveryServiceService.getDeliveryServices({ profile: $stateParams.profileId });
							}
						}
					}
				}
			})
		;
		$urlRouterProvider.otherwise('/');
	});
<|endoftext|>


<commit_before>import FS from "fs";
import Path from "path";
import _ from "lodash-fp";

export const title = "Day 12: JSAbacusFramework.io";

function visit(node, customizer = _.constant(true)) {
    if (!customizer(node))
        return 0;

    if (_.isArray(node))
        return _.map((x) => visit(x, customizer), node);

    if (_.isObject(node))
        return _.map((k) => visit(node[k], customizer), Object.keys(node));

    return node;
}

function reduceDeep(collection, func, start, customizer) {
    const values = _.flattenDeep(visit(collection, customizer));
    let value = start;

    for (let i = 0; i < values.length; i += 1) {
        value = func(value, values[i], i, values);
    }

    return value;
}

export function total(collection, customizer) {
    return reduceDeep(collection, _.add, 0, customizer);
}

export function run() {
    const inputPath = Path.join(__dirname, "input.json");
    const input = JSON.parse(FS.readFileSync(inputPath, "utf-8"));

    console.log("What is the sum of all numbers in the document?", total(input));
}
<commit_msg>Completed part 2. - Spoiler alert: the answer is 96852.<commit_after>import FS from "fs";
import Path from "path";
import _ from "lodash-fp";

export const title = "Day 12: JSAbacusFramework.io";

function visit(node, customizer = _.constant(true)) {
    if (!customizer(node))
        return 0;

    if (_.isArray(node))
        return _.map((x) => visit(x, customizer), node);

    if (_.isObject(node))
        return _.map((k) => visit(node[k], customizer), Object.keys(node));

    return node;
}

function reduceDeep(collection, func, start, customizer) {
    const values = _.flattenDeep(visit(collection, customizer));
    let value = start;

    for (let i = 0; i < values.length; i += 1) {
        value = func(value, values[i], i, values);
    }

    return value;
}

export function total(collection, customizer) {
    return reduceDeep(collection, _.add, 0, customizer);
}

export function run() {
    const inputPath = Path.join(__dirname, "input.json");
    const input = JSON.parse(FS.readFileSync(inputPath, "utf-8"));
    const customizer = (node) => {
        if (_.isPlainObject(node))
            return !_.includes("red", node);

        return true;
    };

    console.log("What's the sum of all the numbers?", total(input));
    console.log("What's the sum of all numbers (ignoring object nodes with the value 'red')?", total(input, customizer));
}
<|endoftext|>


<commit_before>import R from 'ramda'
import { PAGE_SIZE } from '../../config'

import {
  asyncRes,
  asyncErr,
  makeDebugger,
  dispatchEvent,
  EVENT,
  ERR,
  TYPE,
  ROUTE,
  THREAD,
  $solver,
  scrollIntoEle,
  // GA,
} from '../../utils'

import S from './schema'
import SR71 from '../../utils/network/sr71'

const sr71$ = new SR71({
  resv_event: [
    EVENT.REFRESH_POSTS,
    EVENT.PREVIEW_CLOSED,
    EVENT.COMMUNITY_CHANGE,
    EVENT.TABBER_CHANGE,
  ],
})
/* eslint-disable no-unused-vars */
const debug = makeDebugger('L:PostsThread')
/* eslint-enable no-unused-vars */

let store = null
let sub$ = null

// TODO: move to utils
const validFilter = R.pickBy(R.compose(R.not, R.isEmpty))

export const inAnchor = () => store.setHeaderFix(false)
export const outAnchor = () => store.setHeaderFix(true)

export function loadPosts(page = 1) {
  // NOTE: do not use viewing.community, it's too slow
  const { curCommunity } = store
  const { subPath: topic } = store.curRoute
  // const { curCommunity: community, curThread } = store

  const userHasLogin = store.isLogin

  store.markState({ curView: TYPE.LOADING })

  const args = {
    filter: {
      page,
      size: PAGE_SIZE.D,
      ...store.filtersData,
      tag: store.activeTagData.title,
      community: curCommunity.raw,
    },
    userHasLogin,
  }

  if (curCommunity.raw === ROUTE.HOME) {
    args.filter = R.merge(args.filter, { topic })
  }

  args.filter = validFilter(args.filter)
  scrollIntoEle(TYPE.APP_HEADER_ID)

  sr71$.query(S.pagedPosts, args)
  store.markRoute({ page })
}

export const onFilterSelect = option => store.selectFilter(option)

export function onTagSelect(tag) {
  store.selectTag(tag)
  loadPosts()
  store.markRoute({ tag: tag.title })
}

export const onUserSelect = user =>
  dispatchEvent(EVENT.PREVIEW_OPEN, {
    type: TYPE.PREVIEW_USER_VIEW,
    data: user,
  })

export function onTitleSelect(data) {
  // debug('onTitleSelect publish post: ', data)
  setTimeout(() => store.setViewedFlag(data.id), 1500)

  dispatchEvent(EVENT.PREVIEW_OPEN, {
    type: TYPE.PREVIEW_POST_VIEW,
    thread: THREAD.POST,
    data,
  })

  store.markRoute({ preview: THREAD.POST, id: data.id })
  /*
  GA.event({
    action: data.title,
    category: '浏览',
    label: '社区',
  })
  */
}

export const createContent = () => {
  if (!store.isLogin) return store.authWarning()

  dispatchEvent(EVENT.PREVIEW_OPEN, { type: TYPE.PREVIEW_POST_CREATE })
}

export const onCustomChange = option => {
  dispatchEvent(EVENT.SET_C11N, { data: option })
  store.updateC11N(option)
}

// ###############################
// Data & Error handlers
// ###############################
const DataSolver = [
  {
    match: asyncRes('pagedPosts'),
    action: ({ pagedPosts }) => {
      debug('pagedPosts: ', pagedPosts)
      let curView = TYPE.RESULT
      if (pagedPosts.totalCount === 0) {
        curView = TYPE.RESULT_EMPTY
      }
      store.markState({ curView, pagedPosts })
    },
  },
  {
    match: asyncRes('partialTags'),
    action: ({ partialTags: tags }) => store.markState({ tags }),
  },
  {
    match: asyncRes(EVENT.COMMUNITY_CHANGE),
    action: () => {
      debug('======= fucking COMMUNITY_CHANGE ')
      loadPosts()
    },
  },
  {
    match: asyncRes(EVENT.TABBER_CHANGE),
    action: () => loadPosts(),
  },
  {
    match: asyncRes(EVENT.REFRESH_POSTS),
    action: () => loadPosts(),
  },
  {
    match: asyncRes(EVENT.PREVIEW_CLOSED),
    action: () => {
      store.setViewing({ post: {} })
      store.markRoute({})
    },
  },
]

const ErrSolver = [
  {
    match: asyncErr(ERR.CRAPHQL),
    action: ({ details }) => {
      debug('ERR.CRAPHQL -->', details)
    },
  },
  {
    match: asyncErr(ERR.TIMEOUT),
    action: ({ details }) => {
      debug('ERR.TIMEOUT -->', details)
    },
  },
  {
    match: asyncErr(ERR.NETWORK),
    action: ({ details }) => {
      debug('ERR.NETWORK -->', details)
    },
  },
]

export function init(_store) {
  debug('======== init')
  store = _store
  // if (sub$) sub$.unsubscribe()
  sub$ = sr71$.data().subscribe($solver(DataSolver, ErrSolver))
}

export function uninit() {
  debug('======== un init')
  if (sub$) sub$.unsubscribe()
}
<commit_msg>chore(debug): ajax dead<commit_after>import R from 'ramda'
import { PAGE_SIZE } from '../../config'

import {
  asyncRes,
  asyncErr,
  makeDebugger,
  dispatchEvent,
  EVENT,
  ERR,
  TYPE,
  ROUTE,
  THREAD,
  $solver,
  scrollIntoEle,
  // GA,
} from '../../utils'

import S from './schema'
import SR71 from '../../utils/network/sr71'

const sr71$ = new SR71({
  resv_event: [
    EVENT.REFRESH_POSTS,
    EVENT.PREVIEW_CLOSED,
    EVENT.COMMUNITY_CHANGE,
    EVENT.TABBER_CHANGE,
  ],
})
/* eslint-disable no-unused-vars */
const debug = makeDebugger('L:PostsThread')
/* eslint-enable no-unused-vars */

let store = null
let sub$ = null

// TODO: move to utils
const validFilter = R.pickBy(R.compose(R.not, R.isEmpty))

export const inAnchor = () => store.setHeaderFix(false)
export const outAnchor = () => store.setHeaderFix(true)

export function loadPosts(page = 1) {
  // NOTE: do not use viewing.community, it's too slow
  const { curCommunity } = store
  const { subPath: topic } = store.curRoute
  // const { curCommunity: community, curThread } = store

  const userHasLogin = store.isLogin

  store.markState({ curView: TYPE.LOADING })

  const args = {
    filter: {
      page,
      size: PAGE_SIZE.D,
      ...store.filtersData,
      tag: store.activeTagData.title,
      community: curCommunity.raw,
    },
    userHasLogin,
  }

  if (curCommunity.raw === ROUTE.HOME) {
    args.filter = R.merge(args.filter, { topic })
  }

  args.filter = validFilter(args.filter)
  scrollIntoEle(TYPE.APP_HEADER_ID)

  sr71$.query(S.pagedPosts, args)
  store.markRoute({ page })
}

export const onFilterSelect = option => store.selectFilter(option)

export function onTagSelect(tag) {
  store.selectTag(tag)
  loadPosts()
  store.markRoute({ tag: tag.title })
}

export const onUserSelect = user =>
  dispatchEvent(EVENT.PREVIEW_OPEN, {
    type: TYPE.PREVIEW_USER_VIEW,
    data: user,
  })

export function onTitleSelect(data) {
  // debug('onTitleSelect publish post: ', data)
  setTimeout(() => store.setViewedFlag(data.id), 1500)

  dispatchEvent(EVENT.PREVIEW_OPEN, {
    type: TYPE.PREVIEW_POST_VIEW,
    thread: THREAD.POST,
    data,
  })

  store.markRoute({ preview: THREAD.POST, id: data.id })
  /*
  GA.event({
    action: data.title,
    category: '浏览',
    label: '社区',
  })
  */
}

export const createContent = () => {
  if (!store.isLogin) return store.authWarning()

  dispatchEvent(EVENT.PREVIEW_OPEN, { type: TYPE.PREVIEW_POST_CREATE })
}

export const onCustomChange = option => {
  dispatchEvent(EVENT.SET_C11N, { data: option })
  store.updateC11N(option)
}

// ###############################
// Data & Error handlers
// ###############################
const DataSolver = [
  {
    match: asyncRes('pagedPosts'),
    action: ({ pagedPosts }) => {
      debug('pagedPosts: ', pagedPosts)
      let curView = TYPE.RESULT
      if (pagedPosts.totalCount === 0) {
        curView = TYPE.RESULT_EMPTY
      }
      store.markState({ curView, pagedPosts })
    },
  },
  {
    match: asyncRes('partialTags'),
    action: ({ partialTags: tags }) => store.markState({ tags }),
  },
  {
    match: asyncRes(EVENT.COMMUNITY_CHANGE),
    action: () => {
      debug('======= fucking COMMUNITY_CHANGE ')
      loadPosts()
    },
  },
  {
    match: asyncRes(EVENT.TABBER_CHANGE),
    action: () => loadPosts(),
  },
  {
    match: asyncRes(EVENT.REFRESH_POSTS),
    action: () => loadPosts(),
  },
  {
    match: asyncRes(EVENT.PREVIEW_CLOSED),
    action: () => {
      store.setViewing({ post: {} })
      store.markRoute({})
    },
  },
]

const ErrSolver = [
  {
    match: asyncErr(ERR.CRAPHQL),
    action: ({ details }) => {
      debug('ERR.CRAPHQL -->', details)
    },
  },
  {
    match: asyncErr(ERR.TIMEOUT),
    action: ({ details }) => {
      debug('ERR.TIMEOUT -->', details)
    },
  },
  {
    match: asyncErr(ERR.NETWORK),
    action: ({ details }) => {
      debug('ERR.NETWORK -->', details)
    },
  },
]

export function init(_store) {
  debug('======== init')
  store = _store
  if (sub$) sub$.unsubscribe()
  sub$ = sr71$.data().subscribe($solver(DataSolver, ErrSolver))
}

export function uninit() {
  debug('======== un init')
  if (sub$) sub$.unsubscribe()
}
<|endoftext|>


<commit_before>/**
 * @file Check entity definition
 * @since 0.1.6
 */
/*#ifndef(UMD)*/
"use strict";
/*global _GpfEntityDefinition*/ // Entity definition
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*global _gpfFunc*/ // Create a new function using the source
/*global _gpfIgnore*/ // Helper to remove unused parameter warning
/*global _gpfObjectForEach*/ // Similar to [].forEach but for objects
/*global _gpfCreateAbstractFunction*/ // Build a function that throws the abstractMethod exception
/*#endif*/

_gpfErrorDeclare("define/check", {
    /**
     * ### Summary
     *
     * One of the $ properties is invalid in the definition passed to {@link gpf.define}
     *
     * ### Description
     *
     * The list of possible $ properties is fixed and depends on the entity type.
     * This error is thrown when one $ property is not allowed.
     * @since 0.1.6
     */
    invalidEntity$Property: "Invalid entity $ property",

    /**
     * ### Summary
     *
     * Entity name is missing in the definition passed to {@link gpf.define}
     *
     * ### Description
     *
     * This error is thrown when the entity name is missing
     * @since 0.1.6
     */
    missingEntityName: "Missing entity name",

    /**
     * ### Summary
     *
     * Entity namespace is invalid in the definition passed to {@link gpf.define}
     *
     * ### Description
     *
     * This error is thrown when the namespace is invalid
     * @since 0.1.6
     */
    invalidEntityNamespace: "Invalid entity namespace"

});

function _gpfDefineEntityCheckNameIsNotEmpty () {
    /*jshint validthis:true*/ // constructor
    /*eslint-disable no-invalid-this*/
    if (!this._name) {
        gpf.Error.missingEntityName();
    }
    /*eslint-enable no-invalid-this*/
}

function _gpfDefineEntityCheckProperty (value, name) {
    _gpfIgnore(value);
    /*jshint -W040*/ /*eslint-disable no-invalid-this*/ // bound through thisArg
    if (name.charAt(0) === "$") {
        this._check$Property(name.substr(1), value);
    } else {
        this._checkProperty(name, value);
    }
    /*jshint -W040*/ /*eslint-enable no-invalid-this*/
}

Object.assign(_GpfEntityDefinition.prototype, /** @lends _GpfEntityDefinition.prototype */ {

    /**
     * Entity type (class...)
     *
     * @readonly
     * @since 0.1.6
     */
    _type: "",

    /**
     * List of allowed $ properties
     *
     * @type {String[]}
     * @readonly
     * @since 0.1.6
     */
    _allowed$Properties: "type,name,namespace".split(","),

    /**
     * Check if the $ property is allowed by comparing in _allowed$Properties
     *
     * @param {String} name $ Property name (without the starting $)
     * @see _GpfEntityDefinition.prototype._allowed$Properties
     * @throws {gpf.Error.InvalidEntity$Property}
     */
    _check$PropertyInAllowed$Properties: function (name) {
        if (-1 === this._allowed$Properties.indexOf(name)) {
            gpf.Error.invalidEntity$Property();
        }
    },

    /**
     * Check if the $ property is allowed
     *
     * @param {String} name $ Property name (without the starting $)
     * @param {*} value $ Property value
     * @since 0.1.6
     */
    _check$Property: function (name, value) {
        _gpfIgnore(value);
        if (name !== this._type) {
            this._check$PropertyInAllowed$Properties(name);
        }
    },

    /**
     * Throw the invalid property error
     *
     * @abstract
     * @protected
     */
    _throwInvalidProperty: _gpfCreateAbstractFunction(0),

    /**
     * Regular expression used to validate member name
     *
     * @type {RegExp}
     * @readonly
     * @protected
     */
    _reMemberName: new RegExp(".*"),

    /**
     * Check that the member name is a valid one
     *
     * @param {String} name Member name
     */
    _checkMemberName: function (name) {
        if (!this._reMemberName.exec(name)) {
            this._throwInvalidProperty();
        }
    },

    /**
     * List of reserved member names
     *
     * @type {String[]}
     * @readonly
     * @constant
     */
    _reservedNames: "super,class,public,private,protected,static,mixin".split(","),

    /**
     * Check that the member name is not a reserved one
     *
     * @param {String} name Member name
     * @since 0.1.6
     */
    _checkReservedMemberName: function (name) {
        if (-1 !== this._reservedNames.indexOf(name)) {
            this._throwInvalidProperty();
        }
    },

    /**
     * Check the value of the member
     *
     * @param {String} name Property name
     * @param {*} value Property value
     * @protected
     */
    _checkMemberValue: _gpfFunc(["name", "value"], " "),

    /**
     * Check if the property is allowed
     * NOTE: $ properties are handled by {@link _check$Property}
     *
     * @param {String} name Property name
     * @param {*} value Property value
     * @since 0.1.6
     */
    _checkProperty: function (name, value) {
        this._checkMemberName(name);
        this._checkReservedMemberName(name);
        this._checkMemberValue(name, value);
    },

    /**
     * Check the properties contained in the definition passed to {@link gpf.define}
     * @since 0.1.6
     */
    _checkProperties: function () {
        _gpfObjectForEach(this._initialDefinition, _gpfDefineEntityCheckProperty, this);
    },

    /**
     * Entity name
     * @since 0.1.6
     */
    _name: "",

    /**
     * Compute name property
     * @since 0.1.6
     */
    _readName: function () {
        var definition = this._initialDefinition;
        this._name = definition["$" + this._type] || definition.$name;
    },

    /**
     * Check if name property is not empty (throw the error otherwise)
     *
     * @throws {gpf.Error.MissingEntityName}
     * @since 0.1.6
     */
    _checkNameIsNotEmpty: _gpfDefineEntityCheckNameIsNotEmpty,

    /**
     * Check name property (content)
     *
     * @throws {gpf.Error.MissingEntityName}
     * @since 0.1.6
     */
    _checkName: _gpfDefineEntityCheckNameIsNotEmpty,

    /**
     * Entity namespace
     * @since 0.1.6
     */
    _namespace: "",

    /**
     * If the name is prefixed with a namespace, isolate it and update name property
     *
     * @return {String|undefined} Namespace contained in the name or undefined if none
     * @since 0.1.6
     */
    _extractRelativeNamespaceFromName: function () {
        var parts = new RegExp("(.*)\\.([^\\.]+)$").exec(this._name);
        if (parts) {
            this._name = parts[2];
            return parts[1];
        }
    },

    /**
     * Compute namespace property
     * @since 0.1.6
     */
    _readNamespace: function () {
        var namespaces = [
            this._initialDefinition.$namespace,
            this._extractRelativeNamespaceFromName()
        ].filter(function (namespacePart) {
            return namespacePart;
        });
        if (namespaces.length > 0) {
            this._namespace = namespaces.join(".");
        }
    },

    /**
     * Check namespace property
     *
     * @throws {gpf.Error.InvalidEntityNamespace}
     * @since 0.1.6
     */
    _checkNamespace: function () {
        if (!new RegExp("^(:?[a-z_$][a-zA-Z0-9]+(:?\\.[a-z_$][a-zA-Z0-9]+)*)?$").exec(this._namespace)) {
            gpf.Error.invalidEntityNamespace();
        }
    },

    check: function () {
        this._checkProperties();
        this._readName();
        this._checkNameIsNotEmpty();
        this._readNamespace();
        this._checkName();
        this._checkNamespace();
    }

});
<commit_msg>Allows inlining<commit_after>/**
 * @file Check entity definition
 * @since 0.1.6
 */
/*#ifndef(UMD)*/
"use strict";
/*global _GpfEntityDefinition*/ // Entity definition
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*global _gpfFunc*/ // Create a new function using the source
/*global _gpfIgnore*/ // Helper to remove unused parameter warning
/*global _gpfObjectForEach*/ // Similar to [].forEach but for objects
/*global _gpfCreateAbstractFunction*/ // Build a function that throws the abstractMethod exception
/*#endif*/

_gpfErrorDeclare("define/check", {
    /**
     * ### Summary
     *
     * One of the $ properties is invalid in the definition passed to {@link gpf.define}
     *
     * ### Description
     *
     * The list of possible $ properties is fixed and depends on the entity type.
     * This error is thrown when one $ property is not allowed.
     * @since 0.1.6
     */
    invalidEntity$Property: "Invalid entity $ property",

    /**
     * ### Summary
     *
     * Entity name is missing in the definition passed to {@link gpf.define}
     *
     * ### Description
     *
     * This error is thrown when the entity name is missing
     * @since 0.1.6
     */
    missingEntityName: "Missing entity name",

    /**
     * ### Summary
     *
     * Entity namespace is invalid in the definition passed to {@link gpf.define}
     *
     * ### Description
     *
     * This error is thrown when the namespace is invalid
     * @since 0.1.6
     */
    invalidEntityNamespace: "Invalid entity namespace"

});

function _gpfDefineEntityCheck$PropertyInAllowed$Properties (name, allowedList) {
    if (-1 === allowedList.indexOf(name)) {
        gpf.Error.invalidEntity$Property();
    }
}

function _gpfDefineEntityCheckNameIsNotEmpty () {
    /*jshint validthis:true*/ // constructor
    /*eslint-disable no-invalid-this*/
    if (!this._name) {
        gpf.Error.missingEntityName();
    }
    /*eslint-enable no-invalid-this*/
}

function _gpfDefineEntityCheckProperty (value, name) {
    _gpfIgnore(value);
    /*jshint -W040*/ /*eslint-disable no-invalid-this*/ // bound through thisArg
    if (name.charAt(0) === "$") {
        this._check$Property(name.substr(1), value);
    } else {
        this._checkProperty(name, value);
    }
    /*jshint -W040*/ /*eslint-enable no-invalid-this*/
}

Object.assign(_GpfEntityDefinition.prototype, /** @lends _GpfEntityDefinition.prototype */ {

    /**
     * Entity type (class...)
     *
     * @readonly
     * @since 0.1.6
     */
    _type: "",

    /**
     * List of allowed $ properties
     *
     * @type {String[]}
     * @readonly
     * @since 0.1.6
     */
    _allowed$Properties: "type,name,namespace".split(","),

    /**
     * Check if the $ property is allowed
     *
     * @param {String} name $ Property name (without the starting $)
     * @param {*} value $ Property value
     * @since 0.1.6
     */
    _check$Property: function (name, value) {
        _gpfIgnore(value);
        if (name !== this._type) {
            _gpfDefineEntityCheck$PropertyInAllowed$Properties(name, this._allowed$Properties);
        }
    },

    /**
     * Throw the invalid property error
     *
     * @abstract
     * @protected
     */
    _throwInvalidProperty: _gpfCreateAbstractFunction(0),

    /**
     * Regular expression used to validate member name
     *
     * @type {RegExp}
     * @readonly
     * @protected
     */
    _reMemberName: new RegExp(".*"),

    /**
     * Check that the member name is a valid one
     *
     * @param {String} name Member name
     */
    _checkMemberName: function (name) {
        if (!this._reMemberName.exec(name)) {
            this._throwInvalidProperty();
        }
    },

    /**
     * List of reserved member names
     *
     * @type {String[]}
     * @readonly
     * @constant
     */
    _reservedNames: "super,class,public,private,protected,static,mixin".split(","),

    /**
     * Check that the member name is not a reserved one
     *
     * @param {String} name Member name
     * @since 0.1.6
     */
    _checkReservedMemberName: function (name) {
        if (-1 !== this._reservedNames.indexOf(name)) {
            this._throwInvalidProperty();
        }
    },

    /**
     * Check the value of the member
     *
     * @param {String} name Property name
     * @param {*} value Property value
     * @protected
     */
    _checkMemberValue: _gpfFunc(["name", "value"], " "),

    /**
     * Check if the property is allowed
     * NOTE: $ properties are handled by {@link _check$Property}
     *
     * @param {String} name Property name
     * @param {*} value Property value
     * @since 0.1.6
     */
    _checkProperty: function (name, value) {
        this._checkMemberName(name);
        this._checkReservedMemberName(name);
        this._checkMemberValue(name, value);
    },

    /**
     * Check the properties contained in the definition passed to {@link gpf.define}
     * @since 0.1.6
     */
    _checkProperties: function () {
        _gpfObjectForEach(this._initialDefinition, _gpfDefineEntityCheckProperty, this);
    },

    /**
     * Entity name
     * @since 0.1.6
     */
    _name: "",

    /**
     * Compute name property
     * @since 0.1.6
     */
    _readName: function () {
        var definition = this._initialDefinition;
        this._name = definition["$" + this._type] || definition.$name;
    },

    /**
     * Check if name property is not empty (throw the error otherwise)
     *
     * @throws {gpf.Error.MissingEntityName}
     * @since 0.1.6
     */
    _checkNameIsNotEmpty: _gpfDefineEntityCheckNameIsNotEmpty,

    /**
     * Check name property (content)
     *
     * @throws {gpf.Error.MissingEntityName}
     * @since 0.1.6
     */
    _checkName: _gpfDefineEntityCheckNameIsNotEmpty,

    /**
     * Entity namespace
     * @since 0.1.6
     */
    _namespace: "",

    /**
     * If the name is prefixed with a namespace, isolate it and update name property
     *
     * @return {String|undefined} Namespace contained in the name or undefined if none
     * @since 0.1.6
     */
    _extractRelativeNamespaceFromName: function () {
        var parts = new RegExp("(.*)\\.([^\\.]+)$").exec(this._name);
        if (parts) {
            this._name = parts[2];
            return parts[1];
        }
    },

    /**
     * Compute namespace property
     * @since 0.1.6
     */
    _readNamespace: function () {
        var namespaces = [
            this._initialDefinition.$namespace,
            this._extractRelativeNamespaceFromName()
        ].filter(function (namespacePart) {
            return namespacePart;
        });
        if (namespaces.length > 0) {
            this._namespace = namespaces.join(".");
        }
    },

    /**
     * Check namespace property
     *
     * @throws {gpf.Error.InvalidEntityNamespace}
     * @since 0.1.6
     */
    _checkNamespace: function () {
        if (!new RegExp("^(:?[a-z_$][a-zA-Z0-9]+(:?\\.[a-z_$][a-zA-Z0-9]+)*)?$").exec(this._namespace)) {
            gpf.Error.invalidEntityNamespace();
        }
    },

    check: function () {
        this._checkProperties();
        this._readName();
        this._checkNameIsNotEmpty();
        this._readNamespace();
        this._checkName();
        this._checkNamespace();
    }

});
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import fetch from '../util/fetch';
import getPlaceholderImageURL from '../util/getPlaceholderImageURL';
import { Link } from 'react-router-dom';

class FeaturedItems extends React.Component {
	componentDidMount() {
		fetch('GET', '/featured').then(response => {
			// first, go through and update each item
			for (let item of response.data) {
				if (item.type === 'rss') {
					this.props.dispatch({
						rssFeed: item,
						type: 'UPDATE_RSS_FEED',
					});
				} else if (item.type === 'podcast') {
					this.props.dispatch({
						podcast: item,
						type: 'UPDATE_PODCAST_SHOW',
					});
				}
			}

			let featuredItemIDs = response.data.map(item => {
				return `${item.type}:${item._id}`;
			});
			// then, update the list of featured items
			this.props.dispatch({
				featuredItemIDs,
				type: 'UPDATE_FEATURED_ITEMS',
			});
		});
	}
	render() {
		return (

Featured on Winds

					{this.props.featuredItems.map(featuredItem => {
						let linkURL = '#';
						if (featuredItem.type === 'rss') {
							linkURL = `/rss/${featuredItem._id}`;
						} else if (featuredItem.type === 'podcast') {
							linkURL = `/podcasts/${featuredItem._id}`;
						}
						return (
							<Link
								className="featured-item"
								key={featuredItem._id}
								style={{
									backgroundImage: `linear-gradient(to top, black, transparent), url(${featuredItem
										.images.featured ||
										featuredItem.images.favicon ||
										getPlaceholderImageURL(featuredItem._id)})`,
								}}
								to={linkURL}
							>

{featuredItem.title}

								{featuredItem.type}
							</Link>
						);
					})}

		);
	}
}

FeaturedItems.defaultProps = {
	featuredItems: [],
};

FeaturedItems.propTypes = {
	dispatch: PropTypes.func.isRequired,
	featuredItems: PropTypes.array,
};

const mapStateToProps = (state, ownProps) => {
	let deserializedFeaturedItems = [];
	if (state.featuredItems) {
		for (let featuredItemID of state.featuredItems) {
			if (featuredItemID.split(':')[0] === 'rss') {
				deserializedFeaturedItems.push({
					...state.rssFeeds[featuredItemID.split(':')[1]],
					type: 'rss',
				});
			} else if (featuredItemID.split(':')[0] === 'podcast') {
				deserializedFeaturedItems.push({
					...state.podcasts[featuredItemID.split(':')[1]],
					type: 'podcast',
				});
			}
		}
	}
	return { ...ownProps, featuredItems: deserializedFeaturedItems };
};

const mapDispatchToProps = (dispatch, ownProps) => {
	return {
		...ownProps,
		dispatch,
	};
};

const mergeProps = (stateProps, dispatchProps, ownProps) => {
	return {
		...ownProps,
		...dispatchProps,
		...stateProps,
	};
};

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(FeaturedItems);
<commit_msg>not using favicons on featured items<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import fetch from '../util/fetch';
import getPlaceholderImageURL from '../util/getPlaceholderImageURL';
import { Link } from 'react-router-dom';

class FeaturedItems extends React.Component {
	componentDidMount() {
		fetch('GET', '/featured').then(response => {
			// first, go through and update each item
			for (let item of response.data) {
				if (item.type === 'rss') {
					this.props.dispatch({
						rssFeed: item,
						type: 'UPDATE_RSS_FEED',
					});
				} else if (item.type === 'podcast') {
					this.props.dispatch({
						podcast: item,
						type: 'UPDATE_PODCAST_SHOW',
					});
				}
			}

			let featuredItemIDs = response.data.map(item => {
				return `${item.type}:${item._id}`;
			});
			// then, update the list of featured items
			this.props.dispatch({
				featuredItemIDs,
				type: 'UPDATE_FEATURED_ITEMS',
			});
		});
	}
	render() {
		return (

Featured on Winds

					{this.props.featuredItems.map(featuredItem => {
						let linkURL = '#';
						if (featuredItem.type === 'rss') {
							linkURL = `/rss/${featuredItem._id}`;
						} else if (featuredItem.type === 'podcast') {
							linkURL = `/podcasts/${featuredItem._id}`;
						}
						return (
							<Link
								className="featured-item"
								key={featuredItem._id}
								style={{
									backgroundImage: `linear-gradient(to top, black, transparent), url(${featuredItem
										.images.featured ||
										getPlaceholderImageURL(featuredItem._id)})`,
								}}
								to={linkURL}
							>

{featuredItem.title}

								{featuredItem.type}
							</Link>
						);
					})}

		);
	}
}

FeaturedItems.defaultProps = {
	featuredItems: [],
};

FeaturedItems.propTypes = {
	dispatch: PropTypes.func.isRequired,
	featuredItems: PropTypes.array,
};

const mapStateToProps = (state, ownProps) => {
	let deserializedFeaturedItems = [];
	if (state.featuredItems) {
		for (let featuredItemID of state.featuredItems) {
			if (featuredItemID.split(':')[0] === 'rss') {
				deserializedFeaturedItems.push({
					...state.rssFeeds[featuredItemID.split(':')[1]],
					type: 'rss',
				});
			} else if (featuredItemID.split(':')[0] === 'podcast') {
				deserializedFeaturedItems.push({
					...state.podcasts[featuredItemID.split(':')[1]],
					type: 'podcast',
				});
			}
		}
	}
	return { ...ownProps, featuredItems: deserializedFeaturedItems };
};

const mapDispatchToProps = (dispatch, ownProps) => {
	return {
		...ownProps,
		dispatch,
	};
};

const mergeProps = (stateProps, dispatchProps, ownProps) => {
	return {
		...ownProps,
		...dispatchProps,
		...stateProps,
	};
};

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(FeaturedItems);
<|endoftext|>