<commit_before>#!/usr/bin/env node

var gittio = require('../lib/gittio'),
  config = require('../lib/config'),
  logger = require('../lib/logger'),
  program = require('commander'),
  fs = require('fs'),
  package = require('../package.json'),
  updateNotifier = require('update-notifier');

var notifier = updateNotifier({
  packagePath: '../package.json'
});

program
  .version(package.version, '-v, --version')
  .description(package.about.name)
  .usage('command <args> [options]')
  .option('-g, --global', 'use global path for modules')
  .option('-f, --force', 'install components even if already found')
  .option('-p, --platform <platform>', 'apply to a specific platform only');

program.command('install')
  .usage('<id>@<version>:<platform>')
  .description('install all missing modules and widgets')
  .option('-t, --type <type>', 'widget or module (default: both)')
  .action(install);

// ony here for help
program.command('install <id>')
  .description('install the latest version');

// ony here for help
program.command('install <id>@<version>')
  .description('install a specific version');

// ony here for help
program.command('install <id>@<version>:<platform>')
  .description('install a specific version for a specific platform');

program.command('update')
  .description('update all modules and widgets')
  .option('-t, --type <type>', 'widget or module (default: both)')
  .action(function(env) {
    notifier.update && notifier.notify();

    var params = {
      force: this.force,
      global: this.global,
      platform: this.platform,
      type: env.type,
      update: true
    };
    config.init(params.global, function() {
      return gittio.install(params);
    });
  });

program.command('uninstall <id>')
  .usage('<id>@<version>:<platform>')
  .description('uninstall a module or widget')
  .action(uninstall);

// ony here for help
program.command('uninstall <id>@<version>')
  .description('uninstall a specific version');

// ony here for help
program.command('uninstall <id>@<version>:<platform>')
  .description('uninstall a specific version for a specific platform');

program.command('info <id>')
  .description('display info about a component')
  .option('-o, --output <output>', 'pretty or json (default: pretty)')
  .action(gittio.info);

program.command('demo <id>')
  .description('create a demo project using the module example app.js')
  .option('-p, --platform <platform>', 'define which platform(s) you\'d like to demo (comma separated')
  .action(demo);

program.command('config')
  .description('list all global configuration settings')
  .action(function(env) {

    // only run if there are no arguments
    if (this.args.length === 1) {

      require('../lib/config').list();

      // or commander will also run the other config command
      process.exit();

    }

  });

program.command('config <key> <value>')
  .description('set a global configuration setting')
  .action(function(env) {

    require('../lib/config').set(this.args[0], this.args[1]);

  });

program.parse(process.argv);

if (program.args.length === 0 || typeof program.args[program.args.length - 1] === 'string') {
  notifier.update && notifier.notify();

  program.help();
}

function argsToParams(args, params, url) {

  if (typeof args[0] === 'string') {
    var input = args[0];

    if (url && input.indexOf('://') > 0) {
      params.url = input;

    } else if (url && fs.existsSync(input)) {
      params.file = input;

    } else {

      var at = input.indexOf('@');
      var sc = input.indexOf(':');

      if (sc > 0) {
        params.platform = input.substr(sc + 1);
        input = input.substr(0, sc);
      }

      if (at > 0) {
        params.id = input.substr(0, at);
        params.version = input.substr(at + 1);

      } else {
        params.id = input;
      }
    }
  }
}

function install(env) {
  notifier.update && notifier.notify();

  var args = this.args;
  var params = {
    force: this.force,
    global: this.global,
    platform: this.platform,
    type: env.type
  };
  config.init(params.global, function() {
    argsToParams(args, params, true);

    if (params.id && params.version) {
      params.force = true;
    }

    return gittio.install(params);
  });
}

function uninstall(env) {
  notifier.update && notifier.notify();

  var args = this.args;
  var params = {
    force: this.force,
    global: this.global,
    platform: this.platform
  };
  config.init(params.global, function() {
    argsToParams(args, params);

    if (!params.id) {
      logger.error('missing <id>');
      return;
    }

    return gittio.uninstall(params);
  });
}

function demo(env) {
  notifier.update && notifier.notify();

  var args = this.args;
  var params = {
    platform: this.platform
  };
  config.init(true, function() {
    argsToParams(args, params);

    if (!params.id) {
      logger.error('missing <id>');
      return;
    }

    return gittio.demo(params);
  });
}<commit_msg>Added alias for install / uninstall<commit_after>#!/usr/bin/env node

var gittio = require('../lib/gittio'),
  config = require('../lib/config'),
  logger = require('../lib/logger'),
  program = require('commander'),
  fs = require('fs'),
  package = require('../package.json'),
  updateNotifier = require('update-notifier');

var notifier = updateNotifier({
  packagePath: '../package.json'
});

program
  .version(package.version, '-v, --version')
  .description(package.about.name)
  .usage('command <args> [options]')
  .option('-g, --global', 'use global path for modules')
  .option('-f, --force', 'install components even if already found')
  .option('-p, --platform <platform>', 'apply to a specific platform only');

var install_cmd = program.command('install')
  .usage('<id>@<version>:<platform>')
  .description('install all missing modules and widgets')
  .option('-t, --type <type>', 'widget or module (default: both)')
  .action(install);

// ony here for help
program.command('install <id>')
  .description('install the latest version');

// ony here for help
program.command('install <id>@<version>')
  .description('install a specific version');

// ony here for help
program.command('install <id>@<version>:<platform>')
  .description('install a specific version for a specific platform');

// create alias command
var install_alias = program.command('i')
  .action(install)
  .description("shorthand for `install`");

// clone the options
install_alias.options = install_cmd.options;

program.command('update')
  .description('update all modules and widgets')
  .option('-t, --type <type>', 'widget or module (default: both)')
  .action(function(env) {
    notifier.update && notifier.notify();

    var params = {
      force: this.force,
      global: this.global,
      platform: this.platform,
      type: env.type,
      update: true
    };
    config.init(params.global, function() {
      return gittio.install(params);
    });
  });

var uninstall_cmd = program.command('uninstall <id>')
  .usage('<id>@<version>:<platform>')
  .description('uninstall a module or widget')
  .action(uninstall);

// ony here for help
program.command('uninstall <id>@<version>')
  .description('uninstall a specific version');

// ony here for help
program.command('uninstall <id>@<version>:<platform>')
  .description('uninstall a specific version for a specific platform');

// create alias command
var uninstall_alias = program.command('u')
  .action(uninstall)
  .description("shorthand for `uninstall`");

// clone the options
install_alias.options = install_cmd.options;

program.command('info <id>')
  .description('display info about a component')
  .option('-o, --output <output>', 'pretty or json (default: pretty)')
  .action(gittio.info);

program.command('demo <id>')
  .description('create a demo project using the module example app.js')
  .option('-p, --platform <platform>', 'define which platform(s) you\'d like to demo (comma separated')
  .action(demo);

program.command('config')
  .description('list all global configuration settings')
  .action(function(env) {

    // only run if there are no arguments
    if (this.args.length === 1) {

      require('../lib/config').list();

      // or commander will also run the other config command
      process.exit();

    }

  });

program.command('config <key> <value>')
  .description('set a global configuration setting')
  .action(function(env) {

    require('../lib/config').set(this.args[0], this.args[1]);

  });

program.parse(process.argv);

if (program.args.length === 0 || typeof program.args[program.args.length - 1] === 'string') {
  notifier.update && notifier.notify();

  program.help();
}

function argsToParams(args, params, url) {

  if (typeof args[0] === 'string') {
    var input = args[0];

    if (url && input.indexOf('://') > 0) {
      params.url = input;

    } else if (url && fs.existsSync(input)) {
      params.file = input;

    } else {

      var at = input.indexOf('@');
      var sc = input.indexOf(':');

      if (sc > 0) {
        params.platform = input.substr(sc + 1);
        input = input.substr(0, sc);
      }

      if (at > 0) {
        params.id = input.substr(0, at);
        params.version = input.substr(at + 1);

      } else {
        params.id = input;
      }
    }
  }
}

function install(env) {
  notifier.update && notifier.notify();

  var args = this.args;
  var params = {
    force: this.force,
    global: this.global,
    platform: this.platform,
    type: env.type
  };
  config.init(params.global, function() {
    argsToParams(args, params, true);

    if (params.id && params.version) {
      params.force = true;
    }

    return gittio.install(params);
  });
}

function uninstall(env) {
  notifier.update && notifier.notify();

  var args = this.args;
  var params = {
    force: this.force,
    global: this.global,
    platform: this.platform
  };
  config.init(params.global, function() {
    argsToParams(args, params);

    if (!params.id) {
      logger.error('missing <id>');
      return;
    }

    return gittio.uninstall(params);
  });
}

function demo(env) {
  notifier.update && notifier.notify();

  var args = this.args;
  var params = {
    platform: this.platform
  };
  config.init(true, function() {
    argsToParams(args, params);

    if (!params.id) {
      logger.error('missing <id>');
      return;
    }

    return gittio.demo(params);
  });
}<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { toastr } from 'react-redux-toastr';
import { Router } from 'routes';

// components
import Navigation from 'components/form/Navigation';
import Spinner from 'components/ui/Spinner';
import Step1 from 'components/dashboards/form/steps/step-1';

// services
import { fetchDashboard, createDashboard, updateDashboard } from 'services/dashboard';

// utils
import { logEvent } from 'utils/analytics';

// constants
import { STATE_DEFAULT, FORM_ELEMENTS } from 'components/dashboards/form/constants';

class DashboardsForm extends PureComponent {
  static propTypes = {
    user: PropTypes.object.isRequired,
    id: PropTypes.string,
    basic: PropTypes.bool,
    onSubmit: PropTypes.func
  }

  static defaultProps = {
    id: null,
    basic: false,
    onSubmit: null
  }

  state = {
    ...STATE_DEFAULT,
    loading: !!this.props.id,
    form: {
      ...STATE_DEFAULT.form,
      user_id: this.props.user.id
    }
  }

  componentDidMount() {
    const { id } = this.props;
    // Get the dashboards and fill the
    // state form with its params if the id exists
    if (id) {
      fetchDashboard(id)
        .then((data) => {
          this.setState({
            form: this.setFormFromParams(data),
            loading: false
          });
        })
        .catch((err) => { toastr.error(err.message); });
    }
  }

  onSubmit = (event) => {
    const { user: { token } } = this.props;
    const {
      step,
      form,
      submitting,
      stepLength
    } = this.state;
    event.preventDefault();

    FORM_ELEMENTS.validate(step);

    // Set a timeout due to the setState function of react
    setTimeout(() => {
      // Validate all the inputs on the current step
      const valid = FORM_ELEMENTS.isValid(step);
      const onFetchSuccess = (data) => {
        const { id: dashboardId, name } = data;
        toastr.success('Success', `The dashboard "${dashboardId}" - "${name}" has been uploaded correctly`);

        if (this.props.onSubmit) this.props.onSubmit();
      };
      const onFetchError = (err) => {
        this.setState({ submitting: false });
        toastr.error('Error', `Oops! There was an error, try again. ${err.message}`);
      };

      if (valid) {
        logEvent('My RW', 'User creates a new dashboard', form.name);

        // if we are in the last step we will submit the form
        if (step === stepLength && !submitting) {
          const { id } = this.props;

          this.setState({ submitting: true });

          if (!id) {
            createDashboard(form, token)
              .then(onFetchSuccess)
              .catch(onFetchError);
          } else {
            updateDashboard(id, form, token)
              .then(onFetchSuccess)
              .catch(onFetchError);
          }
        } else {
          this.setState({ step: step + 1 });
        }
      } else {
        toastr.error('Error', 'Fill all the required fields or correct the invalid values');
      }
    }, 0);
  }

  onChange =(obj) => {
    const form = Object.assign({}, this.state.form, obj);
    this.setState({ form });
  }

  onStepChange = (step) => { this.setState({ step }); }

  onCancel = () => {
    Router.pushRoute('myrw_detail', { tab: 'dashboards', id: 'new' });
  }

  // HELPERS
  setFormFromParams(params) {
    const newForm = {};

    Object.keys(params).forEach((f) => {
      switch (f) {
        // TODO: if the API doesn't send it we won't need to handle it
        case 'photo': {
          if (params[f] && params[f].original !== '/photos/original/missing.png') {
            newForm[f] = params[f].original;
          }
          break;
        }
        default: {
          if ((typeof params[f] !== 'undefined' || params[f] !== null) ||
              (typeof this.state.form[f] !== 'undefined' || this.state.form[f] !== null)) {
            newForm[f] = params[f] || this.state.form[f];
          }
        }
      }
    });

    return newForm;
  }

  render() {
    const { id, basic } = this.props;
    const {
      loading,
      form,
      step,
      stepLength,
      submitting
    } = this.state;

    return (
      <form
        className="c-form"
        onSubmit={this.onSubmit}
        noValidate
      >
        <Spinner
          isLoading={loading}
          className="-light"
        />

        {(this.state.step === 1 && !loading) &&
          <Step1
            onChange={value => this.onChange(value)}
            basic={basic}
            form={form}
            id={id}
            {...this.props}
          />
        }

        {!loading &&
          <Navigation
            step={step}
            stepLength={stepLength}
            submitting={submitting}
            onStepChange={this.onStepChange}
            onBack={this.onCancel}
          />
        }
      </form>
    );
  }
}

export default DashboardsForm;
<commit_msg>Redirrect to dashboards table when click 'cancel' on new/edit page<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { toastr } from 'react-redux-toastr';
import { Router } from 'routes';

// components
import Navigation from 'components/form/Navigation';
import Spinner from 'components/ui/Spinner';
import Step1 from 'components/dashboards/form/steps/step-1';

// services
import { fetchDashboard, createDashboard, updateDashboard } from 'services/dashboard';

// utils
import { logEvent } from 'utils/analytics';

// constants
import { STATE_DEFAULT, FORM_ELEMENTS } from 'components/dashboards/form/constants';

class DashboardsForm extends PureComponent {
  static propTypes = {
    user: PropTypes.object.isRequired,
    id: PropTypes.string,
    basic: PropTypes.bool,
    onSubmit: PropTypes.func
  }

  static defaultProps = {
    id: null,
    basic: false,
    onSubmit: null
  }

  state = {
    ...STATE_DEFAULT,
    loading: !!this.props.id,
    form: {
      ...STATE_DEFAULT.form,
      user_id: this.props.user.id
    }
  }

  componentDidMount() {
    const { id } = this.props;
    // Get the dashboards and fill the
    // state form with its params if the id exists
    if (id) {
      fetchDashboard(id)
        .then((data) => {
          this.setState({
            form: this.setFormFromParams(data),
            loading: false
          });
        })
        .catch((err) => { toastr.error(err.message); });
    }
  }

  onSubmit = (event) => {
    const { user: { token } } = this.props;
    const {
      step,
      form,
      submitting,
      stepLength
    } = this.state;
    event.preventDefault();

    FORM_ELEMENTS.validate(step);

    // Set a timeout due to the setState function of react
    setTimeout(() => {
      // Validate all the inputs on the current step
      const valid = FORM_ELEMENTS.isValid(step);
      const onFetchSuccess = (data) => {
        const { id: dashboardId, name } = data;
        toastr.success('Success', `The dashboard "${dashboardId}" - "${name}" has been uploaded correctly`);

        if (this.props.onSubmit) this.props.onSubmit();
      };
      const onFetchError = (err) => {
        this.setState({ submitting: false });
        toastr.error('Error', `Oops! There was an error, try again. ${err.message}`);
      };

      if (valid) {
        logEvent('My RW', 'User creates a new dashboard', form.name);

        // if we are in the last step we will submit the form
        if (step === stepLength && !submitting) {
          const { id } = this.props;

          this.setState({ submitting: true });

          if (!id) {
            createDashboard(form, token)
              .then(onFetchSuccess)
              .catch(onFetchError);
          } else {
            updateDashboard(id, form, token)
              .then(onFetchSuccess)
              .catch(onFetchError);
          }
        } else {
          this.setState({ step: step + 1 });
        }
      } else {
        toastr.error('Error', 'Fill all the required fields or correct the invalid values');
      }
    }, 0);
  }

  onChange =(obj) => {
    const form = Object.assign({}, this.state.form, obj);
    this.setState({ form });
  }

  onStepChange = (step) => { this.setState({ step }); }

  onCancel = () => {
    const { basic } = this.props;
    if (basic) {
      Router.pushRoute('myrw', { tab: 'dashboards' });
    } else {
      Router.pushRoute('admin_dashboards');
    }
  }

  // HELPERS
  setFormFromParams(params) {
    const newForm = {};

    Object.keys(params).forEach((f) => {
      switch (f) {
        // TODO: if the API doesn't send it we won't need to handle it
        case 'photo': {
          if (params[f] && params[f].original !== '/photos/original/missing.png') {
            newForm[f] = params[f].original;
          }
          break;
        }
        default: {
          if ((typeof params[f] !== 'undefined' || params[f] !== null) ||
              (typeof this.state.form[f] !== 'undefined' || this.state.form[f] !== null)) {
            newForm[f] = params[f] || this.state.form[f];
          }
        }
      }
    });

    return newForm;
  }

  render() {
    const { id, basic } = this.props;
    const {
      loading,
      form,
      step,
      stepLength,
      submitting
    } = this.state;

    return (
      <form
        className="c-form"
        onSubmit={this.onSubmit}
        noValidate
      >
        <Spinner
          isLoading={loading}
          className="-light"
        />

        {(this.state.step === 1 && !loading) &&
          <Step1
            onChange={value => this.onChange(value)}
            basic={basic}
            form={form}
            id={id}
            {...this.props}
          />
        }

        {!loading &&
          <Navigation
            step={step}
            stepLength={stepLength}
            submitting={submitting}
            onStepChange={this.onStepChange}
            onBack={this.onCancel}
          />
        }
      </form>
    );
  }
}

export default DashboardsForm;
<|endoftext|>


<commit_before>
var mySessionId;
var map;
var userLocation;
var fuzzyUserLocation;
var markersMap = {};
var markerImage;
var advanced = true;
var infoWindowZIndex = 100;
var shareAccurateLocation = false;

var isLowResolution = window.screen.width < 768;
var defaultZoom = isLowResolution ? 2 : 3;
var minZoom = isLowResolution ? 1 : 3;

var locationOptions = {
  enableHighAccuracy: true,
  timeout: 10000,
  maximumAge: 10000
};

var entityMap = {
  "&": "&",
  "<": "<",
  ">": ">",
  '"': '"',
  "#": "#",
  "'": ''',
  "/": '/',
  "卐": 'I am a dick ',
  "卍": 'I am a dick '
};

function initialize() {

  var defaultLatLng = new google.maps.LatLng(0.1, 0.1); // Add the coordinates

  markerImage = {
    url: 'images/blue_marker.png',
    scaledSize: new google.maps.Size(30, 30)
  };

  disabledMarkerImage = {
    url: 'images/grey_marker.png',
    scaledSize: new google.maps.Size(30, 30)
  };

  var mapOptions = {
    center: defaultLatLng,
    zoom: defaultZoom, // The initial zoom level when your map loads (0-20)
    minZoom: minZoom, // Minimum zoom level allowed (0-20)
    maxZoom: 18, // Maximum soom level allowed (0-20)
    zoomControl: false, // Set to true if using zoomControlOptions below, or false to remove all zoom controls.
    mapTypeId: google.maps.MapTypeId.ROADMAP, // Set the type of Map
    scrollwheel: true, // Enable Mouse Scroll zooming
    // All of the below are set to true by default, so simply remove if set to true:
    panControl: false, // Set to false to disable
    mapTypeControl: false, // Disable Map/Satellite switch
    scaleControl: false, // Set to false to hide scale
    streetViewControl: false, // Set to disable to hide street view
    overviewMapControl: false, // Set to false to remove overview control
    rotateControl: false // Set to false to disable rotate control
  };
  var mapDiv = document.getElementById('map-canvas');
  map = new google.maps.Map(mapDiv, mapOptions);

  navigator.geolocation.getCurrentPosition(onFirstPosition, onPositionError, locationOptions);
}

function onFirstPosition(position) {
  setUserLocation(position.coords.latitude, position.coords.longitude);
  initialiseEventBus();
  map.panTo(userLocation);
  var message = {};
  message.lat = position.coords.latitude;
  message.lng = position.coords.longitude;
  message.text = "I just connected to the map!"

  client.publish("pgochat/chat", JSON.stringify(message));
}

function onPositionUpdate(position) {
  if (markersMap[mySessionId]) { //update user marker position
    setUserLocation(position.coords.latitude, position.coords.longitude);
    var userMarker = markersMap[mySessionId].marker;
    userMarker.setPosition(shareAccurateLocation ? userLocation : fuzzyUserLocation);
  }
}

function onPositionError(err) {
  // try fallback location provider ipinfo.io or generate random location
  // $.getJSON("http://ipinfo.io", onFallbackLocationProviderResponse, useRandomLocation);
  onFirstPosition({
    "coords": {
      latitude: parseFloat(0.1),
      longitude: parseFloat(0.1)
    }
  });
}

function onFallbackLocationProviderResponse(ipinfo) {
  console.log("Found location [" + ipinfo.loc + "] by ipinfo.io");
  var latLong = ipinfo.loc.split(",");
  onFirstPosition({
    "coords": {
      latitude: parseFloat(latLong[0]),
      longitude: parseFloat(latLong[1])
    }
  });
}

function useRandomLocation(err) {
  Materialize.toast('User location problem, using random location :P', 7000);
  // These ranges cover only the center of the map
  var lat = (90 * Math.random() - 22.5).toFixed(3);
  var lng = (180 * Math.random() - 90).toFixed(3);
  onFirstPosition({
    "coords": {
      latitude: parseFloat(lat),
      longitude: parseFloat(lng)
    }
  });
}

function setUserLocation(lat, lng) {
  userLocation = new google.maps.LatLng(lat, lng);
  fuzzyUserLocation = new google.maps.LatLng(Math.round(lat * 100) / 100, Math.round(lng * 100) / 100);
}

function createMessage(text) {
  return {
    lat: shareAccurateLocation ? userLocation.lat() : fuzzyUserLocation.lat(),
    lng: shareAccurateLocation ? userLocation.lng() : fuzzyUserLocation.lng(),
    text: text
  };
}

function setupMarkerAndInfoWindow(msgSessionId, content, position, map, icoOn, icoOff) {
    var infoWindow = new google.maps.InfoWindow({
      content: content,
      maxWidth: 400,
      disableAutoPan: true,
      zIndex: infoWindowZIndex
    });
    infoWindowZIndex++;

    var marker = new google.maps.Marker({
      position: position,
      map: map,
      draggable: false,
      icon: icoOn,
      title: "Click to mute/un-mute User " + msgSessionId
    });

    marker.addListener('click', function () {
      if (markersMap[msgSessionId].disabled) {
        markersMap[msgSessionId].disabled = false;
        marker.setIcon(icoOn);
      } else {
        markersMap[msgSessionId].disabled = true;
        marker.setIcon(icoOff);
        infoWindow.close();
      }
    });

    return {
      marker: marker,
      infoWindow: infoWindow
    };
}

function displayChatMessageOnMap(raw) {
  var msg = JSON.parse(raw)
  //console.log(msg)
  var newPosition = new google.maps.LatLng(msg.lat, msg.lng);
  var msgSessionId = msg.sessionId;

  // xss prevention hack
  msg.text = html_sanitize(msg.text);

  msg.text = String(msg.text).replace(/[&<>"#'\/卐卍]/g, function (s) {
    return entityMap[s];
  });

  // msg.text = msg.text ? embedTweet(msg.text) : "";
  msg.text = msg.text.replace(/#(\S*)/g, '#$1');

  // linkify
  msg.text = msg.text.replace(
    /(\b(https?|ftp|file)://[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
    "$1"
  );

  if (markersMap[msgSessionId]) { // update existing marker
    var existingMarker = markersMap[msgSessionId].marker;
    var existingInfoWindow = markersMap[msgSessionId].infoWindow;
    var existingTimeoutId = markersMap[msgSessionId].timeoutId;

    existingMarker.setPosition(newPosition);
    existingInfoWindow.setContent(msg.text);
    existingInfoWindow.setZIndex(infoWindowZIndex);
    infoWindowZIndex++;
    if (msg.text && !markersMap[msgSessionId].disabled) {
      if (existingTimeoutId) {
        clearTimeout(existingTimeoutId);
      }
      markersMap[msgSessionId].timeoutId = setTimeout(function () { existingInfoWindow.close() }, 10000);
      existingInfoWindow.open(map, existingMarker);
    }
  } else { // new marker
    var markerWindow = setupMarkerAndInfoWindow(msgSessionId,msg.text, newPosition, map, markerImage, disabledMarkerImage);
    var infoWindow = markerWindow.infoWindow;
    var marker = markerWindow.marker;

    if (msg.text !== 'undefined') {
      infoWindow.open(map, marker);
    }

    var timeoutId = setTimeout(function () { infoWindow.close() }, 10000);
    markersMap[msgSessionId] = {
      marker: marker,
      infoWindow: infoWindow,
      timeoutId: timeoutId,
      disabled: false
    }
  }

  if (advanced) {
    runAdvancedOptions(msg);
  }
}

// @ro: to calculate time until expiration
function timeUntil(now, then) {
  var timestampNow = Date.parse(now);
  var timestampThen = Date.parse(then);
  var diff = new Date(timestampThen - timestampNow);

  diff.setSeconds(Math.round(diff.getSeconds() / 30) * 30);

  return diff;
}

function displayMessageOnMap(msg, olat, olong, sessid, icostr, expir, pokenick) {
  // @ro: passing values split from incoming payload into two variables for now (lat and long)
  var newPosition = new google.maps.LatLng(olat, olong);
  var msgSessionId = sessid;
  var expiration = expir;
  var pName = '';
  if(typeof pokenick === 'undefined'){
    var pName = " just appeared!
lat: " + olat + " / long: " + olong;
  } else {
    var pName = "" + pokenick + " just appeared!
lat: " + olat + " / long: " + olong;
  }
  // console.log(pName);
  // @ro: just checking the output
  //console.log(olat);
  //console.log(olong);

  // xss prevention hack
  msg.text = html_sanitize(msg.text);

  msg.text = String(msg.text).replace(/[&<>"#'\/卐卍]/g, function (s) {
    return entityMap[s];
  });

  // msg.text = msg.text ? embedTweet(msg.text) : "";
  msg.text = msg.text.replace(/#(\S*)/g, '#$1');

  // linkify
  msg.text = msg.text.replace(
    /(\b(https?|ftp|file)://[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
    "$1"
  );

  var icon = { url: icostr, scaledSize: new google.maps.Size(36, 36) };
  var markerMap = setupMarkerAndInfoWindow(msgSessionId, pName, newPosition, map, icon, icon);
  var marker = markerMap.marker;
  var infoWindow = markerMap.infoWindow;

  if (!markersMap[msgSessionId]) { // new marker
    if (msg.text !== 'undefined') {
      infoWindow.open(map, marker);
    }

    var timeoutId = setTimeout(function () { infoWindow.close() }, 10000);
    markersMap[msgSessionId] = {
      marker: marker,
      infoWindow: infoWindow,
      timeoutId: timeoutId,
      disabled: false
    }
  }

  if (advanced) {
    runAdvancedOptions(msg);
  }
}

function embedTweet(text) {
  var tweetText = "Someone wrote " + text + " on ";
  var tweetUrl = "https:\/\/twitter.com\/share?url=http://maps.pikabot.org/&text=" + tweetText;
  var width = 500, height = 300;
  var left = (screen.width / 2) - (width / 2);
  var top = (screen.height / 2) - (height / 2);
  return " " +
    " <image src='images/twitter_icon_small.png'> <\/a> " + text;
}

function clearMessageFromMap() {
  for (var markerSessionId in markersMap) {
    if (markersMap.hasOwnProperty(markerSessionId)) {
      markersMap[markerSessionId].infoWindow.close();
    }
  }
}

function changeZoom(factor) {
  map.setZoom(map.getZoom() + factor);
}

function runAdvancedOptions(msg) {
  if (msg.sessionId == mySessionId) {
    return;
  }

  if (Notification.permission !== "granted") {
    Notification.requestPermission();
  }

  new Notification('Incoming MapChat', {
    icon: 'favicons/apple-touch-icon-120x120.png',
    body: msg.text ? "Incoming message: " + msg.text : "New user"
  });
}

// This should be displayed when the app is opened from a mobile facebook app WebView (Until a better solution is found)
if (window.navigator.userAgent.indexOf("FBAV") > 0) {
  document.write(
    "
" +
    "
" +
    "
" +
    "This page will not work inside the facebook app, " +
    "please open it in the native browser." +
    "
" +
    "
" +
    "
"
  );
} else {
  google.maps.event.addDomListener(window, 'load', initialize);
}
<commit_msg>To allow the real time display info box on pokemon at the time.<commit_after>
var mySessionId;
var map;
var userLocation;
var fuzzyUserLocation;
var markersMap = {};
var markerImage;
var advanced = true;
var infoWindowZIndex = 100;
var shareAccurateLocation = false;

var isLowResolution = window.screen.width < 768;
var defaultZoom = isLowResolution ? 2 : 3;
var minZoom = isLowResolution ? 1 : 3;

var locationOptions = {
  enableHighAccuracy: true,
  timeout: 10000,
  maximumAge: 10000
};

var entityMap = {
  "&": "&",
  "<": "<",
  ">": ">",
  '"': '"',
  "#": "#",
  "'": ''',
  "/": '/',
  "卐": 'I am a dick ',
  "卍": 'I am a dick '
};

function initialize() {

  var defaultLatLng = new google.maps.LatLng(0.1, 0.1); // Add the coordinates

  markerImage = {
    url: 'images/blue_marker.png',
    scaledSize: new google.maps.Size(30, 30)
  };

  disabledMarkerImage = {
    url: 'images/grey_marker.png',
    scaledSize: new google.maps.Size(30, 30)
  };

  var mapOptions = {
    center: defaultLatLng,
    zoom: defaultZoom, // The initial zoom level when your map loads (0-20)
    minZoom: minZoom, // Minimum zoom level allowed (0-20)
    maxZoom: 18, // Maximum soom level allowed (0-20)
    zoomControl: false, // Set to true if using zoomControlOptions below, or false to remove all zoom controls.
    mapTypeId: google.maps.MapTypeId.ROADMAP, // Set the type of Map
    scrollwheel: true, // Enable Mouse Scroll zooming
    // All of the below are set to true by default, so simply remove if set to true:
    panControl: false, // Set to false to disable
    mapTypeControl: false, // Disable Map/Satellite switch
    scaleControl: false, // Set to false to hide scale
    streetViewControl: false, // Set to disable to hide street view
    overviewMapControl: false, // Set to false to remove overview control
    rotateControl: false // Set to false to disable rotate control
  };
  var mapDiv = document.getElementById('map-canvas');
  map = new google.maps.Map(mapDiv, mapOptions);

  navigator.geolocation.getCurrentPosition(onFirstPosition, onPositionError, locationOptions);
}

function onFirstPosition(position) {
  setUserLocation(position.coords.latitude, position.coords.longitude);
  initialiseEventBus();
  map.panTo(userLocation);
  var message = {};
  message.lat = position.coords.latitude;
  message.lng = position.coords.longitude;
  message.text = "I just connected to the map!"

  client.publish("pgochat/chat", JSON.stringify(message));
}

function onPositionUpdate(position) {
  if (markersMap[mySessionId]) { //update user marker position
    setUserLocation(position.coords.latitude, position.coords.longitude);
    var userMarker = markersMap[mySessionId].marker;
    userMarker.setPosition(shareAccurateLocation ? userLocation : fuzzyUserLocation);
  }
}

function onPositionError(err) {
  // try fallback location provider ipinfo.io or generate random location
  // $.getJSON("http://ipinfo.io", onFallbackLocationProviderResponse, useRandomLocation);
  onFirstPosition({
    "coords": {
      latitude: parseFloat(0.1),
      longitude: parseFloat(0.1)
    }
  });
}

function onFallbackLocationProviderResponse(ipinfo) {
  console.log("Found location [" + ipinfo.loc + "] by ipinfo.io");
  var latLong = ipinfo.loc.split(",");
  onFirstPosition({
    "coords": {
      latitude: parseFloat(latLong[0]),
      longitude: parseFloat(latLong[1])
    }
  });
}

function useRandomLocation(err) {
  Materialize.toast('User location problem, using random location :P', 7000);
  // These ranges cover only the center of the map
  var lat = (90 * Math.random() - 22.5).toFixed(3);
  var lng = (180 * Math.random() - 90).toFixed(3);
  onFirstPosition({
    "coords": {
      latitude: parseFloat(lat),
      longitude: parseFloat(lng)
    }
  });
}

function setUserLocation(lat, lng) {
  userLocation = new google.maps.LatLng(lat, lng);
  fuzzyUserLocation = new google.maps.LatLng(Math.round(lat * 100) / 100, Math.round(lng * 100) / 100);
}

function createMessage(text) {
  return {
    lat: shareAccurateLocation ? userLocation.lat() : fuzzyUserLocation.lat(),
    lng: shareAccurateLocation ? userLocation.lng() : fuzzyUserLocation.lng(),
    text: text
  };
}

function setupMarkerAndInfoWindow(msgSessionId, content, position, map, icoOn, icoOff) {
    var infoWindow = new google.maps.InfoWindow({
      content: content,
      maxWidth: 400,
      disableAutoPan: true,
      zIndex: infoWindowZIndex
    });
    infoWindowZIndex++;

    var marker = new google.maps.Marker({
      position: position,
      map: map,
      draggable: false,
      icon: icoOn,
      title: "Click to mute/un-mute User " + msgSessionId
    });

    marker.addListener('click', function () {
      if (markersMap[msgSessionId].disabled) {
        markersMap[msgSessionId].disabled = false;
        marker.setIcon(icoOn);
      } else {
        markersMap[msgSessionId].disabled = true;
        marker.setIcon(icoOff);
        infoWindow.close();
      }
    });

    return {
      marker: marker,
      infoWindow: infoWindow
    };
}

function displayChatMessageOnMap(raw) {
  var msg = JSON.parse(raw)
  //console.log(msg)
  var newPosition = new google.maps.LatLng(msg.lat, msg.lng);
  var msgSessionId = msg.sessionId;

  // xss prevention hack
  msg.text = html_sanitize(msg.text);

  msg.text = String(msg.text).replace(/[&<>"#'\/卐卍]/g, function (s) {
    return entityMap[s];
  });

  // msg.text = msg.text ? embedTweet(msg.text) : "";
  msg.text = msg.text.replace(/#(\S*)/g, '#$1');

  // linkify
  msg.text = msg.text.replace(
    /(\b(https?|ftp|file)://[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
    "$1"
  );

  if (markersMap[msgSessionId]) { // update existing marker
    var existingMarker = markersMap[msgSessionId].marker;
    var existingInfoWindow = markersMap[msgSessionId].infoWindow;
    var existingTimeoutId = markersMap[msgSessionId].timeoutId;

    existingMarker.setPosition(newPosition);
    existingInfoWindow.setContent(msg.text);
    existingInfoWindow.setZIndex(infoWindowZIndex);
    infoWindowZIndex++;
    if (msg.text && !markersMap[msgSessionId].disabled) {
      if (existingTimeoutId) {
        clearTimeout(existingTimeoutId);
      }
      markersMap[msgSessionId].timeoutId = setTimeout(function () { existingInfoWindow.close() }, 10000);
      existingInfoWindow.open(map, existingMarker);
    }
  } else { // new marker
    var markerWindow = setupMarkerAndInfoWindow(msgSessionId,msg.text, newPosition, map, markerImage, disabledMarkerImage);
    var infoWindow = markerWindow.infoWindow;
    var marker = markerWindow.marker;

    if (msg.text !== 'undefined') {
      infoWindow.open(map, marker);
    }

    var timeoutId = setTimeout(function () { infoWindow.close() }, 10000);
    markersMap[msgSessionId] = {
      marker: marker,
      infoWindow: infoWindow,
      timeoutId: timeoutId,
      disabled: false
    }
  }

  if (advanced) {
    runAdvancedOptions(msg);
  }
}

// @ro: to calculate time until expiration
function timeUntil(now, then) {
  var timestampNow = Date.parse(now);
  var timestampThen = Date.parse(then);
  var diff = new Date(timestampThen - timestampNow);

  diff.setSeconds(Math.round(diff.getSeconds() / 30) * 30);

  return diff;
}

function displayMessageOnMap(msg, olat, olong, sessid, icostr, expir, pokenick) {
  // @ro: passing values split from incoming payload into two variables for now (lat and long)
  var newPosition = new google.maps.LatLng(olat, olong);
  var msgSessionId = sessid;
  var expiration = expir;
  var pName = '';
  if(typeof pokenick === 'undefined'){
    var pName = " just appeared!
lat: " + olat + " / long: " + olong;
  } else {
    var pName = "" + pokenick + " just appeared!
lat: " + olat + " / long: " + olong;
  }
  // console.log(pName);
  // @ro: just checking the output
  //console.log(olat);
  //console.log(olong);

  // xss prevention hack
  msg.text = html_sanitize(msg.text);

  msg.text = String(msg.text).replace(/[&<>"#'\/卐卍]/g, function (s) {
    return entityMap[s];
  });

  // msg.text = msg.text ? embedTweet(msg.text) : "";
  msg.text = msg.text.replace(/#(\S*)/g, '#$1');

  // linkify
  msg.text = msg.text.replace(
    /(\b(https?|ftp|file)://[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
    "$1"
  );

  var icon = { url: icostr, scaledSize: new google.maps.Size(36, 36) };
  var markerMap = setupMarkerAndInfoWindow(msgSessionId, pName, newPosition, map, icon, icon);
  var marker = markerMap.marker;
  var infoWindow = markerMap.infoWindow;

  if (!markersMap[msgSessionId]) { // new marker
    infoWindow.open(map, marker);

    var timeoutId = setTimeout(function () { infoWindow.close() }, 10000);
    markersMap[msgSessionId] = {
      marker: marker,
      infoWindow: infoWindow,
      timeoutId: timeoutId,
      disabled: false
    }
  }

  if (advanced) {
    runAdvancedOptions(msg);
  }
}

function embedTweet(text) {
  var tweetText = "Someone wrote " + text + " on ";
  var tweetUrl = "https:\/\/twitter.com\/share?url=http://maps.pikabot.org/&text=" + tweetText;
  var width = 500, height = 300;
  var left = (screen.width / 2) - (width / 2);
  var top = (screen.height / 2) - (height / 2);
  return " " +
    " <image src='images/twitter_icon_small.png'> <\/a> " + text;
}

function clearMessageFromMap() {
  for (var markerSessionId in markersMap) {
    if (markersMap.hasOwnProperty(markerSessionId)) {
      markersMap[markerSessionId].infoWindow.close();
    }
  }
}

function changeZoom(factor) {
  map.setZoom(map.getZoom() + factor);
}

function runAdvancedOptions(msg) {
  if (msg.sessionId == mySessionId) {
    return;
  }

  if (Notification.permission !== "granted") {
    Notification.requestPermission();
  }

  new Notification('Incoming MapChat', {
    icon: 'favicons/apple-touch-icon-120x120.png',
    body: msg.text ? "Incoming message: " + msg.text : "New user"
  });
}

// This should be displayed when the app is opened from a mobile facebook app WebView (Until a better solution is found)
if (window.navigator.userAgent.indexOf("FBAV") > 0) {
  document.write(
    "
" +
    "
" +
    "
" +
    "This page will not work inside the facebook app, " +
    "please open it in the native browser." +
    "
" +
    "
" +
    "
"
  );
} else {
  google.maps.event.addDomListener(window, 'load', initialize);
}
<|endoftext|>


<commit_before>module.exports = function(skill, info, bot, message, db) {
    var userData = message.text.match(/\<(.*?)\>/g);
    console.log('messaage text: ' + message.text);
    console.log('userdata' + userData);
  if (userData) {
    // if there is a user named send ze hugs!
    //for (var i = 0, len = userData.length; i < len; i++) {
        //FU(userData[i].replace(/[^\w\s]/gi, ''));
        //console.log('userdata[i]' + userData[i]);
        //console.log('userdata[i]' + userData[i].replace(/[^\w\s]/gi, ''));
    //}
    console.log(userData[0].replace(/[^\w\s]/gi, ''));
    bot.reply(message, getSlackName(message.user.replace(/[^\w\s]/gi, '')) + ' Let\'s rumble ' + getSlackName(userData[0].replace(/[^\w\s]/gi, '')));

    //bot.reply(message,'Let\'s rumble' + userData[0].replace(/[^\w\s]/gi, ''));
  } else {
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function getSlackName(userID) {
    bot.api.users.info({user: userID}, (error, response) => {
        console.log(response.user.real_name);
    return response.user.real_name.toString();
    })
}

function FU(user) {
    //DM some shade!
    bot.api.im.open({ user: user }, function (err, response) {
      if (err) {
        return console.log(err)
      }
    var fuckArray = [
    'https://giphy.com/gifs/cheezburger-olympics-U7P2vnWfPkIQ8',
    'https://giphy.com/gifs/louis-ck-middle-finger-fuck-you-Qd71uU3LzyxXO'
    ];
    var randomFuck = Math.floor(Math.random()* fuckArray.length);

    var dmChannel = response.channel.id
    bot.say({channel: dmChannel, text: 'Someone is throwing shade your way... :middle_finger:'})
    bot.say({channel: dmChannel, text: fuckArray[randomFuck]})
    })

}

  var gameEngine = require('./Rock-Paper-Spock');

    bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    })

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "spock"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.addPlayer({id: 3, sign: "spock"});
  instance.addPlayer(4, "rock").addPlayer(5, "paper");
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<commit_msg>Update RockPaperScissors.js<commit_after>module.exports = function(skill, info, bot, message, db) {
    var userData = message.text.match(/\<(.*?)\>/g);
    console.log('messaage text: ' + message.text);
    console.log('userdata' + userData);
  if (userData) {
    // if there is a user named send ze hugs!
    //for (var i = 0, len = userData.length; i < len; i++) {
        //FU(userData[i].replace(/[^\w\s]/gi, ''));
        //console.log('userdata[i]' + userData[i]);
        //console.log('userdata[i]' + userData[i].replace(/[^\w\s]/gi, ''));
    //}
    console.log(userData[0].replace(/[^\w\s]/gi, ''));
    bot.reply(message, getSlackName(message.user.replace(/[^\w\s]/gi, '').toString()) + ' has challenged ' + getSlackName(userData[0].replace(/[^\w\s]/gi, '')));

    //bot.reply(message,'Let\'s rumble' + userData[0].replace(/[^\w\s]/gi, ''));
  } else {
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function getSlackName(userID) {
    bot.api.users.info({user: userID}, (error, response) => {
        console.log(response.user.real_name);
    return response.user.real_name.toString();
    })
}

function FU(user) {
    //DM some shade!
    bot.api.im.open({ user: user }, function (err, response) {
      if (err) {
        return console.log(err)
      }
    var fuckArray = [
    'https://giphy.com/gifs/cheezburger-olympics-U7P2vnWfPkIQ8',
    'https://giphy.com/gifs/louis-ck-middle-finger-fuck-you-Qd71uU3LzyxXO'
    ];
    var randomFuck = Math.floor(Math.random()* fuckArray.length);

    var dmChannel = response.channel.id
    bot.say({channel: dmChannel, text: 'Someone is throwing shade your way... :middle_finger:'})
    bot.say({channel: dmChannel, text: fuckArray[randomFuck]})
    })

}

  var gameEngine = require('./Rock-Paper-Spock');

    bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    })

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "spock"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.addPlayer({id: 3, sign: "spock"});
  instance.addPlayer(4, "rock").addPlayer(5, "paper");
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<|endoftext|>


<commit_before>module.exports = function(skill, info, bot, message, db) {
function isEmpty(obj) {
    for(var key in obj) {
        if(obj.hasOwnProperty(key))
            return false;
    }
    return true;
}
  var userData = message.text.match(/\<(.*?)\>/g);  //suss out any @mentions of users
  if (userData) {
    // if there is a user is mentioned initiate the challenge!
    var challenged = userData[0].replace(/[^\w\s]/gi, '');

    bot.api.users.info({user: challenged}, (error, response) => {
        bot.reply(message, ':rotating_light: <@' + response.user.name + '> you have been challenged to a game of ROCK:mountain: , PAPER:spiral_note_pad: , SCISSORS:scissors:! Prepare to defend your honor!');
    });
    bot.startPrivateConversation(message, privateConvo(bot, message));
  } else {
    //if no user challenged
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function privateConvo(bot, message) {
  const { user, channel } = message;

  return (err, convo) => {
    if (err) throw err;
    var rnd = Math.floor(Math.random()* 65);
    var encouragementArray = [
    'I believe in you!:hugging_face:',
    'I\'m sure you\'ll do your best!:heart:',
    'you\'re already a winner in my book!:wink:',
    'nothing can stop you!:smirk_cat:',
    'you have the eye of the tiger:smirk_cat:',
    'you have the heart of a champion:trophy:',
    'your lucky numbers are ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + '. :four_leaf_clover:',
    'take no prisoners! :rage1:',
    'Rock! On second thought- Paper! No Wait! Scissors...actually IDK',
    'Paper! NO, Rock! No Wait! Scissors; I made things worse, sorry. :disappointed:',
    'shoot straight!:grin:',
    'trust the force.',
    'trust in your instincts.',
    'Paper is on a roll!',
    'Get it. GET IT!',
    'You got this.:raised_hands:',
    'like a boss.:man_in_business_suit_levitating: ',
    'Establish dominance!',
    'what is best in life- Crush your enemies. See them driven before you. Hear the lamentations of their women.',
    'Rock it, or paper it? or _scissor_ it??:flushed:',
    'Cut em with scissors!',
    'Steady like a rock!',
    'give no quarter, and expect none either!:crossed_swords: ',
    'no retreat, no surrender!:crossed_swords: ',
    'I\'m not friends with losers- so try not to lose, eh? :trollface:',
    'If you\'re not first you\'re last!',
    'if you lose, don\'t bother coming home. :trollface:',
    'nothing can conquer your indomitable spirit!:raised_hands:'
    ];
    var randomEncouragement = Math.floor(Math.random()* encouragementArray.length);
    convo.ask('Do you want to play `paper`, `rock`, or `scissors`? No matter what you choose just remember: ' + encouragementArray[randomEncouragement], [
      {
        pattern: 'paper|rock|scissors',
        callback(response, convo) {
          // since no further messages are queued after this,
          // the conversation will end naturally with status === 'completed'
          convo.next();
        },
      }, {
        default: true,
        callback(response, convo) {
          convo.repeat();
          convo.next();
        },
      },
    ], { key: 'rockPaperScissors' }); // store the results in a field called rockPaperScissors

    convo.on('end', (convo) => {
      if (convo.status === 'completed') {
        var userPlay = convo.extractResponse('rockPaperScissors');
	var rpsObj = db.getSync("rps");

          if (err) throw err;

          if (rpsObj.hasOwnProperty('player1')== "" && rpsObj.hasOwnProperty('player2')== "") { //SWAP THIS LOGIC to support RPSSLSBSWG if all players have played!
		console.log(rpsObj.player1);
		  console.log(rpsObj.player2);
		  console.log('no one played');

          } else { //record player enter, note in channel
		console.log(rpsObj.player1);
		  console.log(rpsObj.player2);
		  console.log('someone played');

          }

      } else {
        // this happens if the conversation ended prematurely for some reason
        bot.reply(message, 'OK, nevermind!');
      }

	  });
 }
 };

  var gameEngine = require('./Rock-Paper-Spock');

    //bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    //})

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "paper"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<commit_msg>Update RockPaperScissors.js<commit_after>module.exports = function(skill, info, bot, message, db) {
function isEmpty(obj) {
    for(var key in obj) {
        if(obj.hasOwnProperty(key))
            return false;
    }
    return true;
}
  var userData = message.text.match(/\<(.*?)\>/g);  //suss out any @mentions of users
  if (userData) {
    // if there is a user is mentioned initiate the challenge!
    var challenged = userData[0].replace(/[^\w\s]/gi, '');

    bot.api.users.info({user: challenged}, (error, response) => {
        bot.reply(message, ':rotating_light: <@' + response.user.name + '> you have been challenged to a game of ROCK:mountain: , PAPER:spiral_note_pad: , SCISSORS:scissors:! Prepare to defend your honor!');
    });
    bot.startPrivateConversation(message, privateConvo(bot, message));
  } else {
    //if no user challenged
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function privateConvo(bot, message) {
  const { user, channel } = message;

  return (err, convo) => {
    if (err) throw err;
    var rnd = Math.floor(Math.random()* 65);
    var encouragementArray = [
    'I believe in you!:hugging_face:',
    'I\'m sure you\'ll do your best!:heart:',
    'you\'re already a winner in my book!:wink:',
    'nothing can stop you!:smirk_cat:',
    'you have the eye of the tiger:smirk_cat:',
    'you have the heart of a champion:trophy:',
    'your lucky numbers are ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + '. :four_leaf_clover:',
    'take no prisoners! :rage1:',
    'Rock! On second thought- Paper! No Wait! Scissors...actually IDK',
    'Paper! NO, Rock! No Wait! Scissors; I made things worse, sorry. :disappointed:',
    'shoot straight!:grin:',
    'trust the force.',
    'trust in your instincts.',
    'Paper is on a roll!',
    'Get it. GET IT!',
    'You got this.:raised_hands:',
    'like a boss.:man_in_business_suit_levitating: ',
    'Establish dominance!',
    'what is best in life- Crush your enemies. See them driven before you. Hear the lamentations of their women.',
    'Rock it, or paper it? or _scissor_ it??:flushed:',
    'Cut em with scissors!',
    'Steady like a rock!',
    'give no quarter, and expect none either!:crossed_swords: ',
    'no retreat, no surrender!:crossed_swords: ',
    'I\'m not friends with losers- so try not to lose, eh? :trollface:',
    'If you\'re not first you\'re last!',
    'if you lose, don\'t bother coming home. :trollface:',
    'nothing can conquer your indomitable spirit!:raised_hands:'
    ];
    var randomEncouragement = Math.floor(Math.random()* encouragementArray.length);
    convo.ask('Do you want to play `paper`, `rock`, or `scissors`? No matter what you choose just remember: ' + encouragementArray[randomEncouragement], [
      {
        pattern: 'paper|rock|scissors',
        callback(response, convo) {
          // since no further messages are queued after this,
          // the conversation will end naturally with status === 'completed'
          convo.next();
        },
      }, {
        default: true,
        callback(response, convo) {
          convo.repeat();
          convo.next();
        },
      },
    ], { key: 'rockPaperScissors' }); // store the results in a field called rockPaperScissors

    convo.on('end', (convo) => {
      if (convo.status === 'completed') {
        var userPlay = convo.extractResponse('rockPaperScissors');
	var rpsObj = db.getSync("rps");

          if (err) throw err;

          if (rpsObj.player1== "" && rpsObj.player2== "") { //SWAP THIS LOGIC to support RPSSLSBSWG if all players have played!
		console.log(rpsObj.player1);
		  console.log(rpsObj.player2);
		  console.log('no one played');

          } else { //record player enter, note in channel
		console.log(rpsObj.player1);
		  console.log(rpsObj.player2);
		  console.log('someone played');

          }

      } else {
        // this happens if the conversation ended prematurely for some reason
        bot.reply(message, 'OK, nevermind!');
      }

	  });
 }
 };

  var gameEngine = require('./Rock-Paper-Spock');

    //bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    //})

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "paper"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<|endoftext|>


<commit_before>module.exports = function(skill, info, bot, message, db) {
  var userData = message.text.match(/\<(.*?)\>/g);  //suss out any @mentions of users
  if (userData) {
    // if there is a user is mentioned initiate the challenge!
    var challenged = userData[0].replace(/[^\w\s]/gi, '');

    bot.api.users.info({user: challenged}, (error, response) => {
        bot.reply(message, ':rotating_light: <@' + response.user.name + '> you have been challenged to a game of ROCK:mountain: , PAPER:spiral_note_pad: , SCISSORS:scissors:! Prepare to defend your honor!');
    });
    bot.startPrivateConversation(message, privateConvo(bot, message));
  } else {
    //if no user challenged
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function privateConvo(bot, message) {
  const { user, channel } = message;
  return (err, convo) => {
    if (err) throw err;
    var rnd = Math.floor(Math.random()* 65);
    var encouragementArray = [
    'I believe in you!:hugging_face:',
    'I\'m sure you\'ll do your best!:heart:',
    'you\'re already a winner in my book!:wink:',
    'nothing can stop you!:smirk_cat:',
    'you have the eye of the tiger:smirk_cat:',
    'you have the heart of a champion:trophy:',
    'your lucky numbers are ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + '. :four_leaf_clover:',
    'take no prisoners! :rage1:',
    'Rock! On second thought- Paper! No Wait! Scissors...actually IDK',
    'Paper! NO, Rock! No Wait! Scissors; I made things worse, sorry. :disappointed:',
    'shoot straight!:grin:',
    'trust the force.',
    'trust in your instincts.',
    'Paper is on a roll!',
    'Get it. GET IT!',
    'You got this.:raised_hands:',
    'like a boss.:man_in_business_suit_levitating: ',
    'Establish dominance!',
    'what is best in life- Crush your enemies. See them driven before you. Hear the lamentations of their women.',
    'Rock it, or paper it? or _scissor_ it??:flushed:',
    'Cut em with scissors!',
    'Steady like a rock!',
    'give no quarter, and expect none either!:crossed_swords: ',
    'no retreat, no surrender!:crossed_swords: ',
    'I\'m not friends with losers- so try not to lose, eh? :trollface:',
    'If you\'re not first you\'re last!:medal:',
    'if you lose, don\'t bother coming home. :trollface:',
    'nothing can conquer your indomitable spirit!:raised_hands:'
    ];
    var randomEncouragement = Math.floor(Math.random()* encouragementArray.length);
    convo.ask('Do you want to play `paper`, `rock`, or `scissors`? No matter what you choose just remember: ' + encouragementArray[randomEncouragement], [
      {
        pattern: 'paper|rock|scissors',
        callback(response, convo) {
          // since no further messages are queued after this,
          // the conversation will end naturally with status === 'completed'
          convo.next();
        },
      }, {
        default: true,
        callback(response, convo) {
          convo.repeat();
          convo.next();
        },
      },
    ], { key: 'rockPaperScissors' }); // store the results in a field called rockPaperScissors

    convo.on('end', (convo) => {
      if (convo.status === 'completed') {
        var userPlay = convo.extractResponse('rockPaperScissors');
	var rpsObj = db.getSync("rps");
          if (err) throw err;

          if (rpsObj.played === "") { //no one played yet. enter player move and note to channel
		console.log(rpsObj.played);
		  console.log('no one played');
		  rpsObj.played=message.user + '-' + userPlay;
		  var id = db.saveSync("rps", rpsObj);
		  bot.reply(message, message.user + ' played!');
          } else { //someone played. enter current player move and existing move to game engine. print results. update w-l records for players. and clear played entry
		console.log(rpsObj.played);
		console.log('someone played');
		var gameEngine = require('./Rock-Paper-Spock');
  		var instance = new gameEngine(gameEngine.DefaultRules);
		var player1 = rpsObj.played.split("-");
  		instance.addPlayer({id: player1[0], sign: player1[1]});
  		instance.addPlayer({id: message.user, sign: userPlay});
  		instance.play();
  		console.log(instance.winner);
		  bot.reply(message, instance.winner + ' won!');

          }

      } else {
        // this happens if the conversation ended prematurely for some reason
        bot.reply(message, 'OK, nevermind!');
      }

	  });
 }
 };

};
<commit_msg>Update RockPaperScissors.js<commit_after>module.exports = function(skill, info, bot, message, db) {
  var userData = message.text.match(/\<(.*?)\>/g);  //suss out any @mentions of users
  if (userData) {
    // if there is a user is mentioned initiate the challenge!
    var challenged = userData[0].replace(/[^\w\s]/gi, '');

    bot.api.users.info({user: challenged}, (error, response) => {
        bot.reply(message, ':rotating_light: <@' + response.user.name + '> you have been challenged to a game of ROCK:mountain: , PAPER:spiral_note_pad: , SCISSORS:scissors:! Prepare to defend your honor!');
    });
    bot.startPrivateConversation(message, privateConvo(bot, message));
  } else {
    //if no user challenged
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function privateConvo(bot, message) {
  const { user, channel } = message;
  return (err, convo) => {
    if (err) throw err;
    var rnd = Math.floor(Math.random()* 65);
    var encouragementArray = [
    'I believe in you!:hugging_face:',
    'I\'m sure you\'ll do your best!:heart:',
    'you\'re already a winner in my book!:wink:',
    'nothing can stop you!:smirk_cat:',
    'you have the eye of the tiger:smirk_cat:',
    'you have the heart of a champion:trophy:',
    'your lucky numbers are ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + ', ' + rnd + '. :four_leaf_clover:',
    'take no prisoners! :rage1:',
    'Rock! On second thought- Paper! No Wait! Scissors...actually IDK',
    'Paper! NO, Rock! No Wait! Scissors; I made things worse, sorry. :disappointed:',
    'shoot straight!:grin:',
    'trust the force.',
    'trust in your instincts.',
    'Paper is on a roll!',
    'Get it. GET IT!',
    'You got this.:raised_hands:',
    'like a boss.:man_in_business_suit_levitating: ',
    'Establish dominance!',
    'what is best in life- Crush your enemies. See them driven before you. Hear the lamentations of their women.',
    'Rock it, or paper it? or _scissor_ it??:flushed:',
    'Cut em with scissors!',
    'Steady like a rock!',
    'give no quarter, and expect none either!:crossed_swords: ',
    'no retreat, no surrender!:crossed_swords: ',
    'I\'m not friends with losers- so try not to lose, eh? :trollface:',
    'If you\'re not first you\'re last!:medal:',
    'if you lose, don\'t bother coming home. :trollface:',
    'nothing can conquer your indomitable spirit!:raised_hands:'
    ];
    var randomEncouragement = Math.floor(Math.random()* encouragementArray.length);
    convo.ask('Do you want to play `paper`, `rock`, or `scissors`? No matter what you choose just remember: ' + encouragementArray[randomEncouragement], [
      {
        pattern: 'paper|rock|scissors',
        callback(response, convo) {
          // since no further messages are queued after this,
          // the conversation will end naturally with status === 'completed'
          convo.next();
        },
      }, {
        default: true,
        callback(response, convo) {
          convo.repeat();
          convo.next();
        },
      },
    ], { key: 'rockPaperScissors' }); // store the results in a field called rockPaperScissors

    convo.on('end', (convo) => {
      if (convo.status === 'completed') {
        var userPlay = convo.extractResponse('rockPaperScissors');
	var rpsObj = db.getSync("rps");
          if (err) throw err;

          if (rpsObj.played === "") { //no one played yet. enter player move and note to channel
		console.log(rpsObj.played);
		  console.log('no one played');
		  rpsObj.played=message.user + '-' + userPlay;
		  var id = db.saveSync("rps", rpsObj);
		  bot.reply(message, message.user + ' played!');
          } else { //someone played. enter current player move and existing move to game engine. print results. update w-l records for players. and clear played entry
		console.log(rpsObj.played);
		console.log('someone played');
		var gameEngine = require('./Rock-Paper-Spock');
  		var instance = new gameEngine(gameEngine.DefaultRules);
		var player1 = rpsObj.played.split("-");
  		instance.addPlayer({id: player1[0], sign: player1[1]});
  		instance.addPlayer({id: message.user, sign: userPlay});
  		instance.play();
  		console.log(instance.winner);
		  bot.reply(instance.winner.id + ' won!');

          }

      } else {
        // this happens if the conversation ended prematurely for some reason
        bot.reply(message, 'OK, nevermind!');
      }

	  });
 }
 };

};
<|endoftext|>


<commit_before>#!/usr/bin/env node
const argv = require('argh').argv
const proc = require('../')

function npinit () {
  // usage, version and projectName
  const noCommands = process.argv.length <= 2 && process.stdin.isTTY
  const noProjName  = argv.argv === undefined || process.argv[2] !== argv.argv[0]
  const chk4help = (argv.argv !== undefined && argv.argv[0] === 'help') || argv.h || argv.help
  const chk4test  = (argv.argv !== undefined && argv.argv[0] === 'test')

  // usage
  if (noCommands || noProjName || chk4help) usage()
  // version
  if (argv.v || argv.version) vers()

  // default options
  var opts = {
    install: false,
    devpackages: [],
    packages: [],
    git: false,
    verbose: false,
    dryrun: false,
    files: {
      gitignore: false,
      eslintrc: true,
      index: true,
      license: false,
      package: true,
      readme: true,
      test: false,
      travis: false
    },
    meta: {
      date: new Date().toLocaleString(),
      year: new Date().getFullYear().toString(),
      packageName: projName(),
      type: 'private',
      repo: 'none',
      remote: false,
      push: false,
      author: argv.author,
      email: argv.email,
      name: argv.user,
      url: argv.url,
      version: argv.pkgv,
      license: argv.license
    }
  }

  if (argv.verbose) opts.verbose = true
  if (argv.dry || argv.d) opts.dryrun = true

  // git repository configuration
  // check for private and public projects being created together
  const pub = (argv.g || argv.github)
  const priv = (argv.r || argv.repo)

  // public repo if option -g or -github
  if (!priv && pub) {
    opts.meta.type = 'public'
    opts.meta.remote = 'hubCreate'
    opts.meta.push = true
    opts.files.license = true
    opts.files.travis = true
    repo()
    chkRemote()
  }

  // private repo options:
  // together: -g or --github and -r or --repo
  //  or just: -r or --repo
  if ((priv && pub) || priv) repo()

  // install dependencies configuration
  // check for user install dependencies
  if (argv.dev) devpackages()
  if (argv.dep) packages()

  // misc overrides
  const description = argv.desc || argv.description
  if (description) opts.meta.description = description
  else opts.meta.description = 'An awesome module being created'

  // tags for package.json
  // if (argv.tags) opts.meta.tags = makeArray(argv.tags)
  // else opts.meta.tags = ''

  // get user information, display options & initialize project
  return proc(opts)

  // configuration functions
  // ///////////////////////////////////////////////////////////////////////////////
  function usage () {
    console.log(function () {
    /*

    Usage: npinit <packageName> [options]
           npinit <packageName> --dry [options]
           npinit -n [options]
           npinit -dry [options]

    Options:

      -h, --help          output usage information

      -v, --version       output the version number

      --dry               dry run displaying metadata used for generation

      -n, --new           new private module. for use without a packageName. the default
                          packageName `testproj###` will be assigned. random number `###`
                          generated to avoid potential conflicts.

      -g, --github        new public module. a git repository will be
                          automactically initialized and pushed to gihub. a packageName
                          is required. [default mode is private module, no git repo]
                          running option -n or --new with -g or --github is equivalent to
                          option `-nr` or `--new --repo` initializing a new private
                          module with a git repository. packageName will not be required.
                          options --addRemote, --noRemote and --noPush are inactive in
                          this mode when `-ng` are run together.

      -r, --repo          initialize a git repository when generating a private module
                          [default is none]

      --remote            process will use the generic git command:

                            `git remote add origin https://github.com/username/repo.git`

                          username and repo will be automactically added. Leaving this
                          option off will use `hub` (https://github.com/github/hub)
                          to createthe remote repository. [default command `hub create`].
                          You will have to enter your github username and password
                          if NOT using the --noPush option.

      --no-remote         do not create a remote repository on github. no-remote
                          will not push a repo to github.
                          it will also override the default remote command `hub create`
                          if addRemote is not present when creating a public module
                          with flags -g or --github.

      -P, --noPush        do not push repository to github. use only with
                          flags -g or --github [default is push]

      --D <string>        a list of node modules to install, i.e.,
                          `--D "lodash moment"` or `--D "lodash, moment"`.
                          [npm i --save packages]

      --d <string>        a list of node dev modules to install, i.e.,
                          `--d "tape istanbul"` or `--d "tape, istanbul"`.
                          [npm i --save-dev devpackages]

    Overrides:

      --desc    <string>  description for package.json and github repository if using `hub`.
      --author  <string>  author name for project. [default reads from .npmrc or 'Your Name']
      --email   <string>  email for project. [default reads from .npmrc or 'your@email.com']
      --user    <string>  github username [default reads from .npmrc or 'githubName']
      --license <string>  license type for project. [default reads from .npmrc => ISC]
      --pkgv    <string>  semantic version for project [default reads from .npmrc => 1.0.0]

    */
    }.toString().split(/\n/).slice(2, -2).join('\n'))
    process.exit(0)
  }

  function vers () {
    process.stdout.write(require('../package.json').version + '\n')
    process.exit(0)
  }

  function projName () {
    if (chk4test) return makePkgName(true)
    else return makePkgName(false)
  }

  function makePkgName (choice) {
    var testName = 'test-' + Math.floor(Math.random() * (1000 - 101) + 101)

    switch (choice) {
      case false:
        var tmp = argv.argv[0].toString()
        if (tmp.length === 0) return testName
        return slug(argv.argv[0])
      case true: return testName
    }
  }

  function slug (str) {
    return str.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').replace(/^-/g, '').toLowerCase()
  }

  // configure private git repository
  function repo () {
    opts.git = true
    opts.meta.repo = 'init'
    opts.files.gitignore = true
  }

  function chkRemote () {
    if (argv.remote) {
      opts.meta.remote = 'addRemote'
    } else if (argv.remote === false) {
      opts.meta.type = 'private'
      opts.meta.remote = false
      opts.meta.push = false
    }
  }

  // configure user installed devDependencies
  function devpackages () {
    opts.devpackages = makeArray(argv.dev)
    opts.files.test = true
    opts.install = true
  }

  // configure user installed dependencies
  function packages () {
    opts.packages =  makeArray(argv.dep)
    opts.install = true
  }

  function makeArray (str) {
    return str.toLowerCase().replace(/\,/g, '').split(' ')
  }
}

npinit()
<commit_msg>refactor: update bin/npinit<commit_after>#!/usr/bin/env node
const argv = require('argh').argv
const proc = require('../')

function npinit () {
  // usage, version and projectName
  const noCommands = process.argv.length <= 2 && process.stdin.isTTY
  const noProjName  = argv.argv === undefined || process.argv[2] !== argv.argv[0]
  const chk4help = (argv.argv !== undefined && argv.argv[0] === 'help') || argv.h || argv.help
  const chk4test  = (argv.argv !== undefined && argv.argv[0] === 'test')
  const chk4vers = argv.v || argv.version

  // usage
  if (noCommands || (noProjName && !chk4vers) || chk4help) usage()

  // version
  if (chk4vers) vers()

  // default options
  var opts = {
    install: false,
    devpackages: [],
    packages: [],
    git: false,
    verbose: false,
    dryrun: false,
    files: {
      gitignore: false,
      eslintrc: true,
      index: true,
      license: false,
      package: true,
      readme: true,
      test: false,
      travis: false
    },
    meta: {
      date: new Date().toLocaleString(),
      year: new Date().getFullYear().toString(),
      packageName: projName(),
      type: 'private',
      repo: 'none',
      remote: false,
      push: false,
      author: argv.author,
      email: argv.email,
      name: argv.user,
      url: argv.url,
      version: argv.pkgv,
      license: argv.license
    }
  }

  if (argv.verbose) opts.verbose = true
  if (argv.dry || argv.d) opts.dryrun = true

  // git repository configuration
  // check for private and public projects being created together
  const pub = (argv.g || argv.github)
  const priv = (argv.r || argv.repo)

  // public repo if option -g or -github
  if (!priv && pub) {
    opts.meta.type = 'public'
    opts.meta.remote = 'hubCreate'
    opts.meta.push = true
    opts.files.license = true
    opts.files.travis = true
    repo()
    chkRemote()
  }

  // private repo options:
  // together: -g or --github and -r or --repo
  //  or just: -r or --repo
  if ((priv && pub) || priv) repo()

  // install dependencies configuration
  // check for user install dependencies
  if (argv.dev) devpackages()
  if (argv.dep) packages()

  // misc overrides
  const description = argv.desc || argv.description
  if (description) opts.meta.description = description
  else opts.meta.description = 'An awesome module being created'

  // tags for package.json
  // if (argv.tags) opts.meta.tags = makeArray(argv.tags)
  // else opts.meta.tags = ''

  // get user information, display options & initialize project
  return proc(opts)

  // configuration functions
  // ///////////////////////////////////////////////////////////////////////////////
  function usage () {
    console.log(function () {
    /*

    Usage: npinit <packageName> [options]
           npinit <packageName> --dry [options]
           npinit -n [options]
           npinit -dry [options]

    Options:

      -h, --help          output usage information

      -v, --version       output the version number

      --dry               dry run displaying metadata used for generation

      -n, --new           new private module. for use without a packageName. the default
                          packageName `testproj###` will be assigned. random number `###`
                          generated to avoid potential conflicts.

      -g, --github        new public module. a git repository will be
                          automactically initialized and pushed to gihub. a packageName
                          is required. [default mode is private module, no git repo]
                          running option -n or --new with -g or --github is equivalent to
                          option `-nr` or `--new --repo` initializing a new private
                          module with a git repository. packageName will not be required.
                          options --addRemote, --noRemote and --noPush are inactive in
                          this mode when `-ng` are run together.

      -r, --repo          initialize a git repository when generating a private module
                          [default is none]

      --remote            process will use the generic git command:

                            `git remote add origin https://github.com/username/repo.git`

                          username and repo will be automactically added. Leaving this
                          option off will use `hub` (https://github.com/github/hub)
                          to createthe remote repository. [default command `hub create`].
                          You will have to enter your github username and password
                          if NOT using the --noPush option.

      --no-remote         do not create a remote repository on github. no-remote
                          will not push a repo to github.
                          it will also override the default remote command `hub create`
                          if addRemote is not present when creating a public module
                          with flags -g or --github.

      -P, --noPush        do not push repository to github. use only with
                          flags -g or --github [default is push]

      --D <string>        a list of node modules to install, i.e.,
                          `--D "lodash moment"` or `--D "lodash, moment"`.
                          [npm i --save packages]

      --d <string>        a list of node dev modules to install, i.e.,
                          `--d "tape istanbul"` or `--d "tape, istanbul"`.
                          [npm i --save-dev devpackages]

    Overrides:

      --desc    <string>  description for package.json and github repository if using `hub`.
      --author  <string>  author name for project. [default reads from .npmrc or 'Your Name']
      --email   <string>  email for project. [default reads from .npmrc or 'your@email.com']
      --user    <string>  github username [default reads from .npmrc or 'githubName']
      --license <string>  license type for project. [default reads from .npmrc => ISC]
      --pkgv    <string>  semantic version for project [default reads from .npmrc => 1.0.0]

    */
    }.toString().split(/\n/).slice(2, -2).join('\n'))
    process.exit(0)
  }

  function vers () {
    process.stdout.write(require('../package.json').version + '\n')
    process.exit(0)
  }

  function projName () {
    if (chk4test) return makePkgName(true)
    else return makePkgName(false)
  }

  function makePkgName (choice) {
    var testName = 'test-' + Math.floor(Math.random() * (1000 - 101) + 101)

    switch (choice) {
      case false:
        var tmp = argv.argv[0].toString()
        if (tmp.length === 0) return testName
        return slug(argv.argv[0])
      case true: return testName
    }
  }

  function slug (str) {
    return str.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').replace(/^-/g, '').toLowerCase()
  }

  // configure private git repository
  function repo () {
    opts.git = true
    opts.meta.repo = 'init'
    opts.files.gitignore = true
  }

  function chkRemote () {
    if (argv.remote) {
      opts.meta.remote = 'addRemote'
    } else if (argv.remote === false) {
      opts.meta.type = 'private'
      opts.meta.remote = false
      opts.meta.push = false
    }
  }

  // configure user installed devDependencies
  function devpackages () {
    opts.devpackages = makeArray(argv.dev)
    opts.files.test = true
    opts.install = true
  }

  // configure user installed dependencies
  function packages () {
    opts.packages =  makeArray(argv.dep)
    opts.install = true
  }

  function makeArray (str) {
    return str.toLowerCase().replace(/\,/g, '').split(' ')
  }
}

npinit()
<|endoftext|>


<commit_before>#!/usr/bin/env node

// run with "DEBUG=axios" to see debug logs
require('axios-debug-log')({
  request: function (debug, config) {
    debug(`${config.method.toUpperCase()} ${config.url}`)
  },
  response: () => {},
  error: () => {}
})

const axios = require('axios')
const Bottleneck = require('bottleneck')
const chalk = require('chalk')
const cloneDeep = require('lodash/cloneDeep')
const { diff, diffString } = require('json-diff')
const glob = require('glob')
const humanize = require('humanize-string')

const env = require('../lib/env')
const isTravisCronJob = require('../lib/is-travis-cron-job')
const normalize = require('../lib/normalize')
const notifyAboutFixturesChanges = require('../lib/notify-about-fixtures-changes')
const read = require('../lib/read')
const recordScenario = require('../lib/record-scenario')
const write = require('../lib/write')

const argv = require('minimist')(process.argv.slice(2), {
  boolean: ['update', 'test-cached']
})
const doUpdate = argv.update
const selectedScenarios = argv._
const hasSelectedScenarios = selectedScenarios.length > 0

const scenarios = hasSelectedScenarios ? selectedScenarios : glob.sync('scenarios/**/record.js')
const diffs = []

// run scenarios one by one
scenarios.reduce(async (promise, scenarioPath) => {
  await promise
  const fixtureName = scenarioPath.replace(/(^scenarios\/|\/record\.js$)/g, '')
  const [domain, title] = fixtureName.split('/')
  console.log('')
  console.log(`⏯  ${chalk.bold(domain)}: ${humanize(title.replace('.js', ''))} ...`)

  const request = axios.create({
    baseURL: `https://${domain}`,
    maxRedirects: 0 // record redirects explicitly
  })

  // set Proxy for unauthenticated requests to https://api.github.com
  if (env.FIXTURES_PROXY) {
    request.interceptors.request.use(config => {
      if (config.headers.Authorization) {
        return config
      }

      if (config.baseURL !== 'https://api.github.com') {
        return config
      }

      config.baseURL = env.FIXTURES_PROXY

      return config
    })
  }

  // throttle writing requests
  // https://developer.github.com/v3/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits
  const limiter = new Bottleneck({
    maxConcurrent: 1,
    minTime: 3000
  })
  request.interceptors.request.use(config => {
    if (!['POST', 'PATCH', 'PUT', 'DELETE'].includes(config.method.toUpperCase())) {
      return config
    }

    return limiter.schedule(async () => config)
  })

  // set strict validation header
  // TODO: remove after Nov 1, see https://blog.github.com/changelog/2018-09-26-new-preview-header-for-strict-validation-in-rest-api/
  request.interceptors.request.use(config => {
    config.headers.Accept = `${config.headers.Accept},application/vnd.github.speedy-preview+json`
    return config
  })

  const oldNormalizedFixtures = await read(fixtureName)
  const newRawFixtures = await recordScenario({
    request: request,
    scenario: require(`../scenarios/${fixtureName}/record`)
  })

  const scenarioState = {
    commitSha: {}, // map original commit sha hashes to normalized commit hashes
    ids: {}
  }

  const newNormalizedFixtures = await Promise.all(newRawFixtures
    .map(cloneDeep)
    .filter(hasntIgnoreHeader)
    .map(normalize.bind(null, scenarioState)))

  const fixturesDiffs = diff(newNormalizedFixtures, oldNormalizedFixtures)
  if (!fixturesDiffs) {
    console.log(`✅  Fixtures are up-to-date`)
    return
  }

  diffs.push({
    name: fixtureName,
    changes: fixturesDiffs,
    newNormalizedFixtures,
    oldNormalizedFixtures,
    newRawFixtures
  })

  if (fixturesDiffs[0][0] === '-') {
    if (doUpdate) {
      console.log(`📼  New fixtures recorded`)
      return write(fixtureName, {
        normalized: newNormalizedFixtures,
        raw: newRawFixtures
      })
    }
    console.log(`❌  "${fixtureName}" looks like a new fixture`)
    return
  }

  if (doUpdate) {
    console.log(`📼  Fixture updates recorded`)
    return write(fixtureName, {
      normalized: newNormalizedFixtures,
      raw: newRawFixtures
    })
  }

  console.log(`❌  Fixtures are not up-to-date`)

  if (!isTravisCronJob()) {
    console.log(diffString(oldNormalizedFixtures, newNormalizedFixtures))
    console.log(`💁  Update fixtures with \`${chalk.bold('bin/record.js --update')}\``)
  }
}, Promise.resolve())

  .then(() => {
    if (diffs.length === 0) {
      if (isTravisCronJob()) {
        console.log('🤖  No fixture changes detected in cron job.')
      }
      return
    }

    if (doUpdate) {
      return
    }

    if (isTravisCronJob()) {
      return notifyAboutFixturesChanges(diffs)
    }

    console.log(`${diffs.length} fixtures are out of date. Exit 1`)
    process.exit(1)
  })

  .catch((error) => {
    if (!error.response) {
      console.log(error)
      process.exit(1)
    }

    console.log(error.toString())
    console.log('REQUEST')
    console.log(`${error.config.method.toUpperCase()} ${error.config.url}`)
    console.log('RESPONSE HEADERS')
    console.log(JSON.stringify(error.response.headers, null, 2))
    console.log('RESPONSE BODY')
    console.log(JSON.stringify(error.response.data, null, 2))
    process.exit(1)
  })

function hasntIgnoreHeader (fixture) {
  const hasIgnoreHeader = 'x-octokit-fixture-ignore' in fixture.reqheaders
  return !hasIgnoreHeader
}
<commit_msg>docs: speedy preview comment<commit_after>#!/usr/bin/env node

// run with "DEBUG=axios" to see debug logs
require('axios-debug-log')({
  request: function (debug, config) {
    debug(`${config.method.toUpperCase()} ${config.url}`)
  },
  response: () => {},
  error: () => {}
})

const axios = require('axios')
const Bottleneck = require('bottleneck')
const chalk = require('chalk')
const cloneDeep = require('lodash/cloneDeep')
const { diff, diffString } = require('json-diff')
const glob = require('glob')
const humanize = require('humanize-string')

const env = require('../lib/env')
const isTravisCronJob = require('../lib/is-travis-cron-job')
const normalize = require('../lib/normalize')
const notifyAboutFixturesChanges = require('../lib/notify-about-fixtures-changes')
const read = require('../lib/read')
const recordScenario = require('../lib/record-scenario')
const write = require('../lib/write')

const argv = require('minimist')(process.argv.slice(2), {
  boolean: ['update', 'test-cached']
})
const doUpdate = argv.update
const selectedScenarios = argv._
const hasSelectedScenarios = selectedScenarios.length > 0

const scenarios = hasSelectedScenarios ? selectedScenarios : glob.sync('scenarios/**/record.js')
const diffs = []

// run scenarios one by one
scenarios.reduce(async (promise, scenarioPath) => {
  await promise
  const fixtureName = scenarioPath.replace(/(^scenarios\/|\/record\.js$)/g, '')
  const [domain, title] = fixtureName.split('/')
  console.log('')
  console.log(`⏯  ${chalk.bold(domain)}: ${humanize(title.replace('.js', ''))} ...`)

  const request = axios.create({
    baseURL: `https://${domain}`,
    maxRedirects: 0 // record redirects explicitly
  })

  // set Proxy for unauthenticated requests to https://api.github.com
  if (env.FIXTURES_PROXY) {
    request.interceptors.request.use(config => {
      if (config.headers.Authorization) {
        return config
      }

      if (config.baseURL !== 'https://api.github.com') {
        return config
      }

      config.baseURL = env.FIXTURES_PROXY

      return config
    })
  }

  // throttle writing requests
  // https://developer.github.com/v3/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits
  const limiter = new Bottleneck({
    maxConcurrent: 1,
    minTime: 3000
  })
  request.interceptors.request.use(config => {
    if (!['POST', 'PATCH', 'PUT', 'DELETE'].includes(config.method.toUpperCase())) {
      return config
    }

    return limiter.schedule(async () => config)
  })

  // set strict validation header, remove once stricter validations are applied
  // to all requests: https://developer.github.com/changes/2018-11-07-strict-validation/
  request.interceptors.request.use(config => {
    config.headers.Accept = `${config.headers.Accept},application/vnd.github.speedy-preview+json`
    return config
  })

  const oldNormalizedFixtures = await read(fixtureName)
  const newRawFixtures = await recordScenario({
    request: request,
    scenario: require(`../scenarios/${fixtureName}/record`)
  })

  const scenarioState = {
    commitSha: {}, // map original commit sha hashes to normalized commit hashes
    ids: {}
  }

  const newNormalizedFixtures = await Promise.all(newRawFixtures
    .map(cloneDeep)
    .filter(hasntIgnoreHeader)
    .map(normalize.bind(null, scenarioState)))

  const fixturesDiffs = diff(newNormalizedFixtures, oldNormalizedFixtures)
  if (!fixturesDiffs) {
    console.log(`✅  Fixtures are up-to-date`)
    return
  }

  diffs.push({
    name: fixtureName,
    changes: fixturesDiffs,
    newNormalizedFixtures,
    oldNormalizedFixtures,
    newRawFixtures
  })

  if (fixturesDiffs[0][0] === '-') {
    if (doUpdate) {
      console.log(`📼  New fixtures recorded`)
      return write(fixtureName, {
        normalized: newNormalizedFixtures,
        raw: newRawFixtures
      })
    }
    console.log(`❌  "${fixtureName}" looks like a new fixture`)
    return
  }

  if (doUpdate) {
    console.log(`📼  Fixture updates recorded`)
    return write(fixtureName, {
      normalized: newNormalizedFixtures,
      raw: newRawFixtures
    })
  }

  console.log(`❌  Fixtures are not up-to-date`)

  if (!isTravisCronJob()) {
    console.log(diffString(oldNormalizedFixtures, newNormalizedFixtures))
    console.log(`💁  Update fixtures with \`${chalk.bold('bin/record.js --update')}\``)
  }
}, Promise.resolve())

  .then(() => {
    if (diffs.length === 0) {
      if (isTravisCronJob()) {
        console.log('🤖  No fixture changes detected in cron job.')
      }
      return
    }

    if (doUpdate) {
      return
    }

    if (isTravisCronJob()) {
      return notifyAboutFixturesChanges(diffs)
    }

    console.log(`${diffs.length} fixtures are out of date. Exit 1`)
    process.exit(1)
  })

  .catch((error) => {
    if (!error.response) {
      console.log(error)
      process.exit(1)
    }

    console.log(error.toString())
    console.log('REQUEST')
    console.log(`${error.config.method.toUpperCase()} ${error.config.url}`)
    console.log('RESPONSE HEADERS')
    console.log(JSON.stringify(error.response.headers, null, 2))
    console.log('RESPONSE BODY')
    console.log(JSON.stringify(error.response.data, null, 2))
    process.exit(1)
  })

function hasntIgnoreHeader (fixture) {
  const hasIgnoreHeader = 'x-octokit-fixture-ignore' in fixture.reqheaders
  return !hasIgnoreHeader
}
<|endoftext|>


<commit_before>#! /usr/bin/env node

var yargs = require('yargs')
  .command('init [preset] [path]', 'initialise browserstack.json with preset and test runner path', function(yargs) {
    return yargs.option('preset', {
      type: 'string',
      default: 'default',
      description: 'name of preset json file(without extension)(present in node_modules/browserstack-runner/presets to be used while initiating'
    })
    .option('path', {
      type: 'string',
      default: '/path/to/test/runner',
      description: 'path to test runner to be inserted in browserstack.json'
    })
  })
  .option('browsers', {
    alias: 'b',
    type: 'array',
    description: 'list of space separatedbrowsers keys as described in json file'
  })
  .option('path', {
    type: 'string',
    description: 'path to test file'
  })
  .option('version', {
    alias: 'V',
    description: 'browserstack-runner version'
  })
  .option('pid', {
    type: 'string',
    description: 'path to pid file'
  })
  .option('verbose', {
    alias: 'v',
    description: 'verbose logging'
  }).argv;

if (yargs['verbose']) {
  global.logLevel = process.env.LOG_LEVEL || 'debug';
} else {
  global.logLevel = 'info';
}
var path = require('path'),
  config;

if(yargs['_'].indexOf('init') !== -1) {
  module.exports.preset = yargs['preset'];
  module.exports.path = yargs['path'];
  require('./init.js');
  return;
}

var config_path = process.env.BROWSERSTACK_JSON || 'browserstack.json';
config_path = path.resolve(path.relative(process.cwd(), config_path));

console.log('Using config:', config_path);
try {
  config = require(config_path);
} catch (e) {
  if (e.code === 'MODULE_NOT_FOUND') {
    console.error('Configuration file `browserstack.json` is missing.');
    throw new Error('Configuration file `browserstack.json` is missing.');
  } else {
    console.error('Invalid configuration in `browserstack.json` file');
    console.error(e.message);
    console.error(e.stack);
    throw new Error('Invalid configuration in `browserstack.json` file');
  }
}

// extract a path to file to store tunnel pid
if(yargs['pid']) {
  if(yargs['pid'].length > 0) {
    config.tunnel_pid_file = yargs['pid'];
  } else {
    console.error('Error while parsing flag --pid. Usage: --pid=/path/to/file');
  }
}

// filter browsers according to from command line arguments
if(yargs['browsers']) {
  if(yargs['browsers'].length > 0) {
    config.browsers = config.browsers.filter( function(browser) {
      return yargs['browsers'].indexOf(browser['cli_key']) !== -1;
    });
  } else {
    console.error('No browser keys specified. Usage --browsers <key1> <key2> ...');
  }
}

// test file path from cli arguments
config.test_path = yargs['path'] || config.test_path;

var runner = require('./cli.js');
runner.run(config, function(err) {
  if(err) {
    if (err.name === 'TestsFailedError') {
      console.error('Exit with fail due to some tests failure.');
    } else {
      console.error(err);
      console.error(err.stack);
      console.error('Invalid Command');
    }
    process.exit(1);
  }
  process.exit(0);
});
<commit_msg>Fixed jshint error in runner.js<commit_after>#! /usr/bin/env node

var yargs = require('yargs')
  .command('init [preset] [path]', 'initialise browserstack.json with preset and test runner path', function(yargs) {
    return yargs.option('preset', {
      type: 'string',
      default: 'default',
      description: 'name of preset json file(without extension)(present in node_modules/browserstack-runner/presets to be used while initiating'
    })
    .option('path', {
      type: 'string',
      default: '/path/to/test/runner',
      description: 'path to test runner to be inserted in browserstack.json'
    });
  })
  .option('browsers', {
    alias: 'b',
    type: 'array',
    description: 'list of space separatedbrowsers keys as described in json file'
  })
  .option('path', {
    type: 'string',
    description: 'path to test file'
  })
  .option('version', {
    alias: 'V',
    description: 'browserstack-runner version'
  })
  .option('pid', {
    type: 'string',
    description: 'path to pid file'
  })
  .option('verbose', {
    alias: 'v',
    description: 'verbose logging'
  }).argv;

if (yargs['verbose']) {
  global.logLevel = process.env.LOG_LEVEL || 'debug';
} else {
  global.logLevel = 'info';
}
var path = require('path'),
  config;

if(yargs['_'].indexOf('init') !== -1) {
  module.exports.preset = yargs['preset'];
  module.exports.path = yargs['path'];
  require('./init.js');
  return;
}

var config_path = process.env.BROWSERSTACK_JSON || 'browserstack.json';
config_path = path.resolve(path.relative(process.cwd(), config_path));

console.log('Using config:', config_path);
try {
  config = require(config_path);
} catch (e) {
  if (e.code === 'MODULE_NOT_FOUND') {
    console.error('Configuration file `browserstack.json` is missing.');
    throw new Error('Configuration file `browserstack.json` is missing.');
  } else {
    console.error('Invalid configuration in `browserstack.json` file');
    console.error(e.message);
    console.error(e.stack);
    throw new Error('Invalid configuration in `browserstack.json` file');
  }
}

// extract a path to file to store tunnel pid
if(yargs['pid']) {
  if(yargs['pid'].length > 0) {
    config.tunnel_pid_file = yargs['pid'];
  } else {
    console.error('Error while parsing flag --pid. Usage: --pid=/path/to/file');
  }
}

// filter browsers according to from command line arguments
if(yargs['browsers']) {
  if(yargs['browsers'].length > 0) {
    config.browsers = config.browsers.filter( function(browser) {
      return yargs['browsers'].indexOf(browser['cli_key']) !== -1;
    });
  } else {
    console.error('No browser keys specified. Usage --browsers <key1> <key2> ...');
  }
}

// test file path from cli arguments
config.test_path = yargs['path'] || config.test_path;

var runner = require('./cli.js');
runner.run(config, function(err) {
  if(err) {
    if (err.name === 'TestsFailedError') {
      console.error('Exit with fail due to some tests failure.');
    } else {
      console.error(err);
      console.error(err.stack);
      console.error('Invalid Command');
    }
    process.exit(1);
  }
  process.exit(0);
});
<|endoftext|>