<commit_before>'use strict';

var _ = require('lodash');

var utils = require('./utils');
var safeJoin = utils.safeJoin;
var nameRegistry = require('./nameRegistry');
var NameRegistry = nameRegistry.NameRegistry;
var constants = require('./constants');
var PRIMITIVE_TYPES = constants.PRIMITIVE_TYPES;

module.exports = Object.freeze({
  map: map
});

function registryFactory() {
  return new NameRegistry();
}

function map(schema, cb) {
  if (_.isString(schema)) schema = JSON.parse(schema);

  var registry = registryFactory();
  var mapped = schema.map(function(entry) {
    var parent = schema;
    var keyChain = [];
    var typeChain = [];
    var namespace = '';

    return mapRecursive(
      cb, registry, namespace, typeChain, keyChain, parent, entry
    );
  });

  return mapped;
}

function mapRecursive(
  cb, registry, namespace, typeChain, keyChain, parent, entryOrName
) {
  var representative = registry.representative(namespace, entryOrName);
  var nameDescriptor;
  var entry;
  var mapped;
  var recursables;

  if (registry.isRegisterable(entryOrName)) {
    nameDescriptor = registry.add(namespace, entryOrName, {entry: entryOrName});
    typeChain = typeChain.concat(nameDescriptor.representative);
    namespace = nameDescriptor.namespace;
  }

  if (registry.has(namespace, representative)) {
    if (typeChain.indexOf(representative) !== -1)
      return;

    entry = registry.get(namespace, representative);
  } else
    throw new Error('Undefined type');

  mapped = cb(entry, keyChain.slice(0), parent, namespace);
  recursables = getRecursables(entry.type)(keyChain.slice(0), entry);

  return recursables.map(function(r) {
    return mapRecursive(
      cb, registry, namespace, typeChain, r.keyChain, mapped, r.entry
    );
  });
}

function getRecursables(type) {

}

function recordRecurse(keyChain, entry) {
  return (entry.fields || []).map(function(fieldEntry) {
    var childPath = keyChain.concat(fieldEntry.name);

    return {keyChain: childPath, entry: fieldEntry};
  });
}

function enumRecurse() {
  return [];
}

function arrayRecurse(keyChain, entry) {
  var childPath = keyChain.concat('$index');

  return {keyChain: childPath, entry: entry.items};
}

function mapRecurse(keyChain, entry) {
  var childPath = keyChain.concat('$key');

  return {keyChain: childPath, entry: entry.values};
}

function unionRecurse(keyChain, record) {
  return entry.map(function(unionMember) {
    return {keyChain: keyChain.slice(0), entry: unionMember};
  });
}

function fixedRecurse(keyChain, record) {
  return [];
}

function primitiveRecurse(keyChain, record) {
  return [];
}

// function suspendedTree(treeRoot, treeTemplate) {
//   treeRoot.suspended = true;
//   treeRoot.suspendedRef = treeTemplate;

//   return treeRoot;
// }

// function specializeTreeToPath(parent, keyChain, tree) {
//   var oldPathPrefix = new RegExp('^' + tree.path.replace(/\./g, '\\.'));
//   var newPathPrefix = safeJoin(keyChain, '.');
//   var specialized = tree.preOrderMap(function(t) {
//     var data = _.cloneDeep(_.omit(t, ['parent', 'children']));
//     var specialT = treeFactory(null, data);

//     specialT.path = newPathPrefix + specialT.path.replace(oldPathPrefix, '');

//     return specialT;
//   }, parent);

//   specialized.key = _.last(keyChain);

//   return specialized;
// }

function isPrimitiveType(val) {
  return PRIMITIVE_TYPES.hasOwnProperty(val);
}
<commit_msg>* slight changes<commit_after>'use strict';

var _ = require('lodash');

var utils = require('./utils');
var safeJoin = utils.safeJoin;
var nameRegistry = require('./nameRegistry');
var NameRegistry = nameRegistry.NameRegistry;
var constants = require('./constants');
var PRIMITIVE_TYPES = constants.PRIMITIVE_TYPES;

module.exports = Object.freeze({
  map: map
});

function registryFactory() {
  return new NameRegistry();
}

function map(schema, cb) {
  if (_.isString(schema)) schema = JSON.parse(schema);

  var registry = registryFactory();

  return schema.map(function(entry) {
    var parent = schema;
    var keyChain = [];
    var typeChain = [];
    var namespace = '';

    return mapRecursive(
      cb, registry, namespace, typeChain, keyChain, parent, entry
    );
  });
}

function mapRecursive(
  cb, registry, namespace, typeChain, keyChain, parent, entryOrName
) {
  var representative = registry.representative(namespace, entryOrName);
  var entry = entryOrName;
  var nameDescriptor;
  var mapped;

  if (registry.isRegisterable(entryOrName)) {
    nameDescriptor = registry.add(namespace, entryOrName, {entry: entryOrName});
    typeChain = typeChain.concat(nameDescriptor.representative);
    namespace = nameDescriptor.namespace;
  }

  if (registry.has(namespace, representative)) {
    if (typeChain.indexOf(representative) !== -1)
      return;

    entry = registry.get(namespace, representative);
  } else
    throw new Error('Undefined type');

  mapped = cb(entry, keyChain.slice(0), parent, namespace);

  return getRecursables(entry).map(function(r) {
    var _keyChain = keyChain.concat(r.key || []);
    return mapRecursive(
      cb, registry, namespace, typeChain, _keyChain, mapped, r.entry
    );
  });
}

function getRecursables(entry) {
  // entry.type
}

function recordRecurse(entry) {
  return (entry.fields || []).map(function(fieldEntry) {
    return {key: fieldEntry.name, entry: fieldEntry};
  });
}

function enumRecurse() {
  return [];
}

function arrayRecurse(entry) {
  return {key: '$index', entry: entry.items};
}

function mapRecurse(entry) {
  return {key: '$key', entry: entry.values};
}

function unionRecurse(entry) {
  return entry.map(function(unionMember, idx) {
    return {key: '$member' + idx, entry: unionMember};
  });
}

function fixedRecurse() {
  return [];
}

function primitiveRecurse() {
  return [];
}

// function suspendedTree(treeRoot, treeTemplate) {
//   treeRoot.suspended = true;
//   treeRoot.suspendedRef = treeTemplate;

//   return treeRoot;
// }

// function specializeTreeToPath(parent, keyChain, tree) {
//   var oldPathPrefix = new RegExp('^' + tree.path.replace(/\./g, '\\.'));
//   var newPathPrefix = safeJoin(keyChain, '.');
//   var specialized = tree.preOrderMap(function(t) {
//     var data = _.cloneDeep(_.omit(t, ['parent', 'children']));
//     var specialT = treeFactory(null, data);

//     specialT.path = newPathPrefix + specialT.path.replace(oldPathPrefix, '');

//     return specialT;
//   }, parent);

//   specialized.key = _.last(keyChain);

//   return specialized;
// }

function isPrimitiveType(val) {
  return PRIMITIVE_TYPES.hasOwnProperty(val);
}
<|endoftext|>


<commit_before>require('babel-register');
const program = require('commander');
const commands = require('./commands');
const blacklist = require('./helpers/blacklist');

program
  .version('0.4.0');

program
  .command('route [route]>')
  .description('Create a route and all its boilerplate code.')
  .option('-c, --component <component>', 'Specify a custom React component.')
  .option('-d, --delete', 'Delete an existing route.')
  .option('-l, --list', 'List all registered application routes, optionally providing a parent path to check child routes.')
  .action((route, options) => {
    if (options.list) {
      commands.list(route);
      return;
    }
    if (blacklist.test(route)) {
      return;
    }
    const component = typeof options.component === 'undefined'
      ? ''
      : options.component;
    if (options.delete) {
      commands.remove(route);
      return;
    }

    commands.create(route, component);
  });

program
  .command('user <action> <username> [password] [role]')
  .description('Manage user accounts.')
  .action((action, username, password, role) => {
    switch (action) {
      case 'create': {
        const works = false;
        if (works === false) {
          console.log('user methods not available: https://github.com/austingray/reaxpress/issues/8');
          return;
        }
        if (typeof password === 'undefined') {
          console.log('You must provide a password.');
          return;
        }
        commands.user.create(username, password, role, () => {
          process.exit(1);
        });
        break;
      }
      case 'delete': {
        console.log('Coming soon...');
        process.exit(1);
        break;
      }
      default: {
        console.log('Did not recognize the command.');
        process.exit(1);
        break;
      }
    }
  });

program
  .command('model <name>')
  .description('Generate a boilerplate model methods file and add it to the models registry')
  .action((name) => {
    commands.model(name);
  });

program.parse(process.argv);
process.exit(1);
<commit_msg>cli should fail when trying to create a regex route without a named component<commit_after>require('babel-register');
const program = require('commander');
const commands = require('./commands');
const blacklist = require('./helpers/blacklist');

program
  .version('0.4.0');

program
  .command('route [route]>')
  .description('Create a route and all its boilerplate code.')
  .option('-c, --component <component>', 'Specify a custom React component.')
  .option('-d, --delete', 'Delete an existing route.')
  .option('-l, --list', 'List all registered application routes, optionally providing a parent path to check child routes.')
  .action((route, options) => {
    // list all routes
    if (options.list) {
      commands.list(route);
      return;
    }

    // bail if route is blacklisted
    if (blacklist.test(route)) {
      return;
    }

    // delete route
    if (options.delete) {
      commands.remove(route);
      return;
    }

    // parse component option
    const component = typeof options.component === 'undefined'
      ? ''
      : options.component;

    // bail if route has any non-alpha characters and no named component
    if (!/^[a-zA-Z]*$/.test(route) && component === '') {
      console.log('Regex routes must have a named react component. Use --component=CustomName');
      return;
    }

    // perform route creation
    commands.create(route, component);
  });

program
  .command('user <action> <username> [password] [role]')
  .description('Manage user accounts.')
  .action((action, username, password, role) => {
    switch (action) {
      case 'create': {
        const works = false;
        if (works === false) {
          console.log('user methods not available: https://github.com/austingray/reaxpress/issues/8');
          return;
        }
        if (typeof password === 'undefined') {
          console.log('You must provide a password.');
          return;
        }
        commands.user.create(username, password, role, () => {
          process.exit(1);
        });
        break;
      }
      case 'delete': {
        console.log('Coming soon...');
        process.exit(1);
        break;
      }
      default: {
        console.log('Did not recognize the command.');
        process.exit(1);
        break;
      }
    }
  });

program
  .command('model <name>')
  .description('Generate a boilerplate model methods file and add it to the models registry')
  .action((name) => {
    commands.model(name);
  });

program.parse(process.argv);
process.exit(1);
<|endoftext|>


<commit_before>define(['map/clientlayer', 'map/labelslayer',
  'leaflet', 'moment', 'locationmarker', 'rbush', 'helper',
  'leaflet.label'],
  function (ClientLayer, LabelsLayer, L, moment, LocationMarker, rbush, helper) {
    'use strict';

    var options = {
      worldCopyJump: true,
      zoomControl: false
    };

    var LocateButton = L.Control.extend({
      options: {
        position: 'bottomright'
      },

      active: false,
      button: undefined,

      initialize: function (f, o) {
        L.Util.setOptions(this, o);
        this.f = f;
      },

      onAdd: function () {
        var button = L.DomUtil.create('button', 'ion-android-locate shadow');
        L.DomEvent.disableClickPropagation(button);
        L.DomEvent.addListener(button, 'click', this.onClick, this);

        this.button = button;

        return button;
      },

      update: function () {
        this.button.classList.toggle('active', this.active);
      },

      set: function (v) {
        this.active = v;
        this.update();
      },

      onClick: function () {
        this.f(!this.active);
      }
    });

    var CoordsPickerButton = L.Control.extend({
      options: {
        position: 'bottomright'
      },

      active: false,
      button: undefined,

      initialize: function (f, o) {
        L.Util.setOptions(this, o);
        this.f = f;
      },

      onAdd: function () {
        var button = L.DomUtil.create('button', 'ion-pin shadow');

        // Click propagation isn't disabled as this causes problems with the
        // location picking mode; instead propagation is stopped in onClick().
        L.DomEvent.addListener(button, 'click', this.onClick, this);

        this.button = button;

        return button;
      },

      update: function () {
        this.button.classList.toggle('active', this.active);
      },

      set: function (v) {
        this.active = v;
        this.update();
      },

      onClick: function (e) {
        L.DomEvent.stopPropagation(e);
        this.f(!this.active);
      }

    });

    function mkMarker(dict, iconFunc, router) {
      return function (d) {
        var m = L.circleMarker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], iconFunc(d));

        m.resetStyle = function resetStyle() {
          m.setStyle(iconFunc(d));
        };

        m.on('click', router.node(d));
        m.bindLabel(d.nodeinfo.hostname);

        dict[d.nodeinfo.node_id] = m;

        return m;
      };
    }

    function addLinksToMap(dict, linkScale, graph, router) {
      graph = graph.filter(function (d) {
        return 'distance' in d && d.type !== 'VPN';
      });

      return graph.map(function (d) {
        var opts = {
          color: d.type === 'Kabel' ? '#50B0F0' : linkScale(d.tq).hex(),
          weight: 4,
          opacity: 0.5,
          dashArray: 'none'
        };

        var line = L.polyline(d.latlngs, opts);

        line.resetStyle = function resetStyle() {
          line.setStyle(opts);
        };

        line.bindLabel(d.source.node.nodeinfo.hostname + ' – ' + d.target.node.nodeinfo.hostname + '
' + helper.showDistance(d) + ' / ' + helper.showTq(d) + '');
        line.on('click', router.link(d));

        dict[d.id] = line;

        return line;
      });
    }

    var iconOnline = {
      color: '#1566A9',
      fillColor: '#1566A9',
      radius: 6,
      fillOpacity: 0.5,
      opacity: 0.5,
      weight: 2,
      className: 'stroke-first'
    };
    var iconOffline = {
      color: '#D43E2A',
      fillColor: '#D43E2A',
      radius: 3,
      fillOpacity: 0.5,
      opacity: 0.5,
      weight: 1,
      className: 'stroke-first'
    };
    var iconLost = {
      color: '#D43E2A',
      fillColor: '#D43E2A',
      radius: 4,
      fillOpacity: 0.8,
      opacity: 0.8,
      weight: 1,
      className: 'stroke-first'
    };
    var iconAlert = {
      color: '#D43E2A',
      fillColor: '#D43E2A',
      radius: 5,
      fillOpacity: 0.8,
      opacity: 0.8,
      weight: 2,
      className: 'stroke-first'
    };
    var iconNew = { color: '#1566A9', fillColor: '#93E929', radius: 6, fillOpacity: 1.0, opacity: 0.5, weight: 2 };

    return function (config, linkScale, sidebar, router, buttons) {
      var self = this;
      var barycenter;
      var groupOnline;
      var groupOffline;
      var groupNew;
      var groupLost;
      var groupLines;
      var savedView;

      var map;
      var userLocation;
      var layerControl;
      var baseLayers = {};

      var locateUserButton = new LocateButton(function (d) {
        if (d) {
          enableTracking();
        } else {
          disableTracking();
        }
      });

      var mybuttons = [];

      function addButton(button) {
        var el = button.onAdd();
        mybuttons.push(el);
        buttons.appendChild(el);
      }

      function clearButtons() {
        mybuttons.forEach(function (d) {
          buttons.removeChild(d);
        });
      }

      var showCoordsPickerButton = new CoordsPickerButton(function (d) {
        if (d) {
          enableCoords();
        } else {
          disableCoords();
        }
      });

      function saveView() {
        savedView = {
          center: map.getCenter(),
          zoom: map.getZoom()
        };
      }

      function enableTracking() {
        map.locate({
          watch: true,
          enableHighAccuracy: true,
          setView: true
        });
        locateUserButton.set(true);
      }

      function disableTracking() {
        map.stopLocate();
        locationError();
        locateUserButton.set(false);
      }

      function enableCoords() {
        map.getContainer().classList.add('pick-coordinates');
        map.on('click', showCoordinates);
        showCoordsPickerButton.set(true);
      }

      function disableCoords() {
        map.getContainer().classList.remove('pick-coordinates');
        map.off('click', showCoordinates);
        showCoordsPickerButton.set(false);
      }

      function showCoordinates(e) {
        router.gotoLocation(e.latlng);
        disableCoords();
      }

      function locationFound(e) {
        if (!userLocation) {
          userLocation = new LocationMarker(e.latlng).addTo(map);
        }

        userLocation.setLatLng(e.latlng);
        userLocation.setAccuracy(e.accuracy);
      }

      function locationError() {
        if (userLocation) {
          map.removeLayer(userLocation);
          userLocation = null;
        }
      }

      function contextMenuOpenLayerMenu() {
        document.querySelector('.leaflet-control-layers').classList.add('leaflet-control-layers-expanded');
      }

      var el = document.createElement('div');
      el.classList.add('map');

      map = L.map(el, options);
      var now = new Date();
      config.mapLayers.forEach(function (item, i) {
        if ((typeof item.config.start === 'number' && item.config.start <= now.getHours()) || (typeof item.config.end === 'number' && item.config.end > now.getHours())) {
          item.config.order = item.config.start * -1;
        } else {
          item.config.order = i;
        }
      });

      config.mapLayers = config.mapLayers.sort(function (a, b) {
        return a.config.order - b.config.order;
      });

      var layers = config.mapLayers.map(function (d) {
        return {
          'name': d.name,
          'layer': 'url' in d ? L.tileLayer(d.url.replace('{retina}', L.Browser.retina ? '@2x' : ''), d.config) : console.warn('Missing map url')
        };
      });

      layers[0].layer.addTo(map);

      layers.forEach(function (d) {
        baseLayers[d.name] = d.layer;
      });

      map.on('locationfound', locationFound);
      map.on('locationerror', locationError);
      map.on('dragend', saveView);
      map.on('contextmenu', contextMenuOpenLayerMenu);

      addButton(locateUserButton);
      addButton(showCoordsPickerButton);

      layerControl = L.control.layers(baseLayers, [], { position: 'bottomright' });
      layerControl.addTo(map);

      var clientLayer = new ClientLayer({ minZoom: 15 });
      clientLayer.addTo(map);
      clientLayer.setZIndex(5);

      var labelsLayer = new LabelsLayer({});
      labelsLayer.addTo(map);
      labelsLayer.setZIndex(6);

      map.on('baselayerchange', function (e) {
        map.options.maxZoom = e.layer.options.maxZoom;
        clientLayer.options.maxZoom = map.options.maxZoom;
        labelsLayer.options.maxZoom = map.options.maxZoom;
        if (map.getZoom() > map.options.maxZoom) {
          map.setZoom(map.options.maxZoom);
        }

        var style = document.querySelector('.css-mode:not([media="not"])');
        if (style && e.layer.options.mode !== '' && !style.classList.contains(e.layer.options.mode)) {
          style.media = 'not';
          labelsLayer.updateLayer();
        }
        if (e.layer.options.mode) {
          document.querySelector('.css-mode.' + e.layer.options.mode).media = '';
          labelsLayer.updateLayer();
        }
      });

      var nodeDict = {};
      var linkDict = {};
      var highlight;

      function resetMarkerStyles(nodes, links) {
        Object.keys(nodes).forEach(function (d) {
          nodes[d].resetStyle();
        });

        Object.keys(links).forEach(function (d) {
          links[d].resetStyle();
        });
      }

      function setView(bounds) {
        map.fitBounds(bounds, { paddingTopLeft: [sidebar(), 0], maxZoom: config.nodeZoom });
      }

      function resetZoom() {
        if (barycenter) {
          setView(barycenter.getBounds());
        }
      }

      function goto(m) {
        var bounds;

        if ('getBounds' in m) {
          bounds = m.getBounds();
        } else {
          bounds = L.latLngBounds([m.getLatLng()]);
        }

        setView(bounds);

        return m;
      }

      function updateView(nopanzoom) {
        resetMarkerStyles(nodeDict, linkDict);
        var m;

        if (highlight !== undefined) {
          if (highlight.type === 'node') {
            m = nodeDict[highlight.o.nodeinfo.node_id];

            if (m) {
              m.setStyle({ color: 'orange', weight: 20, fillOpacity: 1, opacity: 0.7, className: 'stroke-first' });
            }
          } else if (highlight.type === 'link') {
            m = linkDict[highlight.o.id];

            if (m) {
              m.setStyle({ weight: 4, opacity: 1, dashArray: '5, 10' });
            }
          }
        }

        if (!nopanzoom) {
          if (m) {
            goto(m);
          } else if (savedView) {
            map.setView(savedView.center, savedView.zoom);
          } else {
            resetZoom();
          }
        }
      }

      function mapRTree(d) {
        var o = [d.nodeinfo.location.latitude, d.nodeinfo.location.longitude,
          d.nodeinfo.location.latitude, d.nodeinfo.location.longitude];

        o.node = d;

        return o;
      }

      self.setData = function setData(data) {
        nodeDict = {};
        linkDict = {};

        if (groupOffline) {
          groupOffline.clearLayers();
        }

        if (groupOnline) {
          groupOnline.clearLayers();
        }

        if (groupNew) {
          groupNew.clearLayers();
        }

        if (groupLost) {
          groupLost.clearLayers();
        }

        if (groupLines) {
          groupLines.clearLayers();
        }

        var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router);
        groupLines = L.featureGroup(lines).addTo(map);

        if (typeof config.fixedCenter === 'undefined') {
          console.error('FixedCenter is required');
        } else {
          barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000);
        }

        var nodesOnline = helper.subtract(data.nodes.all.filter(helper.online), data.nodes.new);
        var nodesOffline = helper.subtract(data.nodes.all.filter(helper.offline), data.nodes.lost);

        var markersOnline = nodesOnline.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function () {
            return iconOnline;
          }, router));

        var markersOffline = nodesOffline.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function () {
            return iconOffline;
          }, router));

        var markersNew = data.nodes.new.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function () {
            return iconNew;
          }, router));

        var markersLost = data.nodes.lost.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function (d) {
            if (d.lastseen.isAfter(moment(data.now).subtract(config.maxAgeAlert, 'days'))) {
              return iconAlert;
            }

            if (d.lastseen.isAfter(moment(data.now).subtract(config.maxAge, 'days'))) {
              return iconLost;
            }
            return null;
          }, router));

        groupOffline = L.featureGroup(markersOffline).addTo(map);
        groupLost = L.featureGroup(markersLost).addTo(map);
        groupOnline = L.featureGroup(markersOnline).addTo(map);
        groupNew = L.featureGroup(markersNew).addTo(map);

        var rtreeOnlineAll = rbush(9);

        rtreeOnlineAll.load(data.nodes.all.filter(helper.online).filter(helper.hasLocation).map(mapRTree));

        clientLayer.setData(rtreeOnlineAll);
        labelsLayer.setData({
          online: nodesOnline.filter(helper.hasLocation),
          offline: nodesOffline.filter(helper.hasLocation),
          new: data.nodes.new.filter(helper.hasLocation),
          lost: data.nodes.lost.filter(helper.hasLocation)
        });

        updateView(true);
      };

      self.resetView = function resetView() {
        disableTracking();
        highlight = undefined;
        updateView();
      };

      self.gotoNode = function gotoNode(d, update) {
        disableTracking();
        highlight = { type: 'node', o: d };
        updateView(update);
      };

      self.gotoLink = function gotoLink(d, update) {
        disableTracking();
        highlight = { type: 'link', o: d };
        updateView(update);
      };

      self.gotoLocation = function gotoLocation() {
        // ignore
      };

      self.destroy = function destroy() {
        clearButtons();
        map.remove();

        if (el.parentNode) {
          el.parentNode.removeChild(el);
        }
      };

      self.render = function render(d) {
        d.appendChild(el);
        map.invalidateSize();
      };

      return self;
    };
  });
<commit_msg>[TASK] Change style in webkit correctly<commit_after>define(['map/clientlayer', 'map/labelslayer',
  'leaflet', 'moment', 'locationmarker', 'rbush', 'helper',
  'leaflet.label'],
  function (ClientLayer, LabelsLayer, L, moment, LocationMarker, rbush, helper) {
    'use strict';

    var options = {
      worldCopyJump: true,
      zoomControl: false
    };

    var LocateButton = L.Control.extend({
      options: {
        position: 'bottomright'
      },

      active: false,
      button: undefined,

      initialize: function (f, o) {
        L.Util.setOptions(this, o);
        this.f = f;
      },

      onAdd: function () {
        var button = L.DomUtil.create('button', 'ion-android-locate shadow');
        L.DomEvent.disableClickPropagation(button);
        L.DomEvent.addListener(button, 'click', this.onClick, this);

        this.button = button;

        return button;
      },

      update: function () {
        this.button.classList.toggle('active', this.active);
      },

      set: function (v) {
        this.active = v;
        this.update();
      },

      onClick: function () {
        this.f(!this.active);
      }
    });

    var CoordsPickerButton = L.Control.extend({
      options: {
        position: 'bottomright'
      },

      active: false,
      button: undefined,

      initialize: function (f, o) {
        L.Util.setOptions(this, o);
        this.f = f;
      },

      onAdd: function () {
        var button = L.DomUtil.create('button', 'ion-pin shadow');

        // Click propagation isn't disabled as this causes problems with the
        // location picking mode; instead propagation is stopped in onClick().
        L.DomEvent.addListener(button, 'click', this.onClick, this);

        this.button = button;

        return button;
      },

      update: function () {
        this.button.classList.toggle('active', this.active);
      },

      set: function (v) {
        this.active = v;
        this.update();
      },

      onClick: function (e) {
        L.DomEvent.stopPropagation(e);
        this.f(!this.active);
      }

    });

    function mkMarker(dict, iconFunc, router) {
      return function (d) {
        var m = L.circleMarker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], iconFunc(d));

        m.resetStyle = function resetStyle() {
          m.setStyle(iconFunc(d));
        };

        m.on('click', router.node(d));
        m.bindLabel(d.nodeinfo.hostname);

        dict[d.nodeinfo.node_id] = m;

        return m;
      };
    }

    function addLinksToMap(dict, linkScale, graph, router) {
      graph = graph.filter(function (d) {
        return 'distance' in d && d.type !== 'VPN';
      });

      return graph.map(function (d) {
        var opts = {
          color: d.type === 'Kabel' ? '#50B0F0' : linkScale(d.tq).hex(),
          weight: 4,
          opacity: 0.5,
          dashArray: 'none'
        };

        var line = L.polyline(d.latlngs, opts);

        line.resetStyle = function resetStyle() {
          line.setStyle(opts);
        };

        line.bindLabel(d.source.node.nodeinfo.hostname + ' – ' + d.target.node.nodeinfo.hostname + '
' + helper.showDistance(d) + ' / ' + helper.showTq(d) + '');
        line.on('click', router.link(d));

        dict[d.id] = line;

        return line;
      });
    }

    var iconOnline = {
      color: '#1566A9',
      fillColor: '#1566A9',
      radius: 6,
      fillOpacity: 0.5,
      opacity: 0.5,
      weight: 2,
      className: 'stroke-first'
    };
    var iconOffline = {
      color: '#D43E2A',
      fillColor: '#D43E2A',
      radius: 3,
      fillOpacity: 0.5,
      opacity: 0.5,
      weight: 1,
      className: 'stroke-first'
    };
    var iconLost = {
      color: '#D43E2A',
      fillColor: '#D43E2A',
      radius: 4,
      fillOpacity: 0.8,
      opacity: 0.8,
      weight: 1,
      className: 'stroke-first'
    };
    var iconAlert = {
      color: '#D43E2A',
      fillColor: '#D43E2A',
      radius: 5,
      fillOpacity: 0.8,
      opacity: 0.8,
      weight: 2,
      className: 'stroke-first'
    };
    var iconNew = { color: '#1566A9', fillColor: '#93E929', radius: 6, fillOpacity: 1.0, opacity: 0.5, weight: 2 };

    return function (config, linkScale, sidebar, router, buttons) {
      var self = this;
      var barycenter;
      var groupOnline;
      var groupOffline;
      var groupNew;
      var groupLost;
      var groupLines;
      var savedView;

      var map;
      var userLocation;
      var layerControl;
      var baseLayers = {};

      var locateUserButton = new LocateButton(function (d) {
        if (d) {
          enableTracking();
        } else {
          disableTracking();
        }
      });

      var mybuttons = [];

      function addButton(button) {
        var el = button.onAdd();
        mybuttons.push(el);
        buttons.appendChild(el);
      }

      function clearButtons() {
        mybuttons.forEach(function (d) {
          buttons.removeChild(d);
        });
      }

      var showCoordsPickerButton = new CoordsPickerButton(function (d) {
        if (d) {
          enableCoords();
        } else {
          disableCoords();
        }
      });

      function saveView() {
        savedView = {
          center: map.getCenter(),
          zoom: map.getZoom()
        };
      }

      function enableTracking() {
        map.locate({
          watch: true,
          enableHighAccuracy: true,
          setView: true
        });
        locateUserButton.set(true);
      }

      function disableTracking() {
        map.stopLocate();
        locationError();
        locateUserButton.set(false);
      }

      function enableCoords() {
        map.getContainer().classList.add('pick-coordinates');
        map.on('click', showCoordinates);
        showCoordsPickerButton.set(true);
      }

      function disableCoords() {
        map.getContainer().classList.remove('pick-coordinates');
        map.off('click', showCoordinates);
        showCoordsPickerButton.set(false);
      }

      function showCoordinates(e) {
        router.gotoLocation(e.latlng);
        disableCoords();
      }

      function locationFound(e) {
        if (!userLocation) {
          userLocation = new LocationMarker(e.latlng).addTo(map);
        }

        userLocation.setLatLng(e.latlng);
        userLocation.setAccuracy(e.accuracy);
      }

      function locationError() {
        if (userLocation) {
          map.removeLayer(userLocation);
          userLocation = null;
        }
      }

      function contextMenuOpenLayerMenu() {
        document.querySelector('.leaflet-control-layers').classList.add('leaflet-control-layers-expanded');
      }

      var el = document.createElement('div');
      el.classList.add('map');

      map = L.map(el, options);
      var now = new Date();
      config.mapLayers.forEach(function (item, i) {
        if ((typeof item.config.start === 'number' && item.config.start <= now.getHours()) || (typeof item.config.end === 'number' && item.config.end > now.getHours())) {
          item.config.order = item.config.start * -1;
        } else {
          item.config.order = i;
        }
      });

      config.mapLayers = config.mapLayers.sort(function (a, b) {
        return a.config.order - b.config.order;
      });

      var layers = config.mapLayers.map(function (d) {
        return {
          'name': d.name,
          'layer': 'url' in d ? L.tileLayer(d.url.replace('{retina}', L.Browser.retina ? '@2x' : ''), d.config) : console.warn('Missing map url')
        };
      });

      layers[0].layer.addTo(map);

      layers.forEach(function (d) {
        baseLayers[d.name] = d.layer;
      });

      map.on('locationfound', locationFound);
      map.on('locationerror', locationError);
      map.on('dragend', saveView);
      map.on('contextmenu', contextMenuOpenLayerMenu);

      addButton(locateUserButton);
      addButton(showCoordsPickerButton);

      layerControl = L.control.layers(baseLayers, [], { position: 'bottomright' });
      layerControl.addTo(map);

      var clientLayer = new ClientLayer({ minZoom: 15 });
      clientLayer.addTo(map);
      clientLayer.setZIndex(5);

      var labelsLayer = new LabelsLayer({});
      labelsLayer.addTo(map);
      labelsLayer.setZIndex(6);

      map.on('baselayerchange', function (e) {
        map.options.maxZoom = e.layer.options.maxZoom;
        clientLayer.options.maxZoom = map.options.maxZoom;
        labelsLayer.options.maxZoom = map.options.maxZoom;
        if (map.getZoom() > map.options.maxZoom) {
          map.setZoom(map.options.maxZoom);
        }

        var style = document.querySelector('.css-mode:not([media="not"])');
        if (style && e.layer.options.mode !== '' && !style.classList.contains(e.layer.options.mode)) {
          style.media = 'not';
          labelsLayer.updateLayer();
        }
        if (e.layer.options.mode) {
          var newStyle = document.querySelector('.css-mode.' + e.layer.options.mode);
          newStyle.media = '';
          newStyle.appendChild(document.createTextNode(''));
          labelsLayer.updateLayer();
        }
      });

      var nodeDict = {};
      var linkDict = {};
      var highlight;

      function resetMarkerStyles(nodes, links) {
        Object.keys(nodes).forEach(function (d) {
          nodes[d].resetStyle();
        });

        Object.keys(links).forEach(function (d) {
          links[d].resetStyle();
        });
      }

      function setView(bounds) {
        map.fitBounds(bounds, { paddingTopLeft: [sidebar(), 0], maxZoom: config.nodeZoom });
      }

      function resetZoom() {
        if (barycenter) {
          setView(barycenter.getBounds());
        }
      }

      function goto(m) {
        var bounds;

        if ('getBounds' in m) {
          bounds = m.getBounds();
        } else {
          bounds = L.latLngBounds([m.getLatLng()]);
        }

        setView(bounds);

        return m;
      }

      function updateView(nopanzoom) {
        resetMarkerStyles(nodeDict, linkDict);
        var m;

        if (highlight !== undefined) {
          if (highlight.type === 'node') {
            m = nodeDict[highlight.o.nodeinfo.node_id];

            if (m) {
              m.setStyle({ color: 'orange', weight: 20, fillOpacity: 1, opacity: 0.7, className: 'stroke-first' });
            }
          } else if (highlight.type === 'link') {
            m = linkDict[highlight.o.id];

            if (m) {
              m.setStyle({ weight: 4, opacity: 1, dashArray: '5, 10' });
            }
          }
        }

        if (!nopanzoom) {
          if (m) {
            goto(m);
          } else if (savedView) {
            map.setView(savedView.center, savedView.zoom);
          } else {
            resetZoom();
          }
        }
      }

      function mapRTree(d) {
        var o = [d.nodeinfo.location.latitude, d.nodeinfo.location.longitude,
          d.nodeinfo.location.latitude, d.nodeinfo.location.longitude];

        o.node = d;

        return o;
      }

      self.setData = function setData(data) {
        nodeDict = {};
        linkDict = {};

        if (groupOffline) {
          groupOffline.clearLayers();
        }

        if (groupOnline) {
          groupOnline.clearLayers();
        }

        if (groupNew) {
          groupNew.clearLayers();
        }

        if (groupLost) {
          groupLost.clearLayers();
        }

        if (groupLines) {
          groupLines.clearLayers();
        }

        var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router);
        groupLines = L.featureGroup(lines).addTo(map);

        if (typeof config.fixedCenter === 'undefined') {
          console.error('FixedCenter is required');
        } else {
          barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000);
        }

        var nodesOnline = helper.subtract(data.nodes.all.filter(helper.online), data.nodes.new);
        var nodesOffline = helper.subtract(data.nodes.all.filter(helper.offline), data.nodes.lost);

        var markersOnline = nodesOnline.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function () {
            return iconOnline;
          }, router));

        var markersOffline = nodesOffline.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function () {
            return iconOffline;
          }, router));

        var markersNew = data.nodes.new.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function () {
            return iconNew;
          }, router));

        var markersLost = data.nodes.lost.filter(helper.hasLocation)
          .map(mkMarker(nodeDict, function (d) {
            if (d.lastseen.isAfter(moment(data.now).subtract(config.maxAgeAlert, 'days'))) {
              return iconAlert;
            }

            if (d.lastseen.isAfter(moment(data.now).subtract(config.maxAge, 'days'))) {
              return iconLost;
            }
            return null;
          }, router));

        groupOffline = L.featureGroup(markersOffline).addTo(map);
        groupLost = L.featureGroup(markersLost).addTo(map);
        groupOnline = L.featureGroup(markersOnline).addTo(map);
        groupNew = L.featureGroup(markersNew).addTo(map);

        var rtreeOnlineAll = rbush(9);

        rtreeOnlineAll.load(data.nodes.all.filter(helper.online).filter(helper.hasLocation).map(mapRTree));

        clientLayer.setData(rtreeOnlineAll);
        labelsLayer.setData({
          online: nodesOnline.filter(helper.hasLocation),
          offline: nodesOffline.filter(helper.hasLocation),
          new: data.nodes.new.filter(helper.hasLocation),
          lost: data.nodes.lost.filter(helper.hasLocation)
        });

        updateView(true);
      };

      self.resetView = function resetView() {
        disableTracking();
        highlight = undefined;
        updateView();
      };

      self.gotoNode = function gotoNode(d, update) {
        disableTracking();
        highlight = { type: 'node', o: d };
        updateView(update);
      };

      self.gotoLink = function gotoLink(d, update) {
        disableTracking();
        highlight = { type: 'link', o: d };
        updateView(update);
      };

      self.gotoLocation = function gotoLocation() {
        // ignore
      };

      self.destroy = function destroy() {
        clearButtons();
        map.remove();

        if (el.parentNode) {
          el.parentNode.removeChild(el);
        }
      };

      self.render = function render(d) {
        d.appendChild(el);
        map.invalidateSize();
      };

      return self;
    };
  });
<|endoftext|>


<commit_before>CanvasRenderer.prototype.findEdges = function(nodeSet) {

	var edges = cy.edges();

	var hashTable = {};
	var adjacentEdges = [];

	for (var i = 0; i < nodeSet.length; i++) {
		hashTable[nodeSet[i]._private.data.id] = nodeSet[i];
	}

	for (var i = 0; i < edges.length; i++) {
		if (hashTable[edges[i]._private.data.source]
			|| hashTable[edges[i]._private.data.target]) {

			adjacentEdges.push(edges[i]);
		}
	}

	return adjacentEdges;
}

	<commit_msg>delete unused code<commit_after><|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.notification.email',
  name: 'SMTPEmailService',

  documentation: 'Implementation of Email Service using SMTP',

  implements: [
    'foam.nanos.NanoService',
    'foam.nanos.notification.email.EmailService'
  ],

  imports: [
    'threadPool?' // Only imported in Java
  ],

  javaImports: [
    'foam.core.ContextAgent',
    'foam.core.X',
    'foam.nanos.pool.FixedThreadPool',
    'org.apache.commons.lang3.StringUtils',
    'org.jtwig.JtwigModel',
    'org.jtwig.JtwigTemplate',
    'org.jtwig.environment.EnvironmentConfiguration',
    'org.jtwig.environment.EnvironmentConfigurationBuilder',
    'org.jtwig.resource.loader.TypedResourceLoader',
    'javax.mail.*',
    'javax.mail.internet.InternetAddress',
    'javax.mail.internet.MimeMessage',
    'java.util.Date',
    'java.util.Properties'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function (cls) {
        cls.extras.push(foam.java.Code.create({
          data:
`private class SMTPAuthenticator extends javax.mail.Authenticator {
  protected String username_;
  protected String password_;

  public SMTPAuthenticator(String username, String password) {
    this.username_ = username;
    this.password_ = password;
  }

  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(this.username_, this.password_);
  }
}

protected Session session_ = null;
protected EnvironmentConfiguration config_ = null;`
        }))
      }
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'host',
      value: '127.0.0.1'
    },
    {
      class: 'String',
      name: 'port',
      value: '25'
    },
    {
      class: 'Boolean',
      name: 'authenticate',
      value: false
    },
    {
      class: 'Boolean',
      name: 'starttls',
      value: false
    },
    {
      class: 'String',
      name: 'username',
      value: null
    },
    {
      class: 'String',
      name: 'password',
      value: null
    }
  ],

  methods: [
    {
      name: 'getConfig',
      javaReturns: 'EnvironmentConfiguration',
      args: [
        {
          name: 'group',
          javaType: 'String'
        }
      ],
      javaCode:
`if ( config_ == null ) {
  config_ = EnvironmentConfigurationBuilder
    .configuration()
    .resources()
    .resourceLoaders()
    .add(new TypedResourceLoader("dao", new DAOResourceLoader(getX(), group)))
    .and().and()
    .build();
}
return config_;`
    },
    {
      name: 'createMimeMessage',
      javaReturns: 'MimeMessage',
      args: [
        {
          name: 'emailMessage',
          javaType: 'foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`try {
  MimeMessage message = new MimeMessage(session_);

  // don't send email if no sender
  String from = emailMessage.getFrom();
  if ( from == null || from.isEmpty() )
    return null;
  message.setFrom(new InternetAddress(from));

  // don't send email if no subject
  String subject = emailMessage.getSubject();
  if ( subject == null || subject.isEmpty() )
    return null;
  message.setSubject(subject);

  // don't send email if no body
  String body = emailMessage.getBody();
  if ( body == null || body.isEmpty() )
    return null;
  message.setContent(body, "text/html; charset=utf-8");

  // don't send email if no recipient
  String[] to = emailMessage.getTo();
  if ( to == null || to.length <= 0 )
    return null;

  if ( to.length == 1 ) {
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to[0], false));
  } else {
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(StringUtils.join(to, ",")));
  }

   // send email even if no CC
   String[] cc = emailMessage.getCc();
   if ( cc != null && cc.length == 1 ) {
     message.setRecipient(Message.RecipientType.CC, new InternetAddress(cc[0], false));
  } else if ( cc != null && cc.length > 1 ) {
    message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(StringUtils.join(cc, ",")));
  }

  // send email even if no BCC
  String[] bcc = emailMessage.getBcc();
  if ( bcc != null && bcc.length == 1 ) {
    message.setRecipient(Message.RecipientType.BCC, new InternetAddress(bcc[0], false));
  } else if ( bcc != null && bcc.length > 1 ) {
    message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(StringUtils.join(bcc, ",")));
  }

  // set date
  message.setSentDate(new Date());
  return message;
} catch (MessagingException e) {
  e.printStackTrace();
  return null;
}`
    },
    {
      name: 'sendEmail',
      args: [
        {
          name: 'emailMessage',
          javaType: 'final foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`((FixedThreadPool) getThreadPool()).submit(getX(), new ContextAgent() {
  @Override
  public void execute(X x) {
    try {
      MimeMessage message = createMimeMessage(emailMessage);
      if ( message == null ) {
        return;
      }

      // send message
      Transport transport = session_.getTransport("smtp");
      transport.connect();
      transport.sendMessage(message, message.getAllRecipients());
      transport.close();
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
});`
    },
    {
      name: 'sendEmailFromTemplate',
      javaCode:
`String group = user != null ? (String) user.getGroup() : null;
EmailTemplate emailTemplate = DAOResourceLoader.findTemplate(getX(), name, group);
if ( emailMessage == null )
  return;

EnvironmentConfiguration config = getConfig(group);
JtwigTemplate template = JtwigTemplate.inlineTemplate(emailTemplate.getBody(), config);
JtwigModel model = JtwigModel.newModel(templateArgs);
emailMessage.setSubject(emailTemplate.getSubject());
emailMessage.setBody(template.render(model));
sendEmail(emailMessage);`
    },
    {
      name: 'start',
      javaReturns: 'void',
      javaCode:
`Properties props = new Properties();
props.setProperty("mail.smtp.auth", authenticate_ ? "true" : "false");
props.setProperty("mail.smtp.starttls.enable", starttls_ ? "true" : "false");
props.setProperty("mail.smtp.host", host_);
props.setProperty("mail.smtp.port", port_);
if ( authenticate_ ) {
  session_ = Session.getInstance(props, new SMTPAuthenticator(getUsername(), getPassword()));
} else {
  session_ = Session.getInstance(props);
}`
    }
  ]
});
<commit_msg>Replaced direct property access calls with getter function calls<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.notification.email',
  name: 'SMTPEmailService',

  documentation: 'Implementation of Email Service using SMTP',

  implements: [
    'foam.nanos.NanoService',
    'foam.nanos.notification.email.EmailService'
  ],

  imports: [
    'threadPool?' // Only imported in Java
  ],

  javaImports: [
    'foam.core.ContextAgent',
    'foam.core.X',
    'foam.nanos.pool.FixedThreadPool',
    'org.apache.commons.lang3.StringUtils',
    'org.jtwig.JtwigModel',
    'org.jtwig.JtwigTemplate',
    'org.jtwig.environment.EnvironmentConfiguration',
    'org.jtwig.environment.EnvironmentConfigurationBuilder',
    'org.jtwig.resource.loader.TypedResourceLoader',
    'javax.mail.*',
    'javax.mail.internet.InternetAddress',
    'javax.mail.internet.MimeMessage',
    'java.util.Date',
    'java.util.Properties'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function (cls) {
        cls.extras.push(foam.java.Code.create({
          data:
`private class SMTPAuthenticator extends javax.mail.Authenticator {
  protected String username_;
  protected String password_;

  public SMTPAuthenticator(String username, String password) {
    this.username_ = username;
    this.password_ = password;
  }

  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(this.username_, this.password_);
  }
}

protected Session session_ = null;
protected EnvironmentConfiguration config_ = null;`
        }))
      }
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'host',
      value: '127.0.0.1'
    },
    {
      class: 'String',
      name: 'port',
      value: '25'
    },
    {
      class: 'Boolean',
      name: 'authenticate',
      value: false
    },
    {
      class: 'Boolean',
      name: 'starttls',
      value: false
    },
    {
      class: 'String',
      name: 'username',
      value: null
    },
    {
      class: 'String',
      name: 'password',
      value: null
    }
  ],

  methods: [
    {
      name: 'getConfig',
      javaReturns: 'EnvironmentConfiguration',
      args: [
        {
          name: 'group',
          javaType: 'String'
        }
      ],
      javaCode:
`if ( config_ == null ) {
  config_ = EnvironmentConfigurationBuilder
    .configuration()
    .resources()
    .resourceLoaders()
    .add(new TypedResourceLoader("dao", new DAOResourceLoader(getX(), group)))
    .and().and()
    .build();
}
return config_;`
    },
    {
      name: 'createMimeMessage',
      javaReturns: 'MimeMessage',
      args: [
        {
          name: 'emailMessage',
          javaType: 'foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`try {
  MimeMessage message = new MimeMessage(session_);

  // don't send email if no sender
  String from = emailMessage.getFrom();
  if ( from == null || from.isEmpty() )
    return null;
  message.setFrom(new InternetAddress(from));

  // don't send email if no subject
  String subject = emailMessage.getSubject();
  if ( subject == null || subject.isEmpty() )
    return null;
  message.setSubject(subject);

  // don't send email if no body
  String body = emailMessage.getBody();
  if ( body == null || body.isEmpty() )
    return null;
  message.setContent(body, "text/html; charset=utf-8");

  // don't send email if no recipient
  String[] to = emailMessage.getTo();
  if ( to == null || to.length <= 0 )
    return null;

  if ( to.length == 1 ) {
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to[0], false));
  } else {
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(StringUtils.join(to, ",")));
  }

   // send email even if no CC
   String[] cc = emailMessage.getCc();
   if ( cc != null && cc.length == 1 ) {
     message.setRecipient(Message.RecipientType.CC, new InternetAddress(cc[0], false));
  } else if ( cc != null && cc.length > 1 ) {
    message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(StringUtils.join(cc, ",")));
  }

  // send email even if no BCC
  String[] bcc = emailMessage.getBcc();
  if ( bcc != null && bcc.length == 1 ) {
    message.setRecipient(Message.RecipientType.BCC, new InternetAddress(bcc[0], false));
  } else if ( bcc != null && bcc.length > 1 ) {
    message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(StringUtils.join(bcc, ",")));
  }

  // set date
  message.setSentDate(new Date());
  return message;
} catch (MessagingException e) {
  e.printStackTrace();
  return null;
}`
    },
    {
      name: 'sendEmail',
      args: [
        {
          name: 'emailMessage',
          javaType: 'final foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`((FixedThreadPool) getThreadPool()).submit(getX(), new ContextAgent() {
  @Override
  public void execute(X x) {
    try {
      MimeMessage message = createMimeMessage(emailMessage);
      if ( message == null ) {
        return;
      }

      // send message
      Transport transport = session_.getTransport("smtp");
      transport.connect();
      transport.sendMessage(message, message.getAllRecipients());
      transport.close();
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
});`
    },
    {
      name: 'sendEmailFromTemplate',
      javaCode:
`String group = user != null ? (String) user.getGroup() : null;
EmailTemplate emailTemplate = DAOResourceLoader.findTemplate(getX(), name, group);
if ( emailMessage == null )
  return;

EnvironmentConfiguration config = getConfig(group);
JtwigTemplate template = JtwigTemplate.inlineTemplate(emailTemplate.getBody(), config);
JtwigModel model = JtwigModel.newModel(templateArgs);
emailMessage.setSubject(emailTemplate.getSubject());
emailMessage.setBody(template.render(model));
sendEmail(emailMessage);`
    },
    {
      name: 'start',
      javaReturns: 'void',
      javaCode:
`Properties props = new Properties();
props.setProperty("mail.smtp.auth", getAuthenticate() ? "true" : "false");
props.setProperty("mail.smtp.starttls.enable", getStarttls() ? "true" : "false");
props.setProperty("mail.smtp.host", getHost());
props.setProperty("mail.smtp.port", getPort());
if ( getAuthenticate() ) {
  session_ = Session.getInstance(props, new SMTPAuthenticator(getUsername(), getPassword()));
} else {
  session_ = Session.getInstance(props);
}`
    }
  ]
});
<|endoftext|>


<commit_before>'use strict';
var qs = require("querystring");
var crypto = require('crypto');
var xml2js = require('xml2js');
var request = require('request');
var _ = require('underscore');
var tls = require('tls');

/**
 * Constructor for the main MWS client interface used to make api calls and
 * various data structures to encapsulate MWS requests, definitions, etc.
 *
 * @param {String} accessKeyId     Id for your secret Access Key (required)
 * @param {String} secretAccessKey Secret Access Key provided by Amazon (required)
 * @param {String} merchantId      Aka SellerId, provided by Amazon (required)
 * @param {Object} options         Additional configuration options for this instance
 */
function AmazonMwsClient(accessKeyId, secretAccessKey, merchantId, options) {
	options = options || {};

	var createCredentials = tls.createSecureContext || crypto.createCredentials;
	this.host = options.host || 'mws.amazonservices.com';
	this.creds = createCredentials(options.creds || {});
	this.appName = options.appName || 'mws-js';
	this.appVersion = options.appVersion || '0.1.0';
	this.appLanguage = options.appLanguage || 'JavaScript';
	this.accessKeyId = accessKeyId || null;
	this.secretAccessKey = secretAccessKey || null;
	this.merchantId = merchantId || null;
	this.authToken = options.authToken;
}

/**
 * The method used to invoke calls against MWS Endpoints. Recommended usage is
 * through the invoke wrapper method when the api call you're invoking has a
 * request defined in one of the submodules. However, you can use call() manually
 * when a lower level of control is necessary (custom or new requests, for example).
 *
 * @param  {Object}   api      Settings object unique to each API submodule
 * @param  {String}   action   Api `Action`, such as GetServiceStatus or GetOrder
 * @param  {Object}   query    Any parameters belonging to the current action
 * @return Promise
 */
AmazonMwsClient.prototype.call = function(api, action, query) {
	if (this.secretAccessKey == null || this.accessKeyId == null || this.merchantId == null) {
		throw "accessKeyId, secretAccessKey, and merchantId must be set";
	}

	var requestOpts = {
		method: 'POST',
		uri: 'https://' + this.host + api.path
	};

	// Check if we're dealing with a file (such as a feed) upload
	if (api.upload) {
		requestOpts.body = query._BODY_;
		requestOpts.headers = {
			'Content-Type': query._FORMAT_,
			'Content-MD5': crypto.createHash('md5').update(query._BODY_).digest('base64')
		};
		delete query._BODY_;
		delete query._FORMAT_;
	}

	// Add required parameters and sign the query
	query['Action'] = action;
	query['Version'] = api.version;
	query["Timestamp"] = new Date().toISOString();
	query["AWSAccessKeyId"] = this.accessKeyId;

	if (this.authToken) {
		query["MWSAuthToken"] = this.authToken;
	}

	if (api.legacy) {
		query['Merchant'] = this.merchantId;
	} else {
		query['SellerId'] = this.merchantId;
	}

	query = this.sign(api.path, query);

	if (!api.upload) {
		requestOpts.form = query;
	} else {
		request.qs = query;
	}

	return new Promise(function(resolve, reject) {
		request(requestOpts, function(err, response, data) {
			if (err) {
				reject(err);
			} else {
				if (data.slice(0, 5) == '<?xml') {
					xml2js.parseString(data, function(err, result) {
						// Throw an error if there was a problem reported
						if (err != null) {
							reject(new Error(err.Code + ": " + err.Message));
						} else {
							resolve(result);
						}
					});
				} else {
					resolve(data);
				}
			}
		});
	});
};

/**
 * Calculates the HmacSHA256 signature and appends it with additional signature
 * parameters to the provided query object.
 *
 * @param  {String} path  Path of API call (used to build the string to sign)
 * @param  {Object} query Any non-signature parameters that will be sent
 * @return {Object}       Finalized object used to build query string of request
 */
AmazonMwsClient.prototype.sign = function(path, query) {
	// Configure the query signature method/version
	query["SignatureMethod"] = "HmacSHA256";
	query["SignatureVersion"] = "2";

	// Copy query keys, sort them, then copy over the values
	var sorted = _.reduce(_.keys(query).sort(), function(m, k) {
		m[k] = query[k];
		return m;
	}, {});

	var stringToSign = ["POST", this.host, path, qs.stringify(sorted)].join("\n");

	query['Signature'] = crypto.createHmac("sha256", this.secretAccessKey).update(stringToSign, 'utf8').digest("base64");

	return query;
};

/**
 * Suggested method for invoking a pre-defined mws request object.
 *
 * @param  {Object}   request  An instance of AmazonMwsRequest with params, etc.
 * @return Promise
 */
AmazonMwsClient.prototype.invoke = function(request) {
	var _this = this;
	return request.query().then(function(q) {
		return _this.call(request.api, request.action, q);
	});
};

/**
 * Constructor for general MWS request objects, wrapped by api submodules to keep
 * things DRY, yet familiar despite whichever api is being implemented.
 *
 * @param {Object} options Settings to apply to new request instance.
 */
function AmazonMwsRequest(options) {
	this.api = {
		path: options.path || '/',
		version: options.version || '2009-01-01',
		legacy: options.legacy || false,
		upload: options.upload
	};
	this.action = options.action || 'GetServiceStatus';
	this.params = options.params || {};
	this.paramsMap = {};

	if(Object.keys(this.params).length > 0){
		for( var name in this.params){
			var realName = this.params[name].name;
			if(name!== this.params[name].name){
				this.paramsMap[name] = realName;
				this.params[realName] = this.params[name];
				delete this.params[name];
			}
		}
	}
}

/**
 * Handles the casting, renaming, and setting of individual request params.
 *
 * @param {String} param Key of parameter (not ALWAYS the same as the param name!)
 * @param {Mixed} value Value to assign to parameter
 * @return {Object} Current instance to allow function chaining
 */
AmazonMwsRequest.prototype.set = function(param, value) {
	if (param instanceof Object && (value === null || value === undefined)) {
		return this.setMultiple(param);
	} else if (value !== null && value !== undefined) {
		var self = this;

		if(this.paramsMap.hasOwnProperty(param)){
				param = this.paramsMap[param];
		}

		var p = this.params[param],
			v = p.value = {};
		// Handles the actual setting based on type
		var setListValue = function setListValue(name, val) {
			if (p.type == 'Timestamp') {
				v[name] = val.toISOString();
			} else if (p.type == 'Boolean') {
				v[name] = val ? 'true' : 'false';
			} else {
				v[name] = val;
			}
		};

		// Handles the actual setting based on type
		var setValue = function setValue(name, val) {
			console.log(name, val)
			if (p.type == 'Timestamp') {
				self.params[name].value = val.toISOString();
			} else if (p.type == 'Boolean') {
				self.params[name].value = val ? 'true' : 'false';
			} else {
				self.params[name].value = val;
			}
		};

		// Lists need to be sequentially numbered and we take care of that here
		if (p.list) {
			var i = 0;
			if (typeof value == "string" || typeof value == "number") {
				setListValue(p.name + '.1', value);
			}
			if (typeof value == "object") {
				if (Array.isArray(value)) {
					for (i = value.length - 1; i >= 0; i--) {
						setListValue(p.name + '.' + (i + 1), value[i]);
					}
				} else {
					for (var key in value) {
						setListValue(p.name + '.' + ++i, value[key]);
					}
				}
			}
		} else {
			setValue(p.name, value);
		}
	}
	return this;
};

AmazonMwsRequest.prototype.setMultiple = function(conf) {
	_.each(conf, (function(value, key) {
		this.set(key, value);
	}).bind(this));

	return this;
};

/**
 * Builds a query object and checks for required parameters.
 *
 * @return {Object} KvP's of all provided parameters (used by invoke())
 */
AmazonMwsRequest.prototype.query = function() {
	var _this = this;
	return new Promise(function(resolve, reject) {
		var q = {};
		var missing = [];
		for (var param in _this.params) {
			var value = _this.params[param].value,
				name = _this.params[param].name,
				complex = _this.params[param].type === 'Complex',
				list = _this.params[param].list,
				required = _this.params[param].required;
			if (value !== undefined && value !== null) {
				if (complex) {
					value.appendTo(q);
				} else if (list) {
					for (var p in value) {
						q[p] = value[p];
					}
				} else {
					q[name] = value;
				}
			} else {
				if (param.required === true) {
					missing.push(name);
				}
			}
		}
		if (missing.length > 0) reject(new Error("ERROR: Missing required parameter(s): " + missing.join(',') + "!"));
		else resolve(q);
	});
};

/**
 * Contructor for objects used to represent enumeration states. Useful
 * when you need to make programmatic updates to an enumerated data type or
 * wish to encapsulate enum states in a handy, re-usable variable.
 *
 * @param {Array} choices An array of any possible values (choices)
 */
function EnumType(choices) {
	for (var choice in choices) {
		this[choices[choice]] = false;
	}
	this._choices = choices;
}

/**
 * Enable one or more choices (accepts a variable number of arguments)
 * @return {Object} Current instance of EnumType for chaining
 */
EnumType.prototype.enable = function() {
	for (var arg in arguments) {
		this[arguments[arg]] = true;
	}
	return this;
};

/**
 * Disable one or more choices (accepts a variable number of arguments)
 * @return {Object} Current instance of EnumType for chaining
 */
EnumType.prototype.disable = function() {
	for (var arg in arguments) {
		this[arguments[arg]] = false;
	}
	return this;
};

/**
 * Toggles one or more choices (accepts a variable number of arguments)
 * @return {Object} Current instance of EnumType for chaining
 */
EnumType.prototype.toggle = function() {
	for (var arg in arguments) {
		this[arguments[arg]] = !this[arguments[arg]];
	}
	return this;
};

/**
 * Return all possible values without regard to current state
 * @return {Array} Choices passed to EnumType constructor
 */
EnumType.prototype.all = function() {
	return this._choices;
};

/**
 * Return all enabled choices as an array (used to set list params, usually)
 * @return {Array} Choice values for each choice set to true
 */
EnumType.prototype.values = function() {
	var value = [];
	for (var choice in this._choices) {
		if (this[this._choices[choice]] === true) {
			value.push(this._choices[choice]);
		}
	}
	return value;
};

// /**
//  * Takes an object and adds an appendTo function that will add
//  * each kvp of object to a query. Used when dealing with complex
//  * parameters that need to be built in an abnormal or unique way.
//  *
//  * @param {String} name Name of parameter, prefixed to each key
//  * @param {Object} obj  Parameters belonging to the complex type
//  */
// function ComplexType(name) {
// 	this.pre = name;
// 	var _obj = obj;
// 	obj.appendTo = function(query) {
// 		for (var k in _obj) {
// 			query[name + '.' k] = _obj[k];
// 		}
// 		return query;
// 	}
// 	return obj;
// }

// ComplexType.prototype.appendTo = function(query) {
// 	for (var k in value)
// }

/**
 * Complex List helper object. Once initialized, you should set
 * an add(args) method which pushes a new complex object to members.
 *
 * @param {String} name Name of Complex Type (including .member or subtype)
 */
function ComplexListType(name) {
	this.pre = name;
	this.members = [];
}

/**
 * Appends each member object as a complex list item
 * @param  {Object} query Query object to append to
 * @return {Object}       query
 */
ComplexListType.prototype.appendTo = function(query) {
	var members = this.members;
	for (var i = 0; i < members.length; i++) {
		for (var j in members[i]) {
			query[this.pre + '.' + (i + 1) + '.' + j] = members[i][j];
		}
	}
	return query;
};

exports.Client = AmazonMwsClient;
exports.Request = AmazonMwsRequest;
exports.Enum = EnumType;
exports.ComplexList = ComplexListType;
exports.Fbs = require('./fba');
exports.Orders = require('./orders');
exports.Sellers = require('./sellers');
exports.Feeds = require('./feeds');
exports.Products = require('./products');
exports.Reports = require('./reports');
<commit_msg>Fix for Issue #5: query._FORMAT_ = undefined<commit_after>'use strict';
var qs = require("querystring");
var crypto = require('crypto');
var xml2js = require('xml2js');
var request = require('request');
var _ = require('underscore');
var tls = require('tls');

/**
 * Constructor for the main MWS client interface used to make api calls and
 * various data structures to encapsulate MWS requests, definitions, etc.
 *
 * @param {String} accessKeyId     Id for your secret Access Key (required)
 * @param {String} secretAccessKey Secret Access Key provided by Amazon (required)
 * @param {String} merchantId      Aka SellerId, provided by Amazon (required)
 * @param {Object} options         Additional configuration options for this instance
 */
function AmazonMwsClient(accessKeyId, secretAccessKey, merchantId, options) {
	options = options || {};

	var createCredentials = tls.createSecureContext || crypto.createCredentials;
	this.host = options.host || 'mws.amazonservices.com';
	this.creds = createCredentials(options.creds || {});
	this.appName = options.appName || 'mws-js';
	this.appVersion = options.appVersion || '0.1.0';
	this.appLanguage = options.appLanguage || 'JavaScript';
	this.accessKeyId = accessKeyId || null;
	this.secretAccessKey = secretAccessKey || null;
	this.merchantId = merchantId || null;
	this.authToken = options.authToken;
}

/**
 * The method used to invoke calls against MWS Endpoints. Recommended usage is
 * through the invoke wrapper method when the api call you're invoking has a
 * request defined in one of the submodules. However, you can use call() manually
 * when a lower level of control is necessary (custom or new requests, for example).
 *
 * @param  {Object}   api      Settings object unique to each API submodule
 * @param  {String}   action   Api `Action`, such as GetServiceStatus or GetOrder
 * @param  {Object}   query    Any parameters belonging to the current action
 * @return Promise
 */
AmazonMwsClient.prototype.call = function(api, action, query) {
	if (this.secretAccessKey == null || this.accessKeyId == null || this.merchantId == null) {
		throw "accessKeyId, secretAccessKey, and merchantId must be set";
	}

	var requestOpts = {
		method: 'POST',
		uri: 'https://' + this.host + api.path
	};

	// Check if we're dealing with a file (such as a feed) upload
	if (api.upload) {
		requestOpts.body = query._BODY_;
		query._FORMAT_ = 'application/x-www-form-urlencoded';
		requestOpts.headers = {
			'Content-Type': query._FORMAT_,
			'Content-MD5': crypto.createHash('md5').update(query._BODY_).digest('base64')
		};
		delete query._BODY_;
		delete query._FORMAT_;
	}

	// Add required parameters and sign the query
	query['Action'] = action;
	query['Version'] = api.version;
	query["Timestamp"] = new Date().toISOString();
	query["AWSAccessKeyId"] = this.accessKeyId;

	if (this.authToken) {
		query["MWSAuthToken"] = this.authToken;
	}

	if (api.legacy) {
		query['Merchant'] = this.merchantId;
	} else {
		query['SellerId'] = this.merchantId;
	}

	query = this.sign(api.path, query);

	if (!api.upload) {
		requestOpts.form = query;
	} else {
		request.qs = query;
	}

	return new Promise(function(resolve, reject) {
		request(requestOpts, function(err, response, data) {
			if (err) {
				reject(err);
			} else {
				if (data.slice(0, 5) == '<?xml') {
					xml2js.parseString(data, function(err, result) {
						// Throw an error if there was a problem reported
						if (err != null) {
							reject(new Error(err.Code + ": " + err.Message));
						} else {
							resolve(result);
						}
					});
				} else {
					resolve(data);
				}
			}
		});
	});
};

/**
 * Calculates the HmacSHA256 signature and appends it with additional signature
 * parameters to the provided query object.
 *
 * @param  {String} path  Path of API call (used to build the string to sign)
 * @param  {Object} query Any non-signature parameters that will be sent
 * @return {Object}       Finalized object used to build query string of request
 */
AmazonMwsClient.prototype.sign = function(path, query) {
	// Configure the query signature method/version
	query["SignatureMethod"] = "HmacSHA256";
	query["SignatureVersion"] = "2";

	// Copy query keys, sort them, then copy over the values
	var sorted = _.reduce(_.keys(query).sort(), function(m, k) {
		m[k] = query[k];
		return m;
	}, {});

	var stringToSign = ["POST", this.host, path, qs.stringify(sorted)].join("\n");

	query['Signature'] = crypto.createHmac("sha256", this.secretAccessKey).update(stringToSign, 'utf8').digest("base64");

	return query;
};

/**
 * Suggested method for invoking a pre-defined mws request object.
 *
 * @param  {Object}   request  An instance of AmazonMwsRequest with params, etc.
 * @return Promise
 */
AmazonMwsClient.prototype.invoke = function(request) {
	var _this = this;
	return request.query().then(function(q) {
		return _this.call(request.api, request.action, q);
	});
};

/**
 * Constructor for general MWS request objects, wrapped by api submodules to keep
 * things DRY, yet familiar despite whichever api is being implemented.
 *
 * @param {Object} options Settings to apply to new request instance.
 */
function AmazonMwsRequest(options) {
	this.api = {
		path: options.path || '/',
		version: options.version || '2009-01-01',
		legacy: options.legacy || false,
		upload: options.upload
	};
	this.action = options.action || 'GetServiceStatus';
	this.params = options.params || {};
	this.paramsMap = {};

	if(Object.keys(this.params).length > 0){
		for( var name in this.params){
			var realName = this.params[name].name;
			if(name!== this.params[name].name){
				this.paramsMap[name] = realName;
				this.params[realName] = this.params[name];
				delete this.params[name];
			}
		}
	}
}

/**
 * Handles the casting, renaming, and setting of individual request params.
 *
 * @param {String} param Key of parameter (not ALWAYS the same as the param name!)
 * @param {Mixed} value Value to assign to parameter
 * @return {Object} Current instance to allow function chaining
 */
AmazonMwsRequest.prototype.set = function(param, value) {
	if (param instanceof Object && (value === null || value === undefined)) {
		return this.setMultiple(param);
	} else if (value !== null && value !== undefined) {
		var self = this;

		if(this.paramsMap.hasOwnProperty(param)){
				param = this.paramsMap[param];
		}

		var p = this.params[param],
			v = p.value = {};
		// Handles the actual setting based on type
		var setListValue = function setListValue(name, val) {
			if (p.type == 'Timestamp') {
				v[name] = val.toISOString();
			} else if (p.type == 'Boolean') {
				v[name] = val ? 'true' : 'false';
			} else {
				v[name] = val;
			}
		};

		// Handles the actual setting based on type
		var setValue = function setValue(name, val) {
			console.log(name, val)
			if (p.type == 'Timestamp') {
				self.params[name].value = val.toISOString();
			} else if (p.type == 'Boolean') {
				self.params[name].value = val ? 'true' : 'false';
			} else {
				self.params[name].value = val;
			}
		};

		// Lists need to be sequentially numbered and we take care of that here
		if (p.list) {
			var i = 0;
			if (typeof value == "string" || typeof value == "number") {
				setListValue(p.name + '.1', value);
			}
			if (typeof value == "object") {
				if (Array.isArray(value)) {
					for (i = value.length - 1; i >= 0; i--) {
						setListValue(p.name + '.' + (i + 1), value[i]);
					}
				} else {
					for (var key in value) {
						setListValue(p.name + '.' + ++i, value[key]);
					}
				}
			}
		} else {
			setValue(p.name, value);
		}
	}
	return this;
};

AmazonMwsRequest.prototype.setMultiple = function(conf) {
	_.each(conf, (function(value, key) {
		this.set(key, value);
	}).bind(this));

	return this;
};

/**
 * Builds a query object and checks for required parameters.
 *
 * @return {Object} KvP's of all provided parameters (used by invoke())
 */
AmazonMwsRequest.prototype.query = function() {
	var _this = this;
	return new Promise(function(resolve, reject) {
		var q = {};
		var missing = [];
		for (var param in _this.params) {
			var value = _this.params[param].value,
				name = _this.params[param].name,
				complex = _this.params[param].type === 'Complex',
				list = _this.params[param].list,
				required = _this.params[param].required;
			if (value !== undefined && value !== null) {
				if (complex) {
					value.appendTo(q);
				} else if (list) {
					for (var p in value) {
						q[p] = value[p];
					}
				} else {
					q[name] = value;
				}
			} else {
				if (param.required === true) {
					missing.push(name);
				}
			}
		}
		if (missing.length > 0) reject(new Error("ERROR: Missing required parameter(s): " + missing.join(',') + "!"));
		else resolve(q);
	});
};

/**
 * Contructor for objects used to represent enumeration states. Useful
 * when you need to make programmatic updates to an enumerated data type or
 * wish to encapsulate enum states in a handy, re-usable variable.
 *
 * @param {Array} choices An array of any possible values (choices)
 */
function EnumType(choices) {
	for (var choice in choices) {
		this[choices[choice]] = false;
	}
	this._choices = choices;
}

/**
 * Enable one or more choices (accepts a variable number of arguments)
 * @return {Object} Current instance of EnumType for chaining
 */
EnumType.prototype.enable = function() {
	for (var arg in arguments) {
		this[arguments[arg]] = true;
	}
	return this;
};

/**
 * Disable one or more choices (accepts a variable number of arguments)
 * @return {Object} Current instance of EnumType for chaining
 */
EnumType.prototype.disable = function() {
	for (var arg in arguments) {
		this[arguments[arg]] = false;
	}
	return this;
};

/**
 * Toggles one or more choices (accepts a variable number of arguments)
 * @return {Object} Current instance of EnumType for chaining
 */
EnumType.prototype.toggle = function() {
	for (var arg in arguments) {
		this[arguments[arg]] = !this[arguments[arg]];
	}
	return this;
};

/**
 * Return all possible values without regard to current state
 * @return {Array} Choices passed to EnumType constructor
 */
EnumType.prototype.all = function() {
	return this._choices;
};

/**
 * Return all enabled choices as an array (used to set list params, usually)
 * @return {Array} Choice values for each choice set to true
 */
EnumType.prototype.values = function() {
	var value = [];
	for (var choice in this._choices) {
		if (this[this._choices[choice]] === true) {
			value.push(this._choices[choice]);
		}
	}
	return value;
};

// /**
//  * Takes an object and adds an appendTo function that will add
//  * each kvp of object to a query. Used when dealing with complex
//  * parameters that need to be built in an abnormal or unique way.
//  *
//  * @param {String} name Name of parameter, prefixed to each key
//  * @param {Object} obj  Parameters belonging to the complex type
//  */
// function ComplexType(name) {
// 	this.pre = name;
// 	var _obj = obj;
// 	obj.appendTo = function(query) {
// 		for (var k in _obj) {
// 			query[name + '.' k] = _obj[k];
// 		}
// 		return query;
// 	}
// 	return obj;
// }

// ComplexType.prototype.appendTo = function(query) {
// 	for (var k in value)
// }

/**
 * Complex List helper object. Once initialized, you should set
 * an add(args) method which pushes a new complex object to members.
 *
 * @param {String} name Name of Complex Type (including .member or subtype)
 */
function ComplexListType(name) {
	this.pre = name;
	this.members = [];
}

/**
 * Appends each member object as a complex list item
 * @param  {Object} query Query object to append to
 * @return {Object}       query
 */
ComplexListType.prototype.appendTo = function(query) {
	var members = this.members;
	for (var i = 0; i < members.length; i++) {
		for (var j in members[i]) {
			query[this.pre + '.' + (i + 1) + '.' + j] = members[i][j];
		}
	}
	return query;
};

exports.Client = AmazonMwsClient;
exports.Request = AmazonMwsRequest;
exports.Enum = EnumType;
exports.ComplexList = ComplexListType;
exports.Fbs = require('./fba');
exports.Orders = require('./orders');
exports.Sellers = require('./sellers');
exports.Feeds = require('./feeds');
exports.Products = require('./products');
exports.Reports = require('./reports');
<|endoftext|>


<commit_before>const program = require('commander');

program
    .version('1.0.0')
    .option('-p, --port <port>', 'specify the websocket port to listen to [9872]', 9872)
    .parse(process.argv);

const io = require('socket.io-client'),
      winston = require('winston'),
      config = require('./config.js');

winston.level = 'debug';
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {'timestamp': true});

const PORT = program.port;
const SERVICES = config.services;

const ROOMID = 'room1';

winston.info('Unichat matchmaker service');
winston.info('Listening on port ' + PORT);

let serviceSockets = [];
for (var i=0; i < SERVICES.length; i++) {
    let _url = SERVICES[i].url;
    let _type = SERVICES[i].type;

    let _socket = io.connect(_url, {'forceNew': true});

    _socket.on('connect', () => {
        winston.debug('Connected to ' + _type + ' service at ' + _url);
        _socket.emit('register-matchmaker');
    });

    _socket.on('presence-find-partner', (cookieId) => {
        winston.debug('Finding partner for client with cookie: ' + cookieId);
        _socket.emit('matchmaker-send-to-room', cookieId, ROOMID);
        winston.debug('Sent client with cookie (' + cookieId + ') to room: ' + ROOMID);
    });

    serviceSockets.push(_socket);
}
<commit_msg>Add presenceToUse, realtimeToUse to matchmaker<commit_after>const program = require('commander');

program
    .version('1.0.0')
    .option('-p, --port <port>', 'specify the websocket port to listen to [9872]', 9872)
    .parse(process.argv);

const io = require('socket.io-client'),
      winston = require('winston'),
      config = require('./config.js');

winston.level = 'debug';
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {'timestamp': true});

const PORT = program.port;
const SERVICES = config.services;

const ROOMID = 'room1';

winston.info('Unichat matchmaker service');
winston.info('Listening on port ' + PORT);

let serviceSockets = [];
let presenceToUse = '';
let realtimeToUse = '';
for (var i=0; i < SERVICES.length; i++) {
    let _url = SERVICES[i].url;
    let _type = SERVICES[i].type;

    let _socket = io.connect(_url, {'forceNew': true});

    _socket.on('connect', () => {
        winston.debug('Connected to ' + _type + ' service at ' + _url);
        _socket.emit('register-matchmaker');
    });

    _socket.on('presence-find-partner', (cookieId) => {
        winston.debug('Finding partner for client with cookie: ' + cookieId);
        _socket.emit('matchmaker-send-to-room', cookieId, ROOMID);
        winston.debug('Sent client with cookie (' + cookieId + ') to room: ' + ROOMID);
    });

    serviceSockets.push(_socket);

    // Define the primary presence/realtime service that traffic is directed at
    if (_type == 'presence') {
        presenceToUse = {'socket': _socket, 'url': _url};
        winston.debug('Presence to use: ' + presenceToUse.url);
    }
    else {
        realtimeToUse = {'socket': _socket, 'url': _url};
        winston.debug('Realtime to use: ' + realtimeToUse.url);
    }
}
<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/defaultValue',
        '../Core/DeveloperError',
        './TerrainState',
        './Tile',
        './TileState',
        './TileTerrain',
        '../ThirdParty/when'
    ], function(
        defaultValue,
        DeveloperError,
        TerrainState,
        Tile,
        TileState,
        TileTerrain,
        when) {
    "use strict";

    /**
     * Provides an elevation query for an array of Cartographic points by
     * requesting tiles from a terrain provider, sampling and interpolating.
     * Each point height is modified in place.
     */
    var terrainSample = function(terrainProvider, level, pts) {
        level = defaultValue(level, 2);

        var tilingScheme = terrainProvider.getTilingScheme();

        var i;

        // Sort points into a set of tiles
        var tileRequests = []; // Result will be an Array as it's easier to work with
        {
            var tileRequestSet = {}; // A unique set
            for (i = 0; i < pts.length; ++i) {
                var xy = tilingScheme.positionToTileXY(pts[i], level);
                var key = xy.toString();

                if (!tileRequestSet.hasOwnProperty(key)) {
                    // When tile is requested for the first time
                    var value = {
                        x : xy.x,
                        y : xy.y,
                        level : level,
                        tilingScheme : tilingScheme,
                        terrainProvider : terrainProvider,
                        pts : []
                    };
                    tileRequestSet[key] = value;
                    tileRequests.push(value);
                }

                // Now append to array of points for the tile
                tileRequestSet[key].pts.push(pts[i]);
            }
        }

        // Send request for each required tile
        var tilePromises = [];
        for (i = 0; i < tileRequests.length; ++i) {
            var tileRequest = tileRequests[i];
            var requestPromise = tileRequest.terrainProvider.requestTileGeometry(tileRequest.x, tileRequest.y, tileRequest.level, false);
            var tilePromise = when(requestPromise, createInterpolateFunction(tileRequest), createMarkFailedFunction(tileRequest));
            tilePromises.push(tilePromise);
        }

        return when.all(tilePromises);
    };

    function createInterpolateFunction(tileRequest) {
        var tilePts = tileRequest.pts;
        var extent = tileRequest.tilingScheme.tileXYToExtent(tileRequest.x, tileRequest.y, tileRequest.level);
        return function(terrainData) {
            // for each point that falls in this tile
            for (var j = 0; j < tilePts.length; ++j) {
                var pt = tilePts[j];
                pt.height = terrainData.interpolateHeight(extent, pt.longitude, pt.latitude);
            }
        };
    }

    function createMarkFailedFunction(tileRequest) {
        var tilePts = tileRequest.pts;
        return function() {
            // for each point that falls in this tile
            for (var j = 0; j < tilePts.length; ++j) {
                var pt = tilePts[j];
                pt.height = undefined;
            }
        };
    }

    return terrainSample;
});
<commit_msg>Doc and minor improvements to terrainSample.<commit_after>/*global define*/
define([
        '../Core/defaultValue',
        '../Core/DeveloperError',
        './TerrainState',
        '../ThirdParty/when'
    ], function(
        defaultValue,
        DeveloperError,
        TerrainState,
        when) {
    "use strict";

    /**
     * Initiates a terrain height query for an array of {@link Cartographic} positions by
     * requesting tiles from a terrain provider, sampling, and interpolating.  The query
     * happens asynchronously, so this function returns a promise that is resolved when
     * the query completes.  Each point height is modified in place.  If a height can not be
     * determined because no terrain data is available for the specified level at that location,
     * or another error occurs, the height is set to undefined.
     *
     * @exports terrainSample
     *
     * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights.
     * @param {Number} level The terrain level-of-detail from which to query terrain heights.
     * @param {Cartographic[]} positions The positions to update with terrain heights.
     *
     * @returns {Promise} A promise that, when resolved, indicates that the query has completed.
     */
    var terrainSample = function(terrainProvider, level, positions) {
        if (typeof terrainProvider === 'undefined') {
            throw new DeveloperError('terrainProvider is required.');
        }
        if (typeof level === 'undefined') {
            throw new DeveloperError('level is required.');
        }
        if (typeof positions === 'undefined') {
            throw new DeveloperError('positions is required.');
        }

        var tilingScheme = terrainProvider.getTilingScheme();

        var i;

        // Sort points into a set of tiles
        var tileRequests = []; // Result will be an Array as it's easier to work with
        {
            var tileRequestSet = {}; // A unique set
            for (i = 0; i < positions.length; ++i) {
                var xy = tilingScheme.positionToTileXY(positions[i], level);
                var key = xy.toString();

                if (!tileRequestSet.hasOwnProperty(key)) {
                    // When tile is requested for the first time
                    var value = {
                        x : xy.x,
                        y : xy.y,
                        level : level,
                        tilingScheme : tilingScheme,
                        terrainProvider : terrainProvider,
                        positions : []
                    };
                    tileRequestSet[key] = value;
                    tileRequests.push(value);
                }

                // Now append to array of points for the tile
                tileRequestSet[key].positions.push(positions[i]);
            }
        }

        // Send request for each required tile
        var tilePromises = [];
        for (i = 0; i < tileRequests.length; ++i) {
            var tileRequest = tileRequests[i];
            var requestPromise = tileRequest.terrainProvider.requestTileGeometry(tileRequest.x, tileRequest.y, tileRequest.level, false);
            var tilePromise = when(requestPromise, createInterpolateFunction(tileRequest), createMarkFailedFunction(tileRequest));
            tilePromises.push(tilePromise);
        }

        return when.all(tilePromises);
    };

    function createInterpolateFunction(tileRequest) {
        var tilePositions = tileRequest.positions;
        var extent = tileRequest.tilingScheme.tileXYToExtent(tileRequest.x, tileRequest.y, tileRequest.level);
        return function(terrainData) {
            for (var i = 0; i < tilePositions.length; ++i) {
                var position = tilePositions[i];
                position.height = terrainData.interpolateHeight(extent, position.longitude, position.latitude);
            }
        };
    }

    function createMarkFailedFunction(tileRequest) {
        var tilePositions = tileRequest.positions;
        return function() {
            for (var i = 0; i < tilePositions.length; ++i) {
                var position = tilePositions[i];
                position.height = undefined;
            }
        };
    }

    return terrainSample;
});
<|endoftext|>