<commit_before>(function () {
    'use strict';

    angular
        .module('app.core')
        .factory('itemService', itemService);

    itemService.$inject = ['logger', 'restService', '$rootScope', 'eventService', 'modelService'];
    /* @ngInject */
    function itemService(logger, restService, $rootScope, eventService, modelService) {
        var service = {
            items: [],
            itemMap: {},
            itemsFetched: false,
            selected: [],
            createItem: createItem,
            deleteItem: deleteItem,
            saveItem: saveItem,
            getItem: getItem,
            getChildren: getChildren,
            getIdAbleHierarchy: getIdAbleHierarchy
        };

        activate();

        return service;

        function activate() {
            listenToItemEvents();
            if(modelService.activeModel !== null) {
                getAllItems(modelService.activeModel.id);
            }
            $rootScope.$on('modelChanged', function(event, model) {
                if( model != null) {
                    getAllItems(model.id);
                } else {
                    service.items = [];
                    service.itemMap = {};
                    service.itemsFetched = false;
                    service.selected = [];
                }
            });
        }

        function getAllItems(modelID) {
            service.items.splice(0, service.items.length);
            service.itemMap = {};
            return restService.getItems(modelID).then(function(data) {
                service.items.push.apply(service.items, data);
                _.forEach(service.items, function(i){service.itemMap[i.id] = i});
                logger.info('Item Service: Loaded ' + service.items.length + ' items through REST.');
                service.itemsFetched = true;
                $rootScope.$broadcast('itemsFetch', service.items);
            });
        }

        function getItem(id) {
            return _.isUndefined(service.itemMap[id]) ? null : service.itemMap[id];
        }

        function createItem(name, isa) {
            var newItem = {
                name: name,
                isa: isa
            };
            if (modelService.activeModel === null) {
                logger.error('Item Service: Failed to create item, no active model set.');
            } else {
                restService.postItems(newItem, modelService.activeModel.id);
            }
        }

        function saveItem(item) {
            if (modelService.activeModel === null) {
                var msg = 'Item Service: Failed to save item, no active model set.';
                logger.error(msg);
                return $q.reject(msg);
            } else {
                return restService.postItem(item, modelService.activeModel.id);
            }
        }

        function deleteItem(itemID) {
            if (modelService.activeModel === null) {
                logger.error('Item Service: Failed to request item deletion, no active model set.')
            }
            restService.deleteItem(modelService.activeModel.id, itemID);
        }

        function getChildren(node){
            if (_.isUndefined(node) || _.isUndefined(node.children)) return [];
            return _.map(node.children, function(c){
                return service.getItem(c.item)
            });
        }

        function getIdAbleHierarchy(root){
            if (_.isUndefined(root)) return null;
            var rootItem = _.isUndefined(root.item) ? getItem(root.id) : getItem(root.item);
            if (!_.isObject(rootItem)) return null;
            var rootCopy = angular.copy(rootItem);
            rootCopy.children = _.map(root.children, function(c){
                return getIdAbleHierarchy(c);
            });
            return rootCopy;
        }

        function listenToItemEvents() {
            eventService.addListener('ModelDiff', onItemEvent);

            function onItemEvent(data) {
                logger.info('Item Service: Handler received an event.');
                    for (var i = 0; i < data.updatedItems.length; i++) {
                        var remoteItem = data.updatedItems[i];
                        var existingItem = getItem(remoteItem.id);
                        if (existingItem === null) { // item not found => create
                            service.items.push(remoteItem);
                            service.itemMap[remoteItem.id] = remoteItem;
                            $rootScope.$broadcast('itemCreation', remoteItem);
                            logger.info('Item Service: Added an item with name ' + remoteItem.name + '.');
                        } else { // item found => update
                            var oldName = existingItem.name;
                            angular.extend(existingItem, remoteItem);
                            $rootScope.$broadcast('itemUpdate', existingItem);
                            logger.info('Item Service: Updated item ' + oldName + '.');
                        }
                    }
                    for (var j = 0; j < data.deletedItems.length; j++) {
                        var remoteItem = data.deletedItems[j];
                        var localItem = getItem(remoteItem.id);
                        if (localItem === null) {
                            logger.error('Item Service: Could not find an item with id ' + localItem.id + ' to delete.');
                        } else {
                            _.remove(service.items, localItem);
                            delete service.itemMap[localItem.id];
                            $rootScope.$broadcast('itemDeletion', remoteItem);
                            logger.info('Item Service: Removed item ' + localItem.name + '.');
                        }
                    }

            }
        }

    }
})();
<commit_msg>Fixing a bug so only the correct model is updated when modelDiff events arrives. The bug happened when having multiple open in different tabs<commit_after>(function () {
    'use strict';

    angular
        .module('app.core')
        .factory('itemService', itemService);

    itemService.$inject = ['logger', 'restService', '$rootScope', 'eventService', 'modelService'];
    /* @ngInject */
    function itemService(logger, restService, $rootScope, eventService, modelService) {
        var service = {
            items: [],
            itemMap: {},
            itemsFetched: false,
            selected: [],
            createItem: createItem,
            deleteItem: deleteItem,
            saveItem: saveItem,
            getItem: getItem,
            getChildren: getChildren,
            getIdAbleHierarchy: getIdAbleHierarchy
        };

        activate();

        return service;

        function activate() {
            listenToItemEvents();
            if(modelService.activeModel !== null) {
                getAllItems(modelService.activeModel.id);
            }
            $rootScope.$on('modelChanged', function(event, model) {
                if( model != null) {
                    getAllItems(model.id);
                } else {
                    service.items = [];
                    service.itemMap = {};
                    service.itemsFetched = false;
                    service.selected = [];
                }
            });
        }

        function getAllItems(modelID) {
            service.items.splice(0, service.items.length);
            service.itemMap = {};
            return restService.getItems(modelID).then(function(data) {
                service.items.push.apply(service.items, data);
                _.forEach(service.items, function(i){service.itemMap[i.id] = i});
                logger.info('Item Service: Loaded ' + service.items.length + ' items through REST.');
                service.itemsFetched = true;
                $rootScope.$broadcast('itemsFetch', service.items);
            });
        }

        function getItem(id) {
            return _.isUndefined(service.itemMap[id]) ? null : service.itemMap[id];
        }

        function createItem(name, isa) {
            var newItem = {
                name: name,
                isa: isa
            };
            if (modelService.activeModel === null) {
                logger.error('Item Service: Failed to create item, no active model set.');
            } else {
                restService.postItems(newItem, modelService.activeModel.id);
            }
        }

        function saveItem(item) {
            if (modelService.activeModel === null) {
                var msg = 'Item Service: Failed to save item, no active model set.';
                logger.error(msg);
                return $q.reject(msg);
            } else {
                return restService.postItem(item, modelService.activeModel.id);
            }
        }

        function deleteItem(itemID) {
            if (modelService.activeModel === null) {
                logger.error('Item Service: Failed to request item deletion, no active model set.')
            }
            restService.deleteItem(modelService.activeModel.id, itemID);
        }

        function getChildren(node){
            if (_.isUndefined(node) || _.isUndefined(node.children)) return [];
            return _.map(node.children, function(c){
                return service.getItem(c.item)
            });
        }

        function getIdAbleHierarchy(root){
            if (_.isUndefined(root)) return null;
            var rootItem = _.isUndefined(root.item) ? getItem(root.id) : getItem(root.item);
            if (!_.isObject(rootItem)) return null;
            var rootCopy = angular.copy(rootItem);
            rootCopy.children = _.map(root.children, function(c){
                return getIdAbleHierarchy(c);
            });
            return rootCopy;
        }

        function listenToItemEvents() {
            eventService.addListener('ModelDiff', onItemEvent);

            function onItemEvent(data) {
                logger.info('Item Service: Handler received an event.');

                if (data.model == modelService.activeModel.id) {
                    for (var i = 0; i < data.updatedItems.length; i++) {
                        var remoteItem = data.updatedItems[i];
                        var existingItem = getItem(remoteItem.id);
                        if (existingItem === null) { // item not found => create
                            service.items.push(remoteItem);
                            service.itemMap[remoteItem.id] = remoteItem;
                            $rootScope.$broadcast('itemCreation', remoteItem);
                            logger.info('Item Service: Added an item with name ' + remoteItem.name + '.');
                        } else { // item found => update
                            var oldName = existingItem.name;
                            angular.extend(existingItem, remoteItem);
                            $rootScope.$broadcast('itemUpdate', existingItem);
                            logger.info('Item Service: Updated item ' + oldName + '.');
                        }
                    }
                    for (var j = 0; j < data.deletedItems.length; j++) {
                        var remoteItem = data.deletedItems[j];
                        var localItem = getItem(remoteItem.id);
                        if (localItem === null) {
                            logger.error('Item Service: Could not find an item with id ' + localItem.id + ' to delete.');
                        } else {
                            _.remove(service.items, localItem);
                            delete service.itemMap[localItem.id];
                            $rootScope.$broadcast('itemDeletion', remoteItem);
                            logger.info('Item Service: Removed item ' + localItem.name + '.');
                        }
                    }
                }
            }
        }

    }
})();
<|endoftext|>


<commit_before>var uuid = require('node-uuid');
var moment = require('moment');
var config = require('./../config');

var devices = require('./database').devices;

module.exports = function(params, callback) {

  function pad(width, string, padding) {
    return (width <= string.length) ? string : pad(width, padding + string, padding)
  }

  var rand = function() {
      return Math.random().toString(36).substr(2); // remove `0.`
  };

  var generateToken = function() {
      return pad(32, rand() + rand(), '0'); // to make it longer
  };

  var newUuid = uuid.v1();
  var newTimestamp = new Date().getTime();

  var updates = {};

  // Loop through parameters to update device
  for (var param in params) {
    var parsed;
    if(typeof params[param] === 'object'){
      try{
        parsed = JSON.parse(params[param]);
      } catch (e){
        parsed = params[param];
      }
    } else {
      parsed = params[param];
    }
    updates[param] = parsed;
  }

  var deviceChannel;
  if (params.channel){
    deviceChannel = params.channel;
  } else {
    deviceChannel = 'main';
  }

  var devicePresence;
  if(typeof params.online === 'string'){
    if (params.online == "true"){
      devicePresence = true;
    } else if(params.online == "false"){
      devicePresence = false;
    }
  } else if (typeof params.online === 'boolean'){
    devicePresence = params.online;
  } else {
    devicePresence = false;
  }

  var deviceIpAddress;
  var deviceGeo;
  if (params.ipAddress){
    deviceIpAddress = params.ipAddress;
    try {
      var geoip = require('geoip-lite');
      deviceGeo = geoip.lookup(params.ipAddress);
    } catch(geoip){
      deviceGeo = null;
    }
  } else {
    deviceIpAddress = "";
    deviceGeo = null;
  }

  var token;
  if (params.token){
    token = params.token;
  } else {
    token = generateToken();
  }

  var myUuid;
  if (params.uuid){
    devices.findOne({
      uuid: params.uuid
    }, function(err, devicedata) {
      if(err || !devicedata || devicedata.length < 1) {
        myUuid = params.uuid;
        writeUuid();
      } else {
        myUuid = uuid.v1();
        writeUuid();
      }
    });
  } else {
    myUuid = uuid.v1();
    writeUuid();
  }

  function writeUuid() {
    updates.uuid = myUuid;
    updates.timestamp = moment(newTimestamp).toISOString();
    updates.token = token;
    updates.channel = deviceChannel;
    updates.online = devicePresence;
    updates.ipAddress = deviceIpAddress;
    updates.geo = deviceGeo;
    updates.socketid = params.socketid;

    devices.insert(updates, function(err, saved) {

      if(err) {
        var regdata = {
          "error": {
            "message": "Device not registered",
            "code": 500
          }
        };
        callback(regdata);
      } else {
        updates._id.toString();
        delete updates._id;
        callback(updates);
      }
    });
  }

};
<commit_msg>Return an error now if UUID is already registered rather than auto generate a new uuid<commit_after>var uuid = require('node-uuid');
var moment = require('moment');
var config = require('./../config');

var devices = require('./database').devices;

module.exports = function(params, callback) {

  function pad(width, string, padding) {
    return (width <= string.length) ? string : pad(width, padding + string, padding)
  }

  var rand = function() {
      return Math.random().toString(36).substr(2); // remove `0.`
  };

  var generateToken = function() {
      return pad(32, rand() + rand(), '0'); // to make it longer
  };

  var newUuid = uuid.v1();
  var newTimestamp = new Date().getTime();

  var updates = {};

  // Loop through parameters to update device
  for (var param in params) {
    var parsed;
    if(typeof params[param] === 'object'){
      try{
        parsed = JSON.parse(params[param]);
      } catch (e){
        parsed = params[param];
      }
    } else {
      parsed = params[param];
    }
    updates[param] = parsed;
  }

  var deviceChannel;
  if (params.channel){
    deviceChannel = params.channel;
  } else {
    deviceChannel = 'main';
  }

  var devicePresence;
  if(typeof params.online === 'string'){
    if (params.online == "true"){
      devicePresence = true;
    } else if(params.online == "false"){
      devicePresence = false;
    }
  } else if (typeof params.online === 'boolean'){
    devicePresence = params.online;
  } else {
    devicePresence = false;
  }

  var deviceIpAddress;
  var deviceGeo;
  if (params.ipAddress){
    deviceIpAddress = params.ipAddress;
    try {
      var geoip = require('geoip-lite');
      deviceGeo = geoip.lookup(params.ipAddress);
    } catch(geoip){
      deviceGeo = null;
    }
  } else {
    deviceIpAddress = "";
    deviceGeo = null;
  }

  var token;
  if (params.token){
    token = params.token;
  } else {
    token = generateToken();
  }

  var myUuid;
  if (params.uuid){
    devices.findOne({
      uuid: params.uuid
    }, function(err, devicedata) {
      if(err || !devicedata || devicedata.length < 1) {
        myUuid = params.uuid;
        writeUuid();
      } else {
        // myUuid = uuid.v1();
        // writeUuid();

        // Return an error now if UUID is already registered rather than auto generate a new uuid
        var regdata = {
          "error": {
            "message": "Device UUID already registered",
            "code": 500
          }
        };
        callback(regdata);

      }
    });
  } else {
    myUuid = uuid.v1();
    writeUuid();
  }

  function writeUuid() {
    updates.uuid = myUuid;
    updates.timestamp = moment(newTimestamp).toISOString();
    updates.token = token;
    updates.channel = deviceChannel;
    updates.online = devicePresence;
    updates.ipAddress = deviceIpAddress;
    updates.geo = deviceGeo;
    updates.socketid = params.socketid;

    devices.insert(updates, function(err, saved) {

      if(err) {
        var regdata = {
          "error": {
            "message": "Device not registered",
            "code": 500
          }
        };
        callback(regdata);
      } else {
        updates._id.toString();
        delete updates._id;
        callback(updates);
      }
    });
  }

};
<|endoftext|>


<commit_before>! function (definition) {
  if (typeof window != "undefined") window.inquiry = definition();
  else if (typeof define == "function") define(definition);
  else module.exports = definition();
} (function () {
  function parse (rest, fixup, nesting, stop) {
    var expression = [], slash = '/', args, struct, source, i, $;
    rest = rest.trim()
    while (rest && rest[0] != stop) {
      if (rest[0] != '/') {
        if (/^[![{]/.test(rest[0])) {
          rest = '/.' + rest;
        } else {
          rest = slash + rest;
        }
      }
      slash = '';
      $ = /^\/((?:!(?![[{])|[^\]![{/`"]|"(?:[^\\"]|\\.)*")*)((!?)([[{]))?(.*)/.exec(rest);
      if (!$) throw new Error("bad pattern");
      //struct = [ /^['"]/.test($[1].trim()) ? $[1].trim().replace(/^(['"])(.*)\1$/g, "$2").replace(/\\(.)/g, "$1") : decodeURIComponent($[1].trim()) ]
      struct = [ /^"/.exec($[1].trim()) ? JSON.parse($[1].trim()) : decodeURIComponent($[1].trim()) ]
      rest = $[5];
      // Check for have a predicate or a sub-expression.
      switch ($[4]) {
      // We want to consume the contents of the curly braces that define a
      // predicate to construct a function body.
      case "{":
        // Depth is the number of curly braces we've encountered. We match curly
        // braces until it is time to pop.
        // **TODO**: Test against regular expressions. We are going to have to
        // document the one valid regular expression that we know of that we
        // cannot match: `/[/]/`.
        source = $[3] + '(';
        $ = /^(((?:[^'"}]*|'(?:[^\\']|\\.)*'|"(?:[^\\"]|\\.)*")*)})/.exec(rest);
        if (!$) throw new Error("bad pattern");
        source += $[2];
        rest = rest.substring($[1].length);
        args = ['_'];
        for (i = 0; i < nesting; i++) {
          args.push(Array(i + 2).join('$'), Array(i + 2).join('$') + 'i');
        }
        args.push.apply(args, fixup)
        $ = 0; // evil reuse of `$` to count airty. for the bytes, always for the bytes
        source.replace(/\$(\d+)/g, function (_, number) { $ = Math.max($, +number) });
        for (i = 0; i < $; i++) {
          args.push('$' + (i + 1));
        }
        args.push('return ' +  source + ')');
        struct.push((function (predicate) {
          return function (candidate, vargs) {
            return predicate.apply(this, [ candidate._, candidate.o, candidate.i ].concat(vargs));
          }
        })(Function.apply(Function, args)), []);
        break;
      // We want to consume the contents of brackets as a sub-expression, so we
      // call ourselves recursively.
      case "[":
        struct.push((function (negate, subquery) {
          return function (candidate, args) {
            var length = subquery.call(this, candidate, [ candidate.o, candidate.i ].concat(args)).length
            return negate ? ! length : length;
          }
        })($[3] == '!', ($ = parse(rest, fixup, nesting + 1, "]"))[0]));
        rest = $[1].slice(1);
        break;
      default:
        struct.push(null);
      }
      expression.push(struct);
      rest = rest.trim()
    }
    return [ function (candidate, vargs) {
      var candidates = [], stack = [ candidate ],
          star,  i, j, path, object, _;
      // todo: we might be able to get: div/p/3 (third paragraph)
      // todo: we might be able to get: .{ $.tag == 'div' }/.{ $.tag == 'p' }/3 (third paragraph)
      for (i = 0; i < expression.length; i++) {
        while (stack.length) {
          candidate = stack.shift(), object = candidate.o, path = candidate.p, _ = candidate._;
          if (object[expression[i][0]] !== (void(0))) {
            candidates.push({ o: object[expression[i][0]], _: [ expression[i][0] ].concat(_), p: [ object ].concat(path) });
          } else if (expression[i][0] == '.') {
            candidates.push(candidate);
          } else if (expression[i][0] == '..') {
            path = path.slice();
            candidates.unshift({ o: path.shift(), _: _.slice(1), p: path, i: 0 });
          } else if (Array.isArray(object)) {
            for (j = object.length - 1; j > -1; --j) {
              stack.unshift({ o: object[j], _: [ j, expression[i][0] ].concat(_), p: [ object ].concat(path) });
            }
          } else if (~(star = expression[i][0].indexOf('*'))) {
            for (j in object) {
              if (j.indexOf(expression[i][0].substring(0, star)) == 0
                  && j.lastIndexOf(expression[i][0].substring(star + 1) == j.length - (expression[i][0].length - star))) {
                candidates.push({ o: object[j], _: [ j ].concat(_), p: [ object ].concat(path) });
              }
            }
          }
        }
        if (expression[i][1]) {
          while (candidates.length) {
            candidate = candidates.shift(), object = candidate.o;
            if (Array.isArray(object)) {
              for (j = object.length - 1; j > -1; --j) {
                candidates.unshift({ o: object[j], _: [ j, expression[i][0] ].concat(_), p: [ object ].concat(path), i: j });
              }
            } else if (expression[i][1].call(this, candidate, vargs)) {
              stack.push(candidate);
            }
          }
        } else {
          stack.unshift.apply(stack, candidates.splice(0));
        }
      }
      for (j = stack.length - 1; j > -1; --j) stack[j] = stack[j].o;
      return stack;
    }, rest ];
  }
  return function (query, args) {
    var func = parse(query, args || [], 1)[0];
    return function (object) { return func.call(this, { o: object, _: [], p: [], i: 0 }, [].slice.call(arguments, 1)) };
  }
});
<commit_msg>Predicate functions return cadidate if true.<commit_after>! function (definition) {
  if (typeof window != "undefined") window.inquiry = definition();
  else if (typeof define == "function") define(definition);
  else module.exports = definition();
} (function () {
  function parse (rest, fixup, nesting, stop) {
    var expression = [], slash = '/', args, struct, source, i, $;
    rest = rest.trim()
    while (rest && rest[0] != stop) {
      if (rest[0] != '/') {
        if (/^[![{]/.test(rest[0])) {
          rest = '/.' + rest;
        } else {
          rest = slash + rest;
        }
      }
      slash = '';
      $ = /^\/((?:!(?![[{])|[^\]![{/`"]|"(?:[^\\"]|\\.)*")*)((!?)([[{]))?(.*)/.exec(rest);
      if (!$) throw new Error("bad pattern");
      //struct = [ /^['"]/.test($[1].trim()) ? $[1].trim().replace(/^(['"])(.*)\1$/g, "$2").replace(/\\(.)/g, "$1") : decodeURIComponent($[1].trim()) ]
      struct = [ /^"/.exec($[1].trim()) ? JSON.parse($[1].trim()) : decodeURIComponent($[1].trim()) ]
      rest = $[5];
      // Check for have a predicate or a sub-expression.
      switch ($[4]) {
      // We want to consume the contents of the curly braces that define a
      // predicate to construct a function body.
      case "{":
        // Depth is the number of curly braces we've encountered. We match curly
        // braces until it is time to pop.
        // **TODO**: Test against regular expressions. We are going to have to
        // document the one valid regular expression that we know of that we
        // cannot match: `/[/]/`.
        source = $[3] + '(';
        $ = /^(((?:[^'"}]*|'(?:[^\\']|\\.)*'|"(?:[^\\"]|\\.)*")*)})/.exec(rest);
        if (!$) throw new Error("bad pattern");
        source += $[2];
        rest = rest.substring($[1].length);
        args = ['_'];
        for (i = 0; i < nesting; i++) {
          args.push(Array(i + 2).join('$'), Array(i + 2).join('$') + 'i');
        }
        args.push.apply(args, fixup)
        $ = 0; // evil reuse of `$` to count airty. for the bytes, always for the bytes
        source.replace(/\$(\d+)/g, function (_, number) { $ = Math.max($, +number) });
        for (i = 0; i < $; i++) {
          args.push('$' + (i + 1));
        }
        args.push('return ' +  source + ')');
        struct.push((function (predicate) {
          return function (candidate, vargs) {
            return predicate.apply(this, [ candidate._, candidate.o, candidate.i ].concat(vargs))
                 ? [ candidate ] : []
          }
        })(Function.apply(Function, args)), []);
        break;
      // We want to consume the contents of brackets as a sub-expression, so we
      // call ourselves recursively.
      case "[":
        struct.push((function (negate, subquery) {
          return function (candidate, args) {
            var length = subquery.call(this, candidate, [ candidate.o, candidate.i ].concat(args)).length;
            return (negate ? ! length : length) ? [ candidate ] : [];
          }
        })($[3] == '!', ($ = parse(rest, fixup, nesting + 1, "]"))[0]));
        rest = $[1].slice(1);
        break;
      default:
        struct.push(null);
      }
      expression.push(struct);
      rest = rest.trim()
    }
    return [ function (candidate, vargs) {
      var candidates = [], stack = [ candidate ],
          star,  i, j, path, object, _;
      // todo: we might be able to get: div/p/3 (third paragraph)
      // todo: we might be able to get: .{ $.tag == 'div' }/.{ $.tag == 'p' }/3 (third paragraph)
      for (i = 0; i < expression.length; i++) {
        while (stack.length) {
          candidate = stack.shift(), object = candidate.o, path = candidate.p, _ = candidate._;
          if (object[expression[i][0]] !== (void(0))) {
            candidates.push({ o: object[expression[i][0]], _: [ expression[i][0] ].concat(_), p: [ object ].concat(path) });
          } else if (expression[i][0] == '.') {
            candidates.push(candidate);
          } else if (expression[i][0] == '..') {
            path = path.slice();
            candidates.unshift({ o: path.shift(), _: _.slice(1), p: path, i: 0 });
          } else if (Array.isArray(object)) {
            for (j = object.length - 1; j > -1; --j) {
              stack.unshift({ o: object[j], _: [ j, expression[i][0] ].concat(_), p: [ object ].concat(path) });
            }
          } else if (~(star = expression[i][0].indexOf('*'))) {
            for (j in object) {
              if (j.indexOf(expression[i][0].substring(0, star)) == 0
                  && j.lastIndexOf(expression[i][0].substring(star + 1) == j.length - (expression[i][0].length - star))) {
                candidates.push({ o: object[j], _: [ j ].concat(_), p: [ object ].concat(path) });
              }
            }
          }
        }
        if (expression[i][1]) {
          while (candidates.length) {
            candidate = candidates.shift(), object = candidate.o;
            if (Array.isArray(object)) {
              for (j = object.length - 1; j > -1; --j) {
                candidates.unshift({ o: object[j], _: [ j, expression[i][0] ].concat(_), p: [ object ].concat(path), i: j });
              }
            } else {
              stack.push.apply(stack, expression[i][1].call(this, candidate, vargs))
            }
          }
        } else {
          stack.unshift.apply(stack, candidates.splice(0));
        }
      }
      for (j = stack.length - 1; j > -1; --j) stack[j] = stack[j].o;
      return stack;
    }, rest ];
  }
  return function (query, args) {
    var func = parse(query, args || [], 1)[0];
    return function (object) { return func.call(this, { o: object, _: [], p: [], i: 0 }, [].slice.call(arguments, 1)) };
  }
});
<|endoftext|>


<commit_before>import {Class as AstroClass, Module, Behavior} from 'meteor/jagi:astronomy';
import {Meteor} from 'meteor/meteor';
const isRemote = Module.modules.storage.utils.isRemote;
const callMeteorMethod = Module.modules.storage.utils.callMeteorMethod;
import {uniq, find, matchesProperty} from 'lodash';

const relateTo = ({
  localClassName,
  foreignClassName,
  key,
  keyStore,
  keyField,
  foreignKey,
  foreignKeyStore,
  foreignKeyField,
}) => {
  const Class = AstroClass.get(localClassName);
  const relations = Class.getBehavior('relations');
  console.log(relations, relations[0], foreignClassName, find(relations, matchesProperty('Behavior.options.foreignClass', foreignClassName)));
  const doc = Class.findOne({[keyField]: key});

  if (!foreignClassName || !foreignKey) {
    throw new Meteor.Error(500, 'Class and docId are required');
  }
  // if (callback && typeof callback !== 'function') throw new Meteor.Error(500, 'Callback must be a function');

  const RelatedClass = AstroClass.get(foreignClassName);
  const relatedDoc = RelatedClass.findOne({[foreignKeyField]: foreignKey});
  doc.set(keyStore, uniq([...doc[keyStore], foreignKey]));
  doc.save();
  relatedDoc.set(foreignKeyStore, uniq([...relatedDoc[foreignKeyStore], key]));
  relatedDoc.save();
  console.log(`Linked ${localClassName} ${key} with ${foreignClassName} ${foreignKey}`);
  console.log(localClassName,
  foreignClassName,
  key,
  keyStore,
  keyField,
  foreignKey,
  foreignKeyStore,
  foreignKeyField);
  return 1;
};

export default relateTo;
<commit_msg>debugging<commit_after>import {Class as AstroClass, Module, Behavior} from 'meteor/jagi:astronomy';
import {Meteor} from 'meteor/meteor';
const isRemote = Module.modules.storage.utils.isRemote;
const callMeteorMethod = Module.modules.storage.utils.callMeteorMethod;
import {uniq, find, matchesProperty} from 'lodash';

const relateTo = ({
  localClassName,
  foreignClassName,
  key,
  keyStore,
  keyField,
  foreignKey,
  foreignKeyStore,
  foreignKeyField,
}) => {
  const Class = AstroClass.get(localClassName);
  const relations = Class.getBehavior('relations');
  console.log(relations, relations[0].Behavior, relations[0].Behavior.options, foreignClassName, find(relations, matchesProperty('Behavior.options.foreignClass', foreignClassName)));
  const doc = Class.findOne({[keyField]: key});

  if (!foreignClassName || !foreignKey) {
    throw new Meteor.Error(500, 'Class and docId are required');
  }
  // if (callback && typeof callback !== 'function') throw new Meteor.Error(500, 'Callback must be a function');

  const RelatedClass = AstroClass.get(foreignClassName);
  const relatedDoc = RelatedClass.findOne({[foreignKeyField]: foreignKey});
  doc.set(keyStore, uniq([...doc[keyStore], foreignKey]));
  doc.save();
  relatedDoc.set(foreignKeyStore, uniq([...relatedDoc[foreignKeyStore], key]));
  relatedDoc.save();
  console.log(`Linked ${localClassName} ${key} with ${foreignClassName} ${foreignKey}`);
  console.log(localClassName,
  foreignClassName,
  key,
  keyStore,
  keyField,
  foreignKey,
  foreignKeyStore,
  foreignKeyField);
  return 1;
};

export default relateTo;
<|endoftext|>


<commit_before>const qs = require('querystring');

const remote = require('electron').remote;
const ipc = require('electron').ipcRenderer;

const {GitProcess} = require('dugite');

/*
Calculate running averages

Store time that exec was called. Or the difference between that and the last time it was called.
Ignore the time for write operations that are non-parallelizable
Take an average of the last 3 times
And if it is above XX ms create a new renderer to send future messages to.
Once the current renderer finishes up its work kill it
Timing concerns? the async queue will take care of everything for us
*/

class AverageTracker {
  constructor({limit} = {limit: 10}) {
    this.limit = limit;
    this.sum = 0;
    this.values = [];
  }

  addValue(value) {
    if (this.values.length >= this.limit) {
      const discardedValue = this.values.shift();
      this.sum -= discardedValue;
    }
    this.values.push(value);
    this.sum += value;
  }

  getAverage() {
    if (this.values.length < this.limit) { return null; }
    return this.sum / this.limit;
  }
}

const averageTracker = new AverageTracker({limit: 10});

const hostWebContentsId = parseInt(qs.parse(window.location.search.substr(1)).webContentsId, 10);

ipc.on('ping', (event, webContentsId, {args, workingDir, options, operationId, timeSent}) => {
  const formattedArgs = `git ${args.join(' ')} in ${workingDir}`;
  console.log('operationId', operationId, formattedArgs);
  const startTime = performance.now();
  if (process.env.PRINT_GIT_TIMES) {
    console.time(`git:${formattedArgs}`);
  }
  const execStart = performance.now();
  console.log(options, workingDir);
  // debugger;
  GitProcess.exec(args, workingDir, options)
    .then(({stdout, stderr, exitCode}) => {
      event.sender.sendTo(webContentsId, 'git-data', {
        type: 'git',
        data: {stdout, stderr, exitCode, operationId},
      });
      // let err = null;
      // if (exitCode) {
      //   err = {
      //     message: `${formattedArgs} exited with code ${exitCode}\nstdout: ${stdout}\nstderr: ${stderr}`,
      //     code: exitCode,
      //     stdErr: stderr,
      //     stdOut: stdout,
      //     command: formattedArgs,
      //   };
      // }
      // const execTime = performance.now() - startTime;
      // console.log(operationId);
      // console.log(stdout);
      // event.sender.sendTo(webContentsId, 'git-data', {
      //   type: 'git',
      //   data: {result: stdout, err, execTime, operationId, timeSent, formattedArgs},
      // });
    });
  const execEnd = performance.now();
  averageTracker.addValue(execEnd - execStart);
  // console.error(averageTracker.values);
  // console.error(averageTracker.getAverage());
});

ipc.sendTo(hostWebContentsId, 'renderer-ready', {webContentsId: remote.getCurrentWindow().webContents.id});
<commit_msg>:fire: comments<commit_after>const qs = require('querystring');

const remote = require('electron').remote;
const ipc = require('electron').ipcRenderer;

const {GitProcess} = require('dugite');

class AverageTracker {
  constructor({limit} = {limit: 10}) {
    this.limit = limit;
    this.sum = 0;
    this.values = [];
  }

  addValue(value) {
    if (this.values.length >= this.limit) {
      const discardedValue = this.values.shift();
      this.sum -= discardedValue;
    }
    this.values.push(value);
    this.sum += value;
  }

  getAverage() {
    if (this.values.length < this.limit) { return null; }
    return this.sum / this.limit;
  }
}

const averageTracker = new AverageTracker({limit: 10});

const hostWebContentsId = parseInt(qs.parse(window.location.search.substr(1)).webContentsId, 10);

ipc.on('ping', (event, webContentsId, {args, workingDir, options, operationId, timeSent}) => {
  const execStart = performance.now();
  GitProcess.exec(args, workingDir, options)
    .then(({stdout, stderr, exitCode}) => {
      event.sender.sendTo(webContentsId, 'git-data', {
        type: 'git',
        data: {stdout, stderr, exitCode, operationId},
      });
    });
  const execEnd = performance.now();
  averageTracker.addValue(execEnd - execStart);
  // console.error(averageTracker.values);
  // console.error(averageTracker.getAverage());
});

ipc.sendTo(hostWebContentsId, 'renderer-ready', {webContentsId: remote.getCurrentWindow().webContents.id});
<|endoftext|>


<commit_before>import Cucumber from 'cucumber'

const CUCUMBER_EVENTS = [
    'handleBeforeFeatureEvent', 'handleAfterFeatureEvent',
    'handleBeforeScenarioEvent', 'handleAfterScenarioEvent',
    'handleBeforeStepEvent', 'handleStepResultEvent'
]

/**
 * Custom Cucumber Reporter
 */
class CucumberReporter {
    constructor (BaseListener, options, cid, specs) {
        this.listener = BaseListener
        this.capabilities = options.capabilities
        this.options = options
        this.cid = cid
        this.specs = specs
        this.failedCount = 0

        for (const fnName of CUCUMBER_EVENTS) {
            this.listener[fnName] = CucumberReporter.prototype[fnName].bind(this)
        }
    }

    handleBeforeFeatureEvent (event, callback) {
        const feature = event.getUri ? event : event.getPayloadItem('feature')
        this.featureStart = new Date()
        this.runningFeature = feature

        this.emit('suite:start', {
            uid: this.getUniqueIdentifier(feature),
            title: feature.getName(),
            type: 'suite',
            file: this.getUriOf(feature)
        })

        process.nextTick(callback)
    }

    handleBeforeScenarioEvent (event, callback) {
        const scenario = event.getUri ? event : event.getPayloadItem('scenario')
        this.runningScenario = scenario
        this.scenarioStart = new Date()
        this.testStart = new Date()

        this.emit('suite:start', {
            uid: this.getUniqueIdentifier(scenario),
            title: scenario.getName(),
            parent: this.getUniqueIdentifier(this.runningFeature),
            type: 'suite',
            file: this.getUriOf(scenario)
        })

        process.nextTick(callback)
    }

    handleBeforeStepEvent (event, callback) {
        const step = event.getUri ? event : event.getPayloadItem('step')
        this.testStart = new Date()

        this.emit('test:start', {
            uid: this.getUniqueIdentifier(step),
            title: step.getName(),
            type: 'test',
            file: step.getUri(),
            parent: this.getUniqueIdentifier(this.runningScenario),
            duration: new Date() - this.testStart
        })

        process.nextTick(callback)
    }

    handleStepResultEvent (event, callback) {
        const stepResult = event.getStep ? event : event.getPayloadItem('stepResult')
        let step = stepResult.getStep()
        let e = 'undefined'

        switch (stepResult.getStatus()) {
        case Cucumber.Status.FAILED:
        case Cucumber.Status.UNDEFINED:
            e = 'fail'
            break
        case Cucumber.Status.PASSED:
            e = 'pass'
            break
        case Cucumber.Status.PENDING:
        case Cucumber.Status.SKIPPED:
        case Cucumber.Status.AMBIGUOUS:
            e = 'pending'
        }
        let error = {}
        let stepTitle = step.getName() || step.getKeyword() || 'Undefined Step'

        /**
         * if step name is undefined we are dealing with a hook
         * don't report hooks if no error happened
         */
        if (!step.getName() && stepResult.getStatus() !== Cucumber.Status.FAILED) {
            return process.nextTick(callback)
        }

        if (stepResult.getStatus() === Cucumber.Status.UNDEFINED) {
            if (this.options.ignoreUndefinedDefinitions) {
                /**
                 * mark test as pending
                 */
                e = 'pending'
                stepTitle += ' (undefined step)'
            } else {
                /**
                 * mark test as failed
                 */
                this.failedCount++

                error = {
                    message: `Step "${stepTitle}" is not defined. You can ignore this error by setting
                              cucumberOpts.ignoreUndefinedDefinitions as true.`,
                    stack: `${step.getUri()}:${step.getLine()}`
                }
            }
        } else if (stepResult.getStatus() === Cucumber.Status.FAILED) {
            /**
             * cucumber failure exception can't get send to parent process
             * for some reasons
             */
            let err = stepResult.getFailureException()
            error = {
                message: err.message,
                stack: err.stack
            }
            this.failedCount++
        } else if (stepResult.getStatus() === Cucumber.Status.AMBIGUOUS && this.options.failAmbiguousDefinitions) {
            e = 'fail'
            this.failedCount++
            error = {
                message: `Step "${stepTitle}" is ambiguous. The following steps matched the step definition`,
                stack: stepResult.getAmbiguousStepDefinitions().map(step => `${step.getPattern().toString()} in ${step.getUri()}:${step.getLine()}`).join('\n')
            }
        }

        this.emit('test:' + e, {
            uid: this.getUniqueIdentifier(step),
            title: stepTitle.trim(),
            type: 'test',
            file: this.getUriOf(step),
            parent: this.getUniqueIdentifier(this.runningScenario),
            error: error,
            duration: new Date() - this.testStart
        })

        process.nextTick(callback)
    }

    handleAfterScenarioEvent (event, callback) {
        const scenario = event.getUri ? event : event.getPayloadItem('scenario')
        this.emit('suite:end', {
            uid: this.getUniqueIdentifier(scenario),
            title: scenario.getName(),
            parent: this.getUniqueIdentifier(this.runningFeature),
            type: 'suite',
            file: this.getUriOf(scenario),
            duration: new Date() - this.scenarioStart
        })

        process.nextTick(callback)
    }

    handleAfterFeatureEvent (event, callback) {
        const feature = event.getUri ? event : event.getPayloadItem('feature')
        this.emit('suite:end', {
            uid: this.getUniqueIdentifier(feature),
            title: feature.getName(),
            type: 'suite',
            file: this.getUriOf(feature),
            duration: new Date() - this.featureStart
        })

        process.nextTick(callback)
    }

    emit (event, payload) {
        let message = {
            event: event,
            cid: this.cid,
            uid: this.getUniqueIdentifier(payload),
            title: payload.title,
            pending: payload.pending || false,
            parent: payload.parent || null,
            type: payload.type,
            file: payload.file,
            err: payload.error || {},
            duration: payload.duration,
            runner: {},
            specs: this.specs
        }

        message.runner[this.cid] = this.capabilities
        this.send(message)
    }

    send (message) {
        return process.send(message)
    }

    getListener () {
        return this.listener
    }

    getUriOf (type) {
        if (!type || !type.getUri()) {
            return
        }

        return type.getUri().replace(process.cwd(), '')
    }

    getUniqueIdentifier (target) {
        return target.getName() + target.getLine()
    }
}

export default CucumberReporter
<commit_msg>Added fallback for missing line numbers<commit_after>import Cucumber from 'cucumber'

const CUCUMBER_EVENTS = [
    'handleBeforeFeatureEvent', 'handleAfterFeatureEvent',
    'handleBeforeScenarioEvent', 'handleAfterScenarioEvent',
    'handleBeforeStepEvent', 'handleStepResultEvent'
]

/**
 * Custom Cucumber Reporter
 */
class CucumberReporter {
    constructor (BaseListener, options, cid, specs) {
        this.listener = BaseListener
        this.capabilities = options.capabilities
        this.options = options
        this.cid = cid
        this.specs = specs
        this.failedCount = 0

        for (const fnName of CUCUMBER_EVENTS) {
            this.listener[fnName] = CucumberReporter.prototype[fnName].bind(this)
        }
    }

    handleBeforeFeatureEvent (event, callback) {
        const feature = event.getUri ? event : event.getPayloadItem('feature')
        this.featureStart = new Date()
        this.runningFeature = feature

        this.emit('suite:start', {
            uid: this.getUniqueIdentifier(feature),
            title: feature.getName(),
            type: 'suite',
            file: this.getUriOf(feature)
        })

        process.nextTick(callback)
    }

    handleBeforeScenarioEvent (event, callback) {
        const scenario = event.getUri ? event : event.getPayloadItem('scenario')
        this.runningScenario = scenario
        this.scenarioStart = new Date()
        this.testStart = new Date()

        this.emit('suite:start', {
            uid: this.getUniqueIdentifier(scenario),
            title: scenario.getName(),
            parent: this.getUniqueIdentifier(this.runningFeature),
            type: 'suite',
            file: this.getUriOf(scenario)
        })

        process.nextTick(callback)
    }

    handleBeforeStepEvent (event, callback) {
        const step = event.getUri ? event : event.getPayloadItem('step')
        this.testStart = new Date()

        this.emit('test:start', {
            uid: this.getUniqueIdentifier(step),
            title: step.getName(),
            type: 'test',
            file: step.getUri(),
            parent: this.getUniqueIdentifier(this.runningScenario),
            duration: new Date() - this.testStart
        })

        process.nextTick(callback)
    }

    handleStepResultEvent (event, callback) {
        const stepResult = event.getStep ? event : event.getPayloadItem('stepResult')
        let step = stepResult.getStep()
        let e = 'undefined'

        switch (stepResult.getStatus()) {
        case Cucumber.Status.FAILED:
        case Cucumber.Status.UNDEFINED:
            e = 'fail'
            break
        case Cucumber.Status.PASSED:
            e = 'pass'
            break
        case Cucumber.Status.PENDING:
        case Cucumber.Status.SKIPPED:
        case Cucumber.Status.AMBIGUOUS:
            e = 'pending'
        }
        let error = {}
        let stepTitle = step.getName() || step.getKeyword() || 'Undefined Step'

        /**
         * if step name is undefined we are dealing with a hook
         * don't report hooks if no error happened
         */
        if (!step.getName() && stepResult.getStatus() !== Cucumber.Status.FAILED) {
            return process.nextTick(callback)
        }

        if (stepResult.getStatus() === Cucumber.Status.UNDEFINED) {
            if (this.options.ignoreUndefinedDefinitions) {
                /**
                 * mark test as pending
                 */
                e = 'pending'
                stepTitle += ' (undefined step)'
            } else {
                /**
                 * mark test as failed
                 */
                this.failedCount++

                error = {
                    message: `Step "${stepTitle}" is not defined. You can ignore this error by setting
                              cucumberOpts.ignoreUndefinedDefinitions as true.`,
                    stack: `${step.getUri()}:${step.getLine()}`
                }
            }
        } else if (stepResult.getStatus() === Cucumber.Status.FAILED) {
            /**
             * cucumber failure exception can't get send to parent process
             * for some reasons
             */
            let err = stepResult.getFailureException()
            error = {
                message: err.message,
                stack: err.stack
            }
            this.failedCount++
        } else if (stepResult.getStatus() === Cucumber.Status.AMBIGUOUS && this.options.failAmbiguousDefinitions) {
            e = 'fail'
            this.failedCount++
            error = {
                message: `Step "${stepTitle}" is ambiguous. The following steps matched the step definition`,
                stack: stepResult.getAmbiguousStepDefinitions().map(step => `${step.getPattern().toString()} in ${step.getUri()}:${step.getLine()}`).join('\n')
            }
        }

        this.emit('test:' + e, {
            uid: this.getUniqueIdentifier(step),
            title: stepTitle.trim(),
            type: 'test',
            file: this.getUriOf(step),
            parent: this.getUniqueIdentifier(this.runningScenario),
            error: error,
            duration: new Date() - this.testStart
        })

        process.nextTick(callback)
    }

    handleAfterScenarioEvent (event, callback) {
        const scenario = event.getUri ? event : event.getPayloadItem('scenario')
        this.emit('suite:end', {
            uid: this.getUniqueIdentifier(scenario),
            title: scenario.getName(),
            parent: this.getUniqueIdentifier(this.runningFeature),
            type: 'suite',
            file: this.getUriOf(scenario),
            duration: new Date() - this.scenarioStart
        })

        process.nextTick(callback)
    }

    handleAfterFeatureEvent (event, callback) {
        const feature = event.getUri ? event : event.getPayloadItem('feature')
        this.emit('suite:end', {
            uid: this.getUniqueIdentifier(feature),
            title: feature.getName(),
            type: 'suite',
            file: this.getUriOf(feature),
            duration: new Date() - this.featureStart
        })

        process.nextTick(callback)
    }

    emit (event, payload) {
        let message = {
            event: event,
            cid: this.cid,
            uid: this.getUniqueIdentifier(payload),
            title: payload.title,
            pending: payload.pending || false,
            parent: payload.parent || null,
            type: payload.type,
            file: payload.file,
            err: payload.error || {},
            duration: payload.duration,
            runner: {},
            specs: this.specs
        }

        message.runner[this.cid] = this.capabilities
        this.send(message)
    }

    send (message) {
        return process.send(message)
    }

    getListener () {
        return this.listener
    }

    getUriOf (type) {
        if (!type || !type.getUri()) {
            return
        }

        return type.getUri().replace(process.cwd(), '')
    }

    getUniqueIdentifier (target) {
        return target.getName() +
                (target.getLine() || '')
    }
}

export default CucumberReporter
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var util = require('util');
var istanbul = require('istanbul');
var dateformat = require('dateformat');

var Store = istanbul.Store;

var BasePathStore = function(opts) {
  Store.call(this, opts);
  opts = opts || {};
  this.basePath = opts.basePath;
  this.delegate = Store.create('fslookup');
};
BasePathStore.TYPE = 'basePathlookup';
util.inherits(BasePathStore, Store);

Store.mix(BasePathStore, {
  keys : function() {
    return this.delegate.keys();
  },
  toKey : function(key) {
    if (key.indexOf('./') === 0) { return path.join(this.basePath, key); }
    return key;
  },
  get : function(key) {
    return this.delegate.get(this.toKey(key));
  },
  hasKey : function(key) {
    return this.delegate.hasKey(this.toKey(key));
  },
  set : function(key, contents) {
    return this.delegate.set(this.toKey(key), contents);
  }
});

// TODO(vojta): inject only what required (config.basePath, config.coverageReporter)
var CoverageReporter = function(rootConfig, emitter, helper, logger) {
  var log = logger.create('coverage');
  var config = rootConfig.coverageReporter;
  var basePath = rootConfig.basePath;
  var outDir = config.dir;
  var type = config.type;

  this.adapters = [];
  var collectors;
  var pendingFileWritings = 0;
  var fileWritingFinished = function() {};

  function writeEnd() {
    if (!--pendingFileWritings) {
      fileWritingFinished();
    }
  }

  this.onRunStart = function(browsers) {
    collectors = {};
    browsers.forEach(function(browser) {
      collectors[browser.id] = new istanbul.Collector();
    });
  };

  this.onBrowserComplete = function(browser, result) {
    var collector = collectors[browser.id];

    if (!collector) {
      return;
    }

    if (result && result.coverage) {
      collector.add(result.coverage);
    }

    pendingFileWritings++;
    helper.mkdirIfNotExists(path.resolve(outDir), function() {
      var now = dateformat(new Date(), 'yyyymmdd_HHMMss');
      var name = 'coverage-' + browser.name + '-' + now + '.json';
      fs.writeFile(path.join(outDir, name), JSON.stringify(collector.getFinalCoverage()), 'utf8', function(err) {
        if (err) {
          log.error(err);
        }
        writeEnd();
      });
    });
  };

  this.onSpecComplete = function(browser, result) {
    if (result.coverage) {
      collectors[browser.id].add(result.coverage);
    }
  };

  this.onRunComplete = function(browsers, results) {
    browsers.forEach(function(browser) {
      var collector = collectors[browser.id];
      if (collector) {
        pendingFileWritings++;
        var out = path.resolve(outDir, browser.name);
        helper.mkdirIfNotExists(out, function() {
          var options = helper.merge({}, config, {
            dir : out,
            sourceStore : new BasePathStore({
              basePath : basePath
            })
          });
          var reporter = istanbul.Report.create(type, options);
          try {
            reporter.writeReport(collector, true);
          } catch (e) {
            log.error(e);
          }
          collector.dispose();
          writeEnd();
        });
      }
    });
  };

  // TODO(vojta): refactor to onExit
  emitter.on('exit', function(done) {
    if (pendingFileWritings) {
      fileWritingFinished = done;
    } else {
      done();
    }
  });
};

CoverageReporter.$inject = ['config', 'emitter', 'helper', 'logger'];

// PUBLISH
module.exports = CoverageReporter;
<commit_msg>feat: allow multiple report types<commit_after>var path = require('path');
var fs = require('fs');
var util = require('util');
var istanbul = require('istanbul');
var dateformat = require('dateformat');

var Store = istanbul.Store;

var BasePathStore = function(opts) {
  Store.call(this, opts);
  opts = opts || {};
  this.basePath = opts.basePath;
  this.delegate = Store.create('fslookup');
};
BasePathStore.TYPE = 'basePathlookup';
util.inherits(BasePathStore, Store);

Store.mix(BasePathStore, {
  keys : function() {
    return this.delegate.keys();
  },
  toKey : function(key) {
    if (key.indexOf('./') === 0) { return path.join(this.basePath, key); }
    return key;
  },
  get : function(key) {
    return this.delegate.get(this.toKey(key));
  },
  hasKey : function(key) {
    return this.delegate.hasKey(this.toKey(key));
  },
  set : function(key, contents) {
    return this.delegate.set(this.toKey(key), contents);
  }
});

// TODO(vojta): inject only what required (config.basePath, config.coverageReporter)
var CoverageReporter = function(rootConfig, emitter, helper, logger) {
  var log = logger.create('coverage');
  var config = rootConfig.coverageReporter;
  var basePath = rootConfig.basePath;
  var outDir = config.dir;
  var reporters = config.reporters;

  if (!helper.isDefined(reporters)) {
    reporters = [config];
  }

  this.adapters = [];
  var collectors;
  var pendingFileWritings = 0;
  var fileWritingFinished = function() {};

  function writeEnd() {
    if (!--pendingFileWritings) {
      // cleanup collectors
      Object.keys(collectors).forEach(function(key) {
         collectors[key].dispose();
      });
      fileWritingFinished();
    }
  }

  this.onRunStart = function(browsers) {
    collectors = {};
    browsers.forEach(function(browser) {
      collectors[browser.id] = new istanbul.Collector();
    });
  };

  this.onBrowserComplete = function(browser, result) {
    var collector = collectors[browser.id];

    if (!collector) {
      return;
    }

    if (result && result.coverage) {
      collector.add(result.coverage);
    }

    pendingFileWritings++;
    helper.mkdirIfNotExists(path.resolve(outDir), function() {
      var now = dateformat(new Date(), 'yyyymmdd_HHMMss');
      var name = 'coverage-' + browser.name + '-' + now + '.json';
      fs.writeFile(path.join(outDir, name), JSON.stringify(collector.getFinalCoverage()), 'utf8', function(err) {
        if (err) {
          log.error(err);
        }
        writeEnd();
      });
    });
  };

  this.onSpecComplete = function(browser, result) {
    if (result.coverage) {
      collectors[browser.id].add(result.coverage);
    }
  };

  this.onRunComplete = function(browsers, results) {
    reporters.forEach(function(reporterConfig) {
      browsers.forEach(function(browser) {
        var collector = collectors[browser.id];
        if (collector) {
          pendingFileWritings++;
          var out = path.resolve(outDir, browser.name);
          helper.mkdirIfNotExists(out, function() {
            var options = helper.merge({}, reporterConfig, {
              dir : out,
              sourceStore : new BasePathStore({
                basePath : basePath
              })
            });
            var reporter = istanbul.Report.create(reporterConfig.type, options);
            try {
              reporter.writeReport(collector, true);
            } catch (e) {
              log.error(e);
            }
            collector.dispose();
            writeEnd();
          });
        }
      });
    });
  };

  // TODO(vojta): refactor to onExit
  emitter.on('exit', function(done) {
    if (pendingFileWritings) {
      fileWritingFinished = done;
    } else {
      done();
    }
  });
};

CoverageReporter.$inject = ['config', 'emitter', 'helper', 'logger'];

// PUBLISH
module.exports = CoverageReporter;
<|endoftext|>


<commit_before>/**
 * Unanimity
 */

var fs = require("fs");
var process = require("process");
var wrench = require("wrench");
var asar = require("asar");

var discordPath;
var importLineNumber;
var functionLineNumber;
var functionCallLineNumber;
var packageLineNumber;

var appIndexPath = "/app/index.js";
var appPackagePath = "/app/package.json";

function exit()
{
    process.exit();
}

/*
 type 0: message
 type 1: error
 */
function log(message, type)
{
    if (typeof document == "undefined") {
        var typeString;

        switch (type) {
            case 0:
                typeString = "";
                break;
            case 1:
                typeString = "Error: ";
                break;
            default:
                typeString = "";
                break;
        }

        console.log(typeString + message);
    } else {
        document.getElementById("logs").innerHTML = message;

        if (type == 0) {
            document.getElementById("logs").className = "message";
        } else if (type == 1) {
            document.getElementById("logs").className = "error";
            document.getElementById("exitButton").disabled = false;
        }
    }
}

function install()
{
    if (typeof document != "undefined") {
        document.getElementById("installButton").disabled = true;
        document.getElementById("exitButton").disabled = true;
    }

    if (typeof discordPath == "undefined") {
		var os = process.platform;

		if (os == "darwin") {
			discordPath = "/Applications/Discord.app/Contents/Resources";
			importLineNumber = 84;
			functionLineNumber = 602;
			functionCallLineNumber = 500;
			packageLineNumber = 10;
		} else {
			log("Unanimity only supports OS X.", 1);
		}
	}

	fs.exists(discordPath, function (exists) {
		if (exists) {
			log("Discord folder found at " + discordPath + ".", 0);

			var appPath = discordPath + "/node_modules/Unanimity";
			var asarPath = discordPath + "/app.asar";
			var extractedAsarPath = discordPath + "/app";

			if (fs.existsSync(appPath)) {
				log("Removing current version of Unanimity.", 0);
				wrench.rmdirSyncRecursive(appPath);
				log("Removed current version of Unanimity.", 0);
			}

			if (fs.existsSync(extractedAsarPath)) {
				log("Removing old Discord Atom-Shell Archive.", 0);
				wrench.rmdirSyncRecursive(extractedAsarPath);
				log("Removed old Discord Atom-Shell Archive.", 0);
			}

			log("Installing Unanimity.", 0);
			wrench.copyDirSyncRecursive(process.cwd() + "/Unanimity/", appPath, {});

			if (fs.existsSync(asarPath)) {
				log("Discord Atom-Shell Archive found at " + asarPath + ".", 0);
			} else {
				log("Discord Atom-Shell Archive not found at " + asarPath + ".", 1);
			}

			log("Extracting Discord Atom-Shell Archive.", 0);
			asar.extractAll(asarPath, extractedAsarPath);

			fs.exists(extractedAsarPath, function (exists) {
				if (exists) {
					log("Discord Atom-Shell Archive extracted at " + extractedAsarPath + ".", 0);

					log("Injecting index.js.", 0);

					var data = fs.readFileSync(extractedAsarPath + appIndexPath).toString().split("\n");
					data.splice(importLineNumber, 0, "var unanimity = require('unanimity');\n");
					data.splice(functionCallLineNumber, 0, "\n_unanimity(mainWindow);");
					data.splice(functionLineNumber, 0, "\t\tfunction _unanimity(w) { unanimity = new unanimity.Unanimity(w); unanimity.init(); }\n");

					fs.writeFile(extractedAsarPath + appIndexPath, data.join("\n"), function(err) {
						if (err) {
							log("Something went wrong while injecting index.js.", 1);
							return;
						}

						log("Injected index.js.", 0);
						log("Injecting package.json.", 0);

						var data = fs.readFileSync(extractedAsarPath + appPackagePath).toString().split("\n");
						data.splice(packageLineNumber, 0, '\t\t"unanimity": "^0.1.0",');

						fs.writeFile(extractedAsarPath + appPackagePath, data.join("\n"), function(err) {
							if (err) {
								log("Something went wrong while injecting package.json.", 1);
								return;
							}

							log("Injected package.json.", 0);

							log("Enjoy.", 0);

                            if (typeof document != "undefined") {
                                document.getElementById("exitButton").disabled = false;
                            }
						});
					});
				} else {
					log("Could not extract Discord Atom-Shell Archive.", 1);
				}
			});
		} else {
			log("Discord folder not found at " + discordPath + ".", 1);
		}
	});
}

if (typeof document == "undefined") {
    var argument = process.argv.slice(2);

    if (argument == "install") {
        install();
    } else {
        log("Usage: node install.js {install}.")
    }
}<commit_msg>Add support for Windows<commit_after>/**
 * Unanimity
 */

var fs = require("fs");
var process = require("process");
var wrench = require("wrench");
var asar = require("asar");

var discordPath;
var importLineNumber;
var functionLineNumber;
var functionCallLineNumber;
var packageLineNumber;

var appIndexPath = "/app/index.js";
var appPackagePath = "/app/package.json";
var discordVersion = "0.0.280";

function exit()
{
    process.exit();
}

/*
 type 0: message
 type 1: error
 */
function log(message, type)
{
    if (typeof document == "undefined") {
        var typeString;

        switch (type) {
            case 0:
                typeString = "";
                break;
            case 1:
                typeString = "Error: ";
                break;
            default:
                typeString = "";
                break;
        }

        console.log(typeString + message);
    } else {
        document.getElementById("logs").innerHTML = message;

        if (type == 0) {
            document.getElementById("logs").className = "message";
        } else if (type == 1) {
            document.getElementById("logs").className = "error";
            document.getElementById("exitButton").disabled = false;
        }
    }
}

function install()
{
    if (typeof document != "undefined") {
        document.getElementById("installButton").disabled = true;
        document.getElementById("exitButton").disabled = true;
    }

    if (typeof discordPath == "undefined") {
		var os = process.platform;

		if (os == "darwin") {
			discordPath = "/Applications/Discord.app/Contents/Resources";
			importLineNumber = 84;
			functionLineNumber = 602;
			functionCallLineNumber = 500;
			packageLineNumber = 10;
		} else if (os == "win32") {
            //noinspection JSUnresolvedVariable
            discordPath = process.env.LOCALAPPDATA + "/Discord/app-" + discordVersion + "/resources";
            importLineNumber = 84;
            functionLineNumber = 597;
            functionCallLineNumber = 497;
            packageLineNumber = 10;
        } else {
			log("Unanimity only supports OS X.", 1);
		}
	}

	fs.exists(discordPath, function (exists) {
		if (exists) {
			log("Discord folder found at " + discordPath + ".", 0);

			var appPath = discordPath + "/node_modules/Unanimity";
			var asarPath = discordPath + "/app.asar";
			var extractedAsarPath = discordPath + "/app";

			if (fs.existsSync(appPath)) {
				log("Removing current version of Unanimity.", 0);
				wrench.rmdirSyncRecursive(appPath);
				log("Removed current version of Unanimity.", 0);
			}

			if (fs.existsSync(extractedAsarPath)) {
				log("Removing old Discord Atom-Shell Archive.", 0);
				wrench.rmdirSyncRecursive(extractedAsarPath);
				log("Removed old Discord Atom-Shell Archive.", 0);
			}

			log("Installing Unanimity.", 0);
			wrench.copyDirSyncRecursive(process.cwd() + "/Unanimity/", appPath, {});

			if (fs.existsSync(asarPath)) {
				log("Discord Atom-Shell Archive found at " + asarPath + ".", 0);
			} else {
				log("Discord Atom-Shell Archive not found at " + asarPath + ".", 1);
			}

			log("Extracting Discord Atom-Shell Archive.", 0);
			asar.extractAll(asarPath, extractedAsarPath);

			fs.exists(extractedAsarPath, function (exists) {
				if (exists) {
					log("Discord Atom-Shell Archive extracted at " + extractedAsarPath + ".", 0);

					log("Injecting index.js.", 0);

					var data = fs.readFileSync(extractedAsarPath + appIndexPath).toString().split("\n");
					data.splice(importLineNumber, 0, "var unanimity = require('unanimity');\n");
					data.splice(functionCallLineNumber, 0, "\n_unanimity(mainWindow);");
					data.splice(functionLineNumber, 0, "\t\tfunction _unanimity(w) { unanimity = new unanimity.Unanimity(w); unanimity.init(); }\n");

					fs.writeFile(extractedAsarPath + appIndexPath, data.join("\n"), function(err) {
						if (err) {
							log("Something went wrong while injecting index.js.", 1);
							return;
						}

						log("Injected index.js.", 0);
						log("Injecting package.json.", 0);

						var data = fs.readFileSync(extractedAsarPath + appPackagePath).toString().split("\n");
						data.splice(packageLineNumber, 0, '\t\t"unanimity": "^0.1.0",');

						fs.writeFile(extractedAsarPath + appPackagePath, data.join("\n"), function(err) {
							if (err) {
								log("Something went wrong while injecting package.json.", 1);
								return;
							}

							log("Injected package.json.", 0);

							log("Enjoy.", 0);

                            if (typeof document != "undefined") {
                                document.getElementById("exitButton").disabled = false;
                            }
						});
					});
				} else {
					log("Could not extract Discord Atom-Shell Archive.", 1);
				}
			});
		} else {
			log("Discord folder not found at " + discordPath + ".", 1);
		}
	});
}

if (typeof document == "undefined") {
    var argument = process.argv.slice(2);

    if (argument == "install") {
        install();
    } else {
        log("Usage: node install.js {install}.")
    }
}<|endoftext|>


<commit_before>"use strict"

const fmt = require("./fmt")
const formatTime = require("./fn").formatTime

module.exports = function () {
	const $ = this.$

	return this
		.on("fly_run", file => {
			$.log(`Flying with ${fmt.path(file)}`)
		})

		.on("flyfile_not_found", () => {
			$.log("Flyfile not found!")
			process.exit(1)
		})

		.on("fly_watch", () => {
			$.log(fmt.warn("Watching files..."))
		})

		.on("fly_watch_event", obj => {
			$.log(`File ${obj.action}: ${fmt.warn(obj.file)}`)
		})

		.on("globs_no_match", (globs, opts) => {
			let str = `${fmt.warn("Warning:")} Source did not match any files!`
			str += `\n\t  Patterns:   ${JSON.stringify(globs)}`
			opts && (str += `\n\t  Options:    ${JSON.stringify(opts)}`)
			$.log(str)
		})

		.on("plugin_load", obj => {
			$.log(`Loading plugin ${fmt.title(obj.plugin)}`)
		})

		.on("plugin_load_error", str => {
			$.log(`Problem loading plugin: ${fmt.title(str)}`)
		})

		.on("plugin_rename", obj => {
			$.log(`${fmt.title(obj.o)} was renamed to ${fmt.title(obj.n)} because its name was taken`)
		})

		.on("plugin_error", obj => {
			process.exitCode = 1
			$.log(`${fmt.error(obj.plugin)} failed due to ${fmt.error(obj.error)}`)
		})

		.on("tasks_force_object", () => {
			$.error("Invalid Tasks!")
			$.log("Custom `tasks` must be an `object`.")
			process.exit(1)
		})

		.on("task_error", obj => {
			process.exitCode = 1
			$.trace(obj.error)
			$.log(`${fmt.error(obj.task)} failed due to ${fmt.error(obj.error)}`)
		})

		.on("task_start", str => {
			$.log(`Starting ${fmt.title(str)}`)
		})

		.on("task_complete", (str, time) => {
			const t = formatTime(time)
			$.log(`Finished ${fmt.complete(str)} in ${fmt.time(t)}`)
		})

		.on("task_not_found", str => {
			$.log(`${fmt.error(str)} not found in Flyfile.`)
			process.exit(1)
		})

		.on("serial_error", () => {
			$.error("Task chain was aborted!")
			process.exit(1)
		})
}
<commit_msg>update 'plugin_rename' reporter<commit_after>"use strict"

const fmt = require("./fmt")
const formatTime = require("./fn").formatTime

module.exports = function () {
	const $ = this.$

	return this
		.on("fly_run", file => {
			$.log(`Flying with ${fmt.path(file)}`)
		})

		.on("flyfile_not_found", () => {
			$.log("Flyfile not found!")
			process.exit(1)
		})

		.on("fly_watch", () => {
			$.log(fmt.warn("Watching files..."))
		})

		.on("fly_watch_event", obj => {
			$.log(`File ${obj.action}: ${fmt.warn(obj.file)}`)
		})

		.on("globs_no_match", (globs, opts) => {
			let str = `${fmt.warn("Warning:")} Source did not match any files!`
			str += `\n\t  Patterns:   ${JSON.stringify(globs)}`
			opts && (str += `\n\t  Options:    ${JSON.stringify(opts)}`)
			$.log(str)
		})

		.on("plugin_load", obj => {
			$.log(`Loading plugin ${fmt.title(obj.plugin)}`)
		})

		.on("plugin_load_error", str => {
			$.log(`Problem loading plugin: ${fmt.title(str)}`)
		})

		.on("plugin_rename", (old, nxt) => {
			$.log(`${fmt.title(old)} was renamed to ${fmt.title(nxt)} because its name was taken`)
		})

		.on("plugin_error", obj => {
			process.exitCode = 1
			$.log(`${fmt.error(obj.plugin)} failed due to ${fmt.error(obj.error)}`)
		})

		.on("tasks_force_object", () => {
			$.error("Invalid Tasks!")
			$.log("Custom `tasks` must be an `object`.")
			process.exit(1)
		})

		.on("task_error", obj => {
			process.exitCode = 1
			$.trace(obj.error)
			$.log(`${fmt.error(obj.task)} failed due to ${fmt.error(obj.error)}`)
		})

		.on("task_start", str => {
			$.log(`Starting ${fmt.title(str)}`)
		})

		.on("task_complete", (str, time) => {
			const t = formatTime(time)
			$.log(`Finished ${fmt.complete(str)} in ${fmt.time(t)}`)
		})

		.on("task_not_found", str => {
			$.log(`${fmt.error(str)} not found in Flyfile.`)
			process.exit(1)
		})

		.on("serial_error", () => {
			$.error("Task chain was aborted!")
			process.exit(1)
		})
}
<|endoftext|>


<commit_before>var async = require('async'),
    child_process = require('child_process'),
    spawn = child_process.spawn,
    path = require('path'),
    fs = require('fs'),
    request = require('request'),
    AdmZip = require('adm-zip');

function passthru() {
    var args = Array.prototype.slice.call(arguments);
    var cb = args.splice(-1)[0];
    var cmd = args.splice(0, 1)[0];
    var opts = {};
    if(typeof(args.slice(-1)[0]) === 'object') {
        opts = args.splice(-1)[0];
    }
    var child = spawn(cmd, args, opts);

    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);
    child.on('exit', cb);
}

function shpassthru() {
    var cmd =
    passthru.apply(null, ['/bin/sh', '-c'].concat(Array.prototype.slice.call(arguments)));
}

function envpassthru() {
    passthru.apply(null, ['/usr/bin/env'].concat(Array.prototype.slice.call(arguments)));
}

var updateSubmodules = function(mainCallback) {
    console.log('[nodegit] Downloading libgit2 dependency.');
    async.series([
        function(callback) {
            envpassthru('git', 'submodule', 'init', callback);
        }, function(callback) {
            envpassthru('git', 'submodule', 'update', callback);
        }
        ], function(error) {
            if (error) process.exit(error);
            mainCallback();
        });
};

var checkoutDependencies = function(mainCallback) {
    console.log('[nodegit] Downloading libgit2 dependency.');

    var commit = 'b70bf922a1de35722904930c42467e95c889562f';
    var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/' + commit + '.zip';
        zipFile = __dirname + '/vendor/libgit2.zip',
        unzippedFolderName = __dirname + '/vendor/libgit2-' + commit,
        targetFolderName = __dirname + '/vendor/libgit2';

    async.series([
        function(callback) {
            request(libgit2ZipUrl)
                .pipe(fs.createWriteStream(zipFile))
                .on('close', function () {
                    callback();
            });

        }, function(callback) {
            var zip = new AdmZip(zipFile);
            zip.extractAllTo(__dirname + '/vendor/', true);
            fs.unlink(zipFile);
            callback();
        },
        function renameLibgit2Folder(callback) {
            fs.rename(unzippedFolderName, targetFolderName, callback);
        }
        ], function(error) {
            if (error) process.exit(error);
            mainCallback();
        });
};

var buildDir = path.join(__dirname, 'vendor/libgit2/build');
async.series([
    function(callback) {
        // Check for presence of .git folder
        fs.exists(__dirname + '/.git', function(exists) {
            if (exists) {
                updateSubmodules(callback);
            } else {
                checkoutDependencies(callback);
            }
        });
    },
    function(callback) {
        console.log('[nodegit] Building libgit2 dependency.');
        envpassthru('mkdir', '-p', buildDir, callback);
    },
    function(callback) {
        envpassthru('cmake', '-DTHREADSAFE=1', '-DBUILD_CLAR=0', '..', {
            cwd: buildDir
        }, callback);
    },
    function(callback) {
        envpassthru('cmake', '--build', '.', {
            cwd: buildDir
        }, callback);
    },
    function(callback) {
        console.log('[nodegit] Building native module.');
        shpassthru('node-gyp configure --debug', callback);
        // shpassthru('node-gyp configure', callback);
    },
    function(callback) {
        shpassthru('node-gyp build', callback);
    }
], function(err) {
    if(err) process.exit(err);
});
<commit_msg>Updated installer<commit_after>var async = require('async'),
    child_process = require('child_process'),
    spawn = child_process.spawn,
    path = require('path'),
    fs = require('fs'),
    request = require('request'),
    AdmZip = require('adm-zip');

function passthru() {
    var args = Array.prototype.slice.call(arguments);
    var cb = args.splice(-1)[0];
    var cmd = args.splice(0, 1)[0];
    var opts = {};
    if(typeof(args.slice(-1)[0]) === 'object') {
        opts = args.splice(-1)[0];
    }
    var child = spawn(cmd, args, opts);

    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);
    child.on('exit', cb);
}

function shpassthru() {
    var cmd =
    passthru.apply(null, ['/bin/sh', '-c'].concat(Array.prototype.slice.call(arguments)));
}

function envpassthru() {
    passthru.apply(null, ['/usr/bin/env'].concat(Array.prototype.slice.call(arguments)));
}

var updateSubmodules = function(mainCallback) {
    console.log('[nodegit] Downloading libgit2 dependency.');
    async.series([
        function(callback) {
            envpassthru('git', 'submodule', 'init', callback);
        }, function(callback) {
            envpassthru('git', 'submodule', 'update', callback);
        }
        ], function(error) {
            if (error) process.exit(error);
            mainCallback();
        });
};

var checkoutDependencies = function(mainCallback) {
    console.log('[nodegit] Downloading libgit2 dependency.');
    var commit = 'b70bf922a1de35722904930c42467e95c889562f';
    var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/' + commit + '.zip';
        zipFile = __dirname + '/vendor/libgit2.zip',
        unzippedFolderName = __dirname + '/vendor/libgit2-' + commit,
        targetFolderName = __dirname + '/vendor/libgit2';

    async.waterfall([
        function downloadLibgit2(callback) {
            var ws = fs.createWriteStream(zipFile);
            ws.on('close', function() {
                callback();
            });
            request(libgit2ZipUrl)
                .pipe(ws);
        }, function unzipLibgit2(callback) {
            var zip = new AdmZip(zipFile);
            zip.extractAllTo(__dirname + '/vendor/', true);
            fs.unlink(zipFile);
            callback();
        },
        function renameLibgit2Folder(callback) {
            fs.rename(unzippedFolderName, targetFolderName, callback);
        }
        ], function(error) {
            if (error) process.exit(error);
            mainCallback();
        });
};

var buildDir = path.join(__dirname, 'vendor/libgit2/build');
async.series([
    function(callback) {
        // Check for presence of .git folder
        fs.exists(__dirname + '/.git', function(exists) {
            if (exists) {
                updateSubmodules(callback);
            } else {
                checkoutDependencies(callback);
            }
        });
    },
    function(callback) {
        console.log('[nodegit] Building libgit2 dependency.');
        envpassthru('mkdir', '-p', buildDir, callback);
    },
    function(callback) {
        envpassthru('cmake', '-DTHREADSAFE=1', '-DBUILD_CLAR=0', '..', {
            cwd: buildDir
        }, callback);
    },
    function(callback) {
        envpassthru('cmake', '--build', '.', {
            cwd: buildDir
        }, callback);
    },
    function(callback) {
        console.log('[nodegit] Building native module.');
        shpassthru('node-gyp configure --debug', callback);
        // shpassthru('node-gyp configure', callback);
    },
    function(callback) {
        shpassthru('node-gyp build', callback);
    }
], function(err) {
    if(err) process.exit(err);
});
<|endoftext|>


<commit_before>var fmt = require('./fmt')
var log = require('./utils').log
var trace = require('./utils').trace

var evts = {
	add: 'added',
	change: 'changed',
	unlink: 'removed'
}

module.exports = function () {
	return this
		.on('fly_run', function (obj) {
			log('Flying with ' + fmt.path + '...', obj.path)
		})

		.on('flyfile_not_found', function () {
			process.exitCode = 1
			log('Flyfile not found')
		})

		.on('fly_watch', function () {
			log(fmt.warn.toString(), 'Watching files...')
		})

		.on('fly_watch_event', function (obj) {
			log('File ' + (evts[obj.type] || obj.type.trim()) + ': ' + fmt.warn, obj.file)
		})

		.on('plugin_load', function (obj) {
			log('Loading plugin ' + fmt.title, obj.plugin)
		})

		.on('plugin_error', function (obj) {
			process.exitCode = 1
			log(
				fmt.error + ' failed due to ' + fmt.error,
				obj.plugin, obj.error
			)
		})

		.on('task_error', function (obj) {
			process.exitCode = 1
			trace(obj.error)
			log(
				fmt.error + ' failed due to ' + fmt.error,
				obj.task, obj.error
			)
		})

		.on('task_start', function (obj) {
			log('Starting ' + fmt.start, obj.task)
		})

		.on('task_complete', function (obj) {
			var time = formatTime(obj.duration)
			log(
				'Finished ' + fmt.complete + ' in ' + fmt.secs,
				obj.task, time.duration, time.scale
			)
		})

		.on('task_not_found', function (obj) {
			process.exitCode = 1
			log(fmt.error + ' not found in Flyfile.', obj.task)
		})
}

/**
 * Format the task's time duration
 * @param  {Integer}  time    The task's duration, in ms
 * @param  {String}   unit    The unit of time measurement
 * @return {Object}
 */
function formatTime(time, unit) {
	unit = unit || 'ms'

	if (time >= 1000) {
		time = Math.round((time / 1000) * 10) / 10
		unit = 's'
	}

	return {
		duration: time,
		scale: unit
	}
}
<commit_msg>return formatted string from formatTime()<commit_after>var fmt = require('./fmt')
var log = require('./utils').log
var trace = require('./utils').trace

var evts = {
	add: 'added',
	change: 'changed',
	unlink: 'removed'
}

module.exports = function () {
	return this
		.on('fly_run', function (obj) {
			log('Flying with ' + fmt.path + '...', obj.path)
		})

		.on('flyfile_not_found', function () {
			process.exitCode = 1
			log('Flyfile not found')
		})

		.on('fly_watch', function () {
			log(fmt.warn.toString(), 'Watching files...')
		})

		.on('fly_watch_event', function (obj) {
			log('File ' + (evts[obj.type] || obj.type.trim()) + ': ' + fmt.warn, obj.file)
		})

		.on('plugin_load', function (obj) {
			log('Loading plugin ' + fmt.title, obj.plugin)
		})

		.on('plugin_error', function (obj) {
			process.exitCode = 1
			log(
				fmt.error + ' failed due to ' + fmt.error,
				obj.plugin, obj.error
			)
		})

		.on('task_error', function (obj) {
			process.exitCode = 1
			trace(obj.error)
			log(
				fmt.error + ' failed due to ' + fmt.error,
				obj.task, obj.error
			)
		})

		.on('task_start', function (obj) {
			log('Starting ' + fmt.start, obj.task)
		})

		.on('task_complete', function (obj) {
			var time = formatTime(obj.duration)
			log(
				'Finished ' + fmt.complete + ' in ' + fmt.secs,
				obj.task, time.duration, time.scale
			)
		})

		.on('task_not_found', function (obj) {
			process.exitCode = 1
			log(fmt.error + ' not found in Flyfile.', obj.task)
		})
}

/**
 * Format the task's time duration
 * @param  {Integer}  time    The task's duration, in ms
 * @param  {String}   unit    The unit of time measurement
 * @return {String}
 */
function formatTime(time, unit) {
	unit = unit || 'ms'

	if (time >= 1000) {
		time = Math.round((time / 1000) * 10) / 10
		unit = 's'
	}

	return `${time}${unit}`;
}
<|endoftext|>