<commit_before>var Coffee = {
  debug: 0,
  debugString: "200\n1. March 14:28:371",

  msgNoPots: 'Ingen kanner i dag',
  msgNoCoffee: 'Kaffen har ikke blitt satt på',
  msgFormatError: 'Feil i kaffeformat',
  msgConnectionError: 'Frakoblet fra kaffekanna',
  msgComforting: 'Så så, det er sikkert kaffe :)',
  msgNotification: 'Kaffen er satt på, straks klar :)',

  get: function(pretty, callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    var api = Affiliation.org[localStorage.affiliationKey1].hw.apis.coffee;

    // Receives the status for the coffee pot
    var self = this;
    Ajaxer.getPlainText({
      url: api,
      success: function(data) {

        // If coffee debugging is enabled
        if (self.debug) {
          data = self.debugString;
        }

        try {
          // Split into pot number and age of last pot
          var pieces = data.split("\n");
          var pots = Number(pieces[0]);
          var ageString = pieces[1];

          // Coffee made today?
          if (self.isMadeToday(ageString)) {

            // Calculate minute difference from right now
            var now = new Date();
            var coffeeTime = String(ageString.match(/\d+:\d+:\d+/)).split(':');
            var then = new Date(now.getFullYear(), now.getMonth(), now.getDate(), coffeeTime[0], coffeeTime[1]);
            var age = self.minuteDiff(then);

            // If pretty strings are requested
            if (pretty) {
              age = self.prettyAgeString(age, coffeeTime);
              pots = self.prettyPotsString(pots);
            }

            // Call it back
            callback(pots, age);
          }
          else {
            // Coffee was not made today
            if (pretty) {
              callback(self.msgNoPots, self.msgNoCoffee);
            }
            else {
              callback(0, 0);
            }
          }
        } catch (err) {
          if (self.debug) console.log('ERROR: Coffee format is wrong:', err);
          callback(self.msgFormatError, self.msgComforting);
        }
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR: Failed to get coffee pot status.');
        callback(self.msgConnectionError, self.msgComforting);
      },
    });
  },

  isMadeToday: function(ageString) {
    // Get now
    var now = new Date();
    // Figure out which date the coffee was made
    var dateObject = ageString.match(/\d+\. [a-zA-Z]+/);
    var dateString = String(dateObject);
    dateString = dateString.replace('.', ''); // Remove period
    dateString = dateString + ', ' + now.getFullYear();
    var coffeeDate = new Date(dateString);
    // Check if the coffee pots were made today
    return coffeeDate.getDate() == now.getDate();
  },

  minuteDiff: function(then) {
    // Get now
    var now = new Date();
    var one_minute = 1000 * 60;
    // Calculate difference between the two dates, and convert to minutes
    return Math.floor(( now.getTime() - then.getTime() ) / one_minute);
  },

  prettyAgeString: function(diff, coffeeTime) {
    // Create a proper time string from all the minutes
    if (0 <= diff && diff <= 9)
      return 'Kaffen ble nettopp laget';
    else if (10 <= diff && diff <= 59)
      return 'Kaffen ble laget for '+diff+' min siden';
    else if (60 <= diff)
      return 'Kaffen ble laget kl '+coffeeTime[0]+':'+coffeeTime[1];
    else
      return 'WAT? Lager noen kaffe i fremtiden nå?!';
  },

  prettyPotsString: function(pots) {
    return (pots=='0'?'Ingen kanner':pots=='1'?'1 kanne':pots+' kanner') + ' i dag';
  },

  showNotification: function(pots, age) { // Parameters 'pots' and 'age' not in use yet.
    var demo = (typeof pots == 'undefined' && typeof age == 'undefined');
    // If the computer has slept for a while and there are
    // suddenly four new coffeepots then they will all be
    // lined up for notifications, giving the user four
    // notifications at once. This is prevented here by not
    // allowing two consecutive notifications within 4 minutes
    // of each other.
    var showIt = true;
    try {
      var then = JSON.parse(localStorage.lastSubscriptionTime);
      if (this.minuteDiff(then) <= 4) {
        showIt = false;
      }
    }
    catch (err) {
      if (this.debug) console.log('ERROR: failed to calculate coffee subscription time difference');
    }
    if (showIt || demo) {

      // Save timestamp if this was a real coffee notification
      if (!demo)
        localStorage.lastSubscriptionTime = JSON.stringify(new Date());

      var key = localStorage.affiliationKey1;
      var memes = [];

      // Add regular memes
      var amount = MEME_AMOUNT; // Number of memes, in regular human numbers, not zero-indexed
      for (var i = 1; i <= amount; i++) {
        memes.push('./meme/'+i+'.jpg');
      }

      // Add affiliation memes
      if (Affiliation.org[key].hw.memes) {
        amount = Affiliation.org[key].hw.memes.numberOfMemes;
        var path = Affiliation.org[key].hw.memes.memePath;
        for (var i = 1; i <= amount; i++) {
          memes.push(path+i+'.jpg');
        }
      }

      // Randomize image
      var random = 1 + (Math.floor(Math.random() * memes.length));
      if (this.debug) console.log('memes['+(random-1)+'] of '+0+'-'+(memes.length-1)+' is "'+memes[random-1]+'"');
      var image = memes[random - 1]; // the list is zero-indexed

      // Create the notification
      item = {
        title: Affiliation.org[key].name + ' Notifier',
        description: this.msgNotification,
        image: image,
        link: 'options.html',
        feedKey: key,
      }
      if (!demo)
        Browser.createNotification(item);
      else
        // Need to run it by the background process because the event listeners are there
        Browser.getBackgroundProcess().Browser.createNotification(item);
    }
    else {
      if (this.debug) console.log('ERROR: coffee notification displayed less than four minutes ago');
    }
  },

}
<commit_msg>coffee: automated affiliation meme counting<commit_after>var Coffee = {
  debug: 0,
  debugString: "200\n1. March 14:28:371",

  msgNoPots: 'Ingen kanner i dag',
  msgNoCoffee: 'Kaffen har ikke blitt satt på',
  msgFormatError: 'Feil i kaffeformat',
  msgConnectionError: 'Frakoblet fra kaffekanna',
  msgComforting: 'Så så, det er sikkert kaffe :)',
  msgNotification: 'Kaffen er satt på, straks klar :)',

  get: function(pretty, callback) {
    if (callback == undefined) {
      console.log('ERROR: Callback is required. In the callback you should insert the results into the DOM.');
      return;
    }

    var api = Affiliation.org[localStorage.affiliationKey1].hw.apis.coffee;

    // Receives the status for the coffee pot
    var self = this;
    Ajaxer.getPlainText({
      url: api,
      success: function(data) {

        // If coffee debugging is enabled
        if (self.debug) {
          data = self.debugString;
        }

        try {
          // Split into pot number and age of last pot
          var pieces = data.split("\n");
          var pots = Number(pieces[0]);
          var ageString = pieces[1];

          // Coffee made today?
          if (self.isMadeToday(ageString)) {

            // Calculate minute difference from right now
            var now = new Date();
            var coffeeTime = String(ageString.match(/\d+:\d+:\d+/)).split(':');
            var then = new Date(now.getFullYear(), now.getMonth(), now.getDate(), coffeeTime[0], coffeeTime[1]);
            var age = self.minuteDiff(then);

            // If pretty strings are requested
            if (pretty) {
              age = self.prettyAgeString(age, coffeeTime);
              pots = self.prettyPotsString(pots);
            }

            // Call it back
            callback(pots, age);
          }
          else {
            // Coffee was not made today
            if (pretty) {
              callback(self.msgNoPots, self.msgNoCoffee);
            }
            else {
              callback(0, 0);
            }
          }
        } catch (err) {
          if (self.debug) console.log('ERROR: Coffee format is wrong:', err);
          callback(self.msgFormatError, self.msgComforting);
        }
      },
      error: function(jqXHR, text, err) {
        if (self.debug) console.log('ERROR: Failed to get coffee pot status.');
        callback(self.msgConnectionError, self.msgComforting);
      },
    });
  },

  isMadeToday: function(ageString) {
    // Get now
    var now = new Date();
    // Figure out which date the coffee was made
    var dateObject = ageString.match(/\d+\. [a-zA-Z]+/);
    var dateString = String(dateObject);
    dateString = dateString.replace('.', ''); // Remove period
    dateString = dateString + ', ' + now.getFullYear();
    var coffeeDate = new Date(dateString);
    // Check if the coffee pots were made today
    return coffeeDate.getDate() == now.getDate();
  },

  minuteDiff: function(then) {
    // Get now
    var now = new Date();
    var one_minute = 1000 * 60;
    // Calculate difference between the two dates, and convert to minutes
    return Math.floor(( now.getTime() - then.getTime() ) / one_minute);
  },

  prettyAgeString: function(diff, coffeeTime) {
    // Create a proper time string from all the minutes
    if (0 <= diff && diff <= 9)
      return 'Kaffen ble nettopp laget';
    else if (10 <= diff && diff <= 59)
      return 'Kaffen ble laget for '+diff+' min siden';
    else if (60 <= diff)
      return 'Kaffen ble laget kl '+coffeeTime[0]+':'+coffeeTime[1];
    else
      return 'WAT? Lager noen kaffe i fremtiden nå?!';
  },

  prettyPotsString: function(pots) {
    return (pots=='0'?'Ingen kanner':pots=='1'?'1 kanne':pots+' kanner') + ' i dag';
  },

  showNotification: function(pots, age) { // Parameters 'pots' and 'age' not in use yet.
    var demo = (typeof pots == 'undefined' && typeof age == 'undefined');
    // If the computer has slept for a while and there are
    // suddenly four new coffeepots then they will all be
    // lined up for notifications, giving the user four
    // notifications at once. This is prevented here by not
    // allowing two consecutive notifications within 4 minutes
    // of each other.
    var showIt = true;
    try {
      var then = JSON.parse(localStorage.lastSubscriptionTime);
      if (this.minuteDiff(then) <= 4) {
        showIt = false;
      }
    }
    catch (err) {
      if (this.debug) console.log('ERROR: failed to calculate coffee subscription time difference');
    }
    if (showIt || demo) {

      // Save timestamp if this was a real coffee notification
      if (!demo)
        localStorage.lastSubscriptionTime = JSON.stringify(new Date());

      var key = localStorage.affiliationKey1;
      var memes = [];

      // Add regular memes
      var amount = MEME_AMOUNT; // Number of memes, in regular human numbers, not zero-indexed
      for (var i = 1; i <= amount; i++) {
        memes.push('./meme/'+i+'.jpg');
      }

      // Add affiliation memes
      if (Affiliation.org[key].hw.memePath) {
        var amount = Affiliation.getMemeCount(key);
        var path = Affiliation.org[key].hw.memePath;
        for (var i = 1; i <= amount; i++) {
          memes.push(path+i+'.jpg');
        }
      }

      // Randomize image
      var random = 1 + (Math.floor(Math.random() * memes.length));
      if (this.debug) console.log('memes['+(random-1)+'] of '+0+'-'+(memes.length-1)+' is "'+memes[random-1]+'"');
      var image = memes[random - 1]; // the list is zero-indexed

      // Create the notification
      item = {
        title: Affiliation.org[key].name + ' Notifier',
        description: this.msgNotification,
        image: image,
        link: 'options.html',
        feedKey: key,
      }
      if (!demo)
        Browser.createNotification(item);
      else
        // Need to run it by the background process because the event listeners are there
        Browser.getBackgroundProcess().Browser.createNotification(item);
    }
    else {
      if (this.debug) console.log('ERROR: coffee notification displayed less than four minutes ago');
    }
  },

}
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import Box from './box'
import { connect } from 'react-redux'

export class Statistics extends Component {

  renderRow(label, value){
    const text = {
      color: 'lightgrey',
      padding: '2px 10px'
    }

    return (

{label}

{value}

    )
  }

  render(){

    const box = {
      padding: '25px 15px'
    }

    return(
      <Box title={'Statistics'} width={300}>

          { this.renderRow('Total value', '€'+this.props.totalAmount) }
          { this.renderRow('Donors', this.props.totalDonors) }
          { this.renderRow('Avg donation', '€'+this.props.avgDonation) }

Top donations

          { this.props.leaderboard.map(l => {
            return this.renderRow(l.key, l.value)
          })}

      </Box>
    )
  }
}

const mapStateToProps = state => {
  console.log(state)
  return {
    leaderboard: state.leaderboard,
    totalAmount: state.totalAmount,
    totalDonors: state.queue.length,
    avgDonation: Math.round(state.totalAmount / state.queue.length || 1)
  }
}

export default connect(mapStateToProps, null)(Statistics)
<commit_msg>Change top donations to top donors<commit_after>import React, { Component } from 'react'
import Box from './box'
import { connect } from 'react-redux'

export class Statistics extends Component {

  renderRow(label, value){
    const text = {
      color: 'lightgrey',
      padding: '2px 10px'
    }

    return (

{label}

{value}

    )
  }

  render(){

    const box = {
      padding: '25px 15px'
    }

    return(
      <Box title={'Statistics'} width={300}>

          { this.renderRow('Total value', '€'+this.props.totalAmount) }
          { this.renderRow('Donors', this.props.totalDonors) }
          { this.renderRow('Avg donation', '€'+this.props.avgDonation) }

Top donors

          { this.props.leaderboard.map(l => {
            return this.renderRow(l.key, l.value)
          })}

      </Box>
    )
  }
}

const mapStateToProps = state => {
  console.log(state)
  return {
    leaderboard: state.leaderboard,
    totalAmount: state.totalAmount,
    totalDonors: state.queue.length,
    avgDonation: Math.round(state.totalAmount / state.queue.length || 1)
  }
}

export default connect(mapStateToProps, null)(Statistics)
<|endoftext|>


<commit_before>// Node modules.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { isEmpty, map, replace } from 'lodash';
import * as Sentry from '@sentry/browser';
// Relative imports.
import AlertBox from '@department-of-veterans-affairs/formation-react/AlertBox';
import LoadingIndicator from '@department-of-veterans-affairs/formation-react/LoadingIndicator';
import environment from 'platform/utilities/environment';
import { apiRequest } from 'platform/utilities/api';
import { appointmentsToolLink } from 'platform/utilities/cerner';

export class CernerCallToAction extends Component {
  static defaultProps = {
    cernerFacilities: [],
    otherFacilities: [],
  };

  static propTypes = {
    cernerFacilities: PropTypes.arrayOf(
      PropTypes.shape({
        facilityId: PropTypes.string.isRequired,
        isCerner: PropTypes.bool.isRequired,
      }).isRequired,
    ),
    otherFacilities: PropTypes.arrayOf(
      PropTypes.shape({
        facilityId: PropTypes.string.isRequired,
        isCerner: PropTypes.bool.isRequired,
      }).isRequired,
    ),
    linksHeaderText: PropTypes.string.isRequired,
    myVAHealthLink: PropTypes.string.isRequired,
    myHealtheVetLink: PropTypes.string.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      error: '',
      facilities: [],
      fetching: true,
    };
  }

  componentDidMount() {
    const { cernerFacilities, otherFacilities } = this.props;

    const facilities = [...cernerFacilities, ...otherFacilities];

    // Escape early if there are no facilities.
    if (isEmpty(facilities)) {
      Sentry.withScope(scope => {
        scope.setExtra('facilities', facilities);
        Sentry.captureMessage(`Facilities - unexpected empty facilities`);
      });
      return;
    }

    // Derive the list of facility IDs.
    const facilityIDs = map(
      facilities,
      facility => `vha_${facility.facilityId}`,
    );

    // Fetch cerner facilities.
    this.fetchFacilities(facilityIDs);
  }

  fetchFacilities = async facilityIDs => {
    // Show loading state.
    this.setState({ fetching: true });

    try {
      // Fetch facilities and store them in state.
      const response = await apiRequest(
        `${environment.API_URL}/v1/facilities/va?ids=${facilityIDs.join(',')}`,
      );
      this.setState({ facilities: response?.data, fetching: false });

      // Log any API errors.
    } catch (error) {
      this.setState({ error: error.message, fetching: false });
    }
  };

  render() {
    const {
      cernerFacilities,
      linksHeaderText,
      myVAHealthLink,
      myHealtheVetLink,
    } = this.props;
    const { error, fetching, facilities } = this.state;

    // Escape early if we are fetching.
    if (fetching) {
      return (

          <LoadingIndicator message="Loading your information..." />

      );
    }

    // Escape early if there was an error fetching the Cerner facilities.
    if (error || isEmpty(facilities)) {
      // WARNING: Add sentry logging here if there is an error fetching Cerner facilities.
      Sentry.withScope(scope => {
        scope.setExtra('error', error);
        scope.setExtra('facilities', facilities);
        Sentry.captureMessage(
          `Facilities - unexpected empty facilities or error`,
        );
      });
      return (

          <AlertBox
            headline="Something went wrong"
            content="We’re sorry. Something went wrong on our end. Please try again later."
            status="error"
          />

      );
    }

    return (

            Your VA health care team may be using our new My VA Health portal

            Our records show that you're registered at:

          {/* List of user's facilities */}
          {map(facilities, facility => {
            // Derive facility properties.
            const id = facility?.id;
            const strippedID = replace(id, 'vha_', '');
            const name = facility?.attributes?.name;
            const isCerner = cernerFacilities?.some(
              cernerFacility => cernerFacility?.facilityId === strippedID,
            );

            return (

                {name}{' '}
                {isCerner
                  ? '(Now using My VA Health)'
                  : '(Using My HealtheVet)'}

            );
          })}

            Please choose a health management portal below, depending on your
            provider's facility. You may need to disable your
            browser's pop-up blocker to open the portal. If you're
            prompted to sign in again, use the same account you used to sign in
            on VA.gov.

{linksHeaderText}

          {/* List of user's facility links */}
          {map(facilities, facility => {
            // Derive facility properties.
            const id = facility?.id;
            const strippedID = replace(id, 'vha_', '');
            const name = facility?.attributes?.name;
            const isCerner = cernerFacilities?.some(
              cernerFacility => cernerFacility?.facilityId === strippedID,
            );

            return (
              <div key={`${id}-cta-link`}>

                  {name}

                  {isCerner ? 'Go to My VA Health' : 'Go to My HealtheVet'}

            );
          })}

              Another VA health facility

              {myHealtheVetLink === appointmentsToolLink
                ? 'Go to the VA appointments tool'
                : 'Go to My HealtheVet'}

    );
  }
}

export default CernerCallToAction;
<commit_msg>Update CTA cerner link text (#15073)<commit_after>// Node modules.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { isEmpty, map, replace } from 'lodash';
import * as Sentry from '@sentry/browser';
// Relative imports.
import AlertBox from '@department-of-veterans-affairs/formation-react/AlertBox';
import LoadingIndicator from '@department-of-veterans-affairs/formation-react/LoadingIndicator';
import environment from 'platform/utilities/environment';
import { apiRequest } from 'platform/utilities/api';
import { appointmentsToolLink } from 'platform/utilities/cerner';

export class CernerCallToAction extends Component {
  static defaultProps = {
    cernerFacilities: [],
    otherFacilities: [],
  };

  static propTypes = {
    cernerFacilities: PropTypes.arrayOf(
      PropTypes.shape({
        facilityId: PropTypes.string.isRequired,
        isCerner: PropTypes.bool.isRequired,
      }).isRequired,
    ),
    otherFacilities: PropTypes.arrayOf(
      PropTypes.shape({
        facilityId: PropTypes.string.isRequired,
        isCerner: PropTypes.bool.isRequired,
      }).isRequired,
    ),
    linksHeaderText: PropTypes.string.isRequired,
    myVAHealthLink: PropTypes.string.isRequired,
    myHealtheVetLink: PropTypes.string.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      error: '',
      facilities: [],
      fetching: true,
    };
  }

  componentDidMount() {
    const { cernerFacilities, otherFacilities } = this.props;

    const facilities = [...cernerFacilities, ...otherFacilities];

    // Escape early if there are no facilities.
    if (isEmpty(facilities)) {
      Sentry.withScope(scope => {
        scope.setExtra('facilities', facilities);
        Sentry.captureMessage(`Facilities - unexpected empty facilities`);
      });
      return;
    }

    // Derive the list of facility IDs.
    const facilityIDs = map(
      facilities,
      facility => `vha_${facility.facilityId}`,
    );

    // Fetch cerner facilities.
    this.fetchFacilities(facilityIDs);
  }

  fetchFacilities = async facilityIDs => {
    // Show loading state.
    this.setState({ fetching: true });

    try {
      // Fetch facilities and store them in state.
      const response = await apiRequest(
        `${environment.API_URL}/v1/facilities/va?ids=${facilityIDs.join(',')}`,
      );
      this.setState({ facilities: response?.data, fetching: false });

      // Log any API errors.
    } catch (error) {
      this.setState({ error: error.message, fetching: false });
    }
  };

  render() {
    const {
      cernerFacilities,
      linksHeaderText,
      myVAHealthLink,
      myHealtheVetLink,
    } = this.props;
    const { error, fetching, facilities } = this.state;

    // Escape early if we are fetching.
    if (fetching) {
      return (

          <LoadingIndicator message="Loading your information..." />

      );
    }

    // Escape early if there was an error fetching the Cerner facilities.
    if (error || isEmpty(facilities)) {
      // WARNING: Add sentry logging here if there is an error fetching Cerner facilities.
      Sentry.withScope(scope => {
        scope.setExtra('error', error);
        scope.setExtra('facilities', facilities);
        Sentry.captureMessage(
          `Facilities - unexpected empty facilities or error`,
        );
      });
      return (

          <AlertBox
            headline="Something went wrong"
            content="We’re sorry. Something went wrong on our end. Please try again later."
            status="error"
          />

      );
    }

    // Derive MyHealtheVet link text.
    const myHealtheVetLinkText =
      myHealtheVetLink === appointmentsToolLink
        ? 'Go to the VA appointments tool'
        : 'Go to My HealtheVet';

    return (

            Your VA health care team may be using our new My VA Health portal

            Our records show that you're registered at:

          {/* List of user's facilities */}
          {map(facilities, facility => {
            // Derive facility properties.
            const id = facility?.id;
            const strippedID = replace(id, 'vha_', '');
            const name = facility?.attributes?.name;
            const isCerner = cernerFacilities?.some(
              cernerFacility => cernerFacility?.facilityId === strippedID,
            );

            return (

                {name}{' '}
                {isCerner
                  ? '(Now using My VA Health)'
                  : '(Using My HealtheVet)'}

            );
          })}

            Please choose a health management portal below, depending on your
            provider's facility. You may need to disable your
            browser's pop-up blocker to open the portal. If you're
            prompted to sign in again, use the same account you used to sign in
            on VA.gov.

{linksHeaderText}

          {/* List of user's facility links */}
          {map(facilities, facility => {
            // Derive facility properties.
            const id = facility?.id;
            const strippedID = replace(id, 'vha_', '');
            const name = facility?.attributes?.name;
            const isCerner = cernerFacilities?.some(
              cernerFacility => cernerFacility?.facilityId === strippedID,
            );

            // Derive the link text/label.
            const linkText = isCerner
              ? 'Go to My VA Health'
              : myHealtheVetLinkText;

            return (
              <div key={`${id}-cta-link`}>

                  {name}

                  {linkText}

            );
          })}

              Another VA health facility

              {myHealtheVetLinkText}

    );
  }
}

export default CernerCallToAction;
<|endoftext|>


<commit_before>"use strict";

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

const Exchange = require ('./base/Exchange');
const { ExchangeError, InsufficientFunds, OrderNotFound, InvalidOrder, AuthenticationError } = require ('./base/errors');

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

module.exports = class coinex extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coinex',
            'name': 'CoinEx',
            'countries': 'CN',
            'rateLimit': 1000,
            'has': {
                'fetchTickers': true,
                'fetchOHLCV': true,
                'fetchOpenOrders': true,
                'fetchClosedOrders': true,
            },
            'timeframes': {
                '1m': '1min',
                '3m': '3min',
                '5m': '5min',
                '15m': '15min',
                '30m': '30min',
                '1h': '1hour',
                '2h': '2hour',
                '4h': '4hour',
                '6h': '6hour',
                '12h': '12hour',
                '1d': '1day',
                '3d': '3day',
                '1w': '1week',
            },
            'urls': {
                'logo': 'https://www.coinex.com/_nuxt/img/coin-ex-logo-white.abfd6af.svg',
                'api': 'https://api.coinex.com/v1',
                'www': 'https://www.coinex.com/',
                'doc': 'https://github.com/coinexcom/coinex_exchange_api/wiki',
                'fees': 'https://www.coinex.com/fees',
            },
            'api': {
                'public': {
                    'get': [
                        'market/list',
                        'market/ticker',
                        'market/ticker/all',
                        'market/depth',
                        'market/deals',
                        'market/kline',
                    ],
                },
                'private': {
                    'get': [
                        'balance',
                        'order',
                        'order/pending',
                        'order/finished',
                        'order/finished/{id}',
                    ],
                    'post': [
                        'order/limit',
                        'order/market',
                    ],
                    'delete': [
                        'order/pending',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'maker': 0.0,
                    'taker': 0.001,
                },
                'funding': {
                    'withdraw': {
                        'BCH': 0.0,
                        'BTC': 0.001,
                        'LTC': 0.001,
                        'ETH': 0.001,
                        'ZEC': 0.0001,
                        'DASH': 0.0001,
                    },
                },
            },
            'limits': {
                'amount': {
                    'min': 0.001,
                    'max': undefined,
                },
            },
            'precision': {
                'amount': 8,
                'price': 8,
            },
        });
    }

    commonCurrencyCode (currency) {
        return currency;
    }

    async fetchMarkets () {
        let markets = await this.publicGetMarketList ();
        let result = [];
        for (let i = 0; i < markets.length; i++) {
            let id = markets[i];
            let [ quote, base ] = [id.slice (0, -3), id.slice (-3)];
            let symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': true,
                'lot': this.limits['amount']['min'],
                'info': id,
            });
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['date'];
        let symbol = market['symbol'];
        ticker = ticker['ticker'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': parseFloat (ticker['high']),
            'low': parseFloat (ticker['low']),
            'bid': parseFloat (ticker['buy']),
            'ask': parseFloat (ticker['sell']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['last']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': parseFloat (ticker['vol']),
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetMarketTicker (this.extend ({
            'market': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.publicGetMarketTickerAll (params);
        let timestamp = tickers['date'];
        tickers = tickers['ticker'];
        let ids = Object.keys (tickers);
        let result = {};
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.markets_by_id[id];
            let symbol = market['symbol'];
            let ticker = {
                'date': timestamp,
                'ticker': tickers[id],
            };
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetMarketDepth (this.extend ({
            'market': this.marketId (symbol),
            'merge': '0.00000001',
        }, params));
        return this.parseOrderBook (orderbook);
    }

    parseTrade (trade, market = undefined) {
        let timestamp = trade['date_ms'];
        let price = parseFloat (trade['price']);
        let amount = parseFloat (trade['amount']);
        let symbol = market['symbol'];
        let cost = parseFloat (this.costToPrecision (symbol, price * amount));
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'id': this.safeString (trade, 'id'),
            'order': undefined,
            'type': 'limit',
            'side': trade['type'],
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': undefined,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let trades = await this.publicGetMarketDeals (this.extend ({
            'market': market['id'],
        }, params));
        return this.parseTrades (trades, market, since, limit);
    }

    parseOHLCV (ohlcv, market = undefined, timeframe = '5m', since = undefined, limit = undefined) {
        return [
            ohlcv[0],
            parseFloat (ohlcv[1]),
            parseFloat (ohlcv[3]),
            parseFloat (ohlcv[4]),
            parseFloat (ohlcv[2]),
            parseFloat (ohlcv[5]),
        ];
    }

    async fetchOHLCV (symbol, timeframe = '5m', since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketKline (this.extend ({
            'market': market['id'],
            'type': this.timeframes[timeframe],
        }, params));
        return this.parseOHLCVs (response, market, timeframe, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privateGetBalance (params);
        let result = { 'info': balances };
        let currencies = Object.keys (balances);
        for (let i = 0; i < currencies.length; i++) {
            let id = currencies[i];
            let balance = balances[id];
            let currency = this.commonCurrencyCode (id);
            let account = {
                'free': parseFloat (balance['available']),
                'used': parseFloat (balance['frozen']),
                'total': 0.0,
            };
            account['total'] = this.sum (account['free'], account['used']);
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    parseOrder (order, market = undefined) {
        // TODO: check if it's actually milliseconds, since examples were in seconds
        let timestamp = this.safeInteger (order, 'create_time') * 1000;
        let price = parseFloat (order['price']);
        let cost = this.safeFloat (order, 'deal_money');
        let amount = this.safeFloat (order, 'amount');
        let filled = this.safeFloat (order, 'deal_amount');
        let symbol = market['symbol'];
        let remaining = this.amountToPrecision (symbol, amount - filled);
        let status = order['status'];
        if (status == 'done') {
            status = 'closed';
        } else {
            // not_deal
            // part_deal
            status = 'open';
        }
        return {
            'id': this.safeString (order, 'id'),
            'datetime': this.iso8601 (timestamp),
            'timestamp': timestamp,
            'status': status,
            'symbol': symbol,
            'type': order['order_type'],
            'side': order['type'],
            'price': price,
            'cost': cost,
            'amount': amount,
            'filled': filled,
            'remaining': remaining,
            'trades': undefined,
            'fee': {
                'currency': market['quote'],
                'cost': parseFloat (order['deal_fee']),
            },
            'info': order,
        };
    }

    parseOrders (orders, market, result = []) {
        for (let i = 0; i < orders.length; i++) {
            let order = orders[i];
            result.push (this.parseOrder (order, market));
        }
        return result;
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privatePostOrder' + this.capitalize (type);
        let market = this.market (symbol);
        amount = parseFloat (amount);
        let request = {
            'market': market['id'],
            'amount': this.amountToPrecision (symbol, amount),
            'type': side,
        };
        if (type == 'limit') {
            price = parseFloat (price);
            request['price'] = this.priceToPrecision (symbol, price);
        }
        let response = await this[method] (this.extend (request, params));
        let order = this.parseOrder (response, market);
        let id = order['id'];
        this.orders[id] = order;
        return order;
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let result = await this.privateDeleteOrderPending (this.extend ({
            'id': id,
            'market': market['id'],
        }, params));
        return this.parseOrder (result, market);
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let order = await this.privateGetOrder (this.extend ({
            'id': id,
            'market': market['id'],
        }, params));
        return this.parseOrder (order, market);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'market': market['id'],
        };
        if (limit)
            request['limit'] = limit;
        let orders = await this.privateGetOrderPending (this.extend (request, params));
        return this.parseOrders (orders['data'], market);
    }

    async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'market': market['id'],
        };
        if (limit)
            request['limit'] = limit;
        let orders = await this.privateGetOrderFinished (this.extend (request, params));
        return this.parseOrders (orders['data'], market);
    }

    // async fetchOrderTrades (id, symbol = undefined, params = {}) {
    //     await this.loadMarkets ();
    //     let market = this.market (symbol);
    //     let trades = await this.privateGetOrderFinishedId (this.extend ({
    //         'id': id,
    //         'market': market['id'],
    //         'page': 1,
    //         'limit': 100,
    //     }, params));
    //     return trades['data'];
    // }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api == 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            query = this.extend ({
                'access_id': this.apiKey,
                'tonce': nonce.toString (),
            }, query);
            query = this.keysort (query);
            let encQuery = this.urlencode (query);
            let signature = this.hash (encQuery + '&secret_key=' + this.secret);
            headers = {
                'Authorization': signature.toUpperCase (),
                'Content-Type': 'application/json',
            };
            if (method == 'GET') {
                url += '?' + encQuery;
            } else {
                body = this.json (query);
            }
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        let code = this.safeString (response, 'code');
        if (code != '0' || !this.safeValue (response, 'data')) {
            let responseCodes = {
                '24': AuthenticationError,
                '25': AuthenticationError,
                '107': InsufficientFunds,
                '600': OrderNotFound,
                '601': InvalidOrder,
                '602': InvalidOrder,
                '606': InvalidOrder,
            };
            let errorClass = this.safeValue (responseCodes, code, ExchangeError);
            throw new errorClass (response['message']);
        }
        // code and message will always be the same here (0, 'Ok'), so ignore them
        return response['data'];
    }
}
<commit_msg>coinex: transpiler<commit_after>"use strict";

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

const Exchange = require ('./base/Exchange');
const { ExchangeError, InsufficientFunds, OrderNotFound, InvalidOrder, AuthenticationError } = require ('./base/errors');

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

module.exports = class coinex extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coinex',
            'name': 'CoinEx',
            'countries': 'CN',
            'rateLimit': 1000,
            'has': {
                'fetchTickers': true,
                'fetchOHLCV': true,
                'fetchOpenOrders': true,
                'fetchClosedOrders': true,
            },
            'timeframes': {
                '1m': '1min',
                '3m': '3min',
                '5m': '5min',
                '15m': '15min',
                '30m': '30min',
                '1h': '1hour',
                '2h': '2hour',
                '4h': '4hour',
                '6h': '6hour',
                '12h': '12hour',
                '1d': '1day',
                '3d': '3day',
                '1w': '1week',
            },
            'urls': {
                'logo': 'https://www.coinex.com/_nuxt/img/coin-ex-logo-white.abfd6af.svg',
                'api': 'https://api.coinex.com/v1',
                'www': 'https://www.coinex.com/',
                'doc': 'https://github.com/coinexcom/coinex_exchange_api/wiki',
                'fees': 'https://www.coinex.com/fees',
            },
            'api': {
                'public': {
                    'get': [
                        'market/list',
                        'market/ticker',
                        'market/ticker/all',
                        'market/depth',
                        'market/deals',
                        'market/kline',
                    ],
                },
                'private': {
                    'get': [
                        'balance',
                        'order',
                        'order/pending',
                        'order/finished',
                        'order/finished/{id}',
                    ],
                    'post': [
                        'order/limit',
                        'order/market',
                    ],
                    'delete': [
                        'order/pending',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'maker': 0.0,
                    'taker': 0.001,
                },
                'funding': {
                    'withdraw': {
                        'BCH': 0.0,
                        'BTC': 0.001,
                        'LTC': 0.001,
                        'ETH': 0.001,
                        'ZEC': 0.0001,
                        'DASH': 0.0001,
                    },
                },
            },
            'limits': {
                'amount': {
                    'min': 0.001,
                    'max': undefined,
                },
            },
            'precision': {
                'amount': 8,
                'price': 8,
            },
        });
    }

    commonCurrencyCode (currency) {
        return currency;
    }

    async fetchMarkets () {
        let markets = await this.publicGetMarketList ();
        let result = [];
        for (let i = 0; i < markets.length; i++) {
            let id = markets[i];
            let base = id.slice (-3);
            let quote = id.slice (0, -3);
            let symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': true,
                'lot': this.limits['amount']['min'],
                'info': id,
            });
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['date'];
        let symbol = market['symbol'];
        ticker = ticker['ticker'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': parseFloat (ticker['high']),
            'low': parseFloat (ticker['low']),
            'bid': parseFloat (ticker['buy']),
            'ask': parseFloat (ticker['sell']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['last']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': parseFloat (ticker['vol']),
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetMarketTicker (this.extend ({
            'market': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.publicGetMarketTickerAll (params);
        let timestamp = tickers['date'];
        tickers = tickers['ticker'];
        let ids = Object.keys (tickers);
        let result = {};
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.markets_by_id[id];
            let symbol = market['symbol'];
            let ticker = {
                'date': timestamp,
                'ticker': tickers[id],
            };
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetMarketDepth (this.extend ({
            'market': this.marketId (symbol),
            'merge': '0.00000001',
        }, params));
        return this.parseOrderBook (orderbook);
    }

    parseTrade (trade, market = undefined) {
        let timestamp = trade['date_ms'];
        let price = parseFloat (trade['price']);
        let amount = parseFloat (trade['amount']);
        let symbol = market['symbol'];
        let cost = parseFloat (this.costToPrecision (symbol, price * amount));
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'id': this.safeString (trade, 'id'),
            'order': undefined,
            'type': 'limit',
            'side': trade['type'],
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': undefined,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let trades = await this.publicGetMarketDeals (this.extend ({
            'market': market['id'],
        }, params));
        return this.parseTrades (trades, market, since, limit);
    }

    parseOHLCV (ohlcv, market = undefined, timeframe = '5m', since = undefined, limit = undefined) {
        return [
            ohlcv[0],
            parseFloat (ohlcv[1]),
            parseFloat (ohlcv[3]),
            parseFloat (ohlcv[4]),
            parseFloat (ohlcv[2]),
            parseFloat (ohlcv[5]),
        ];
    }

    async fetchOHLCV (symbol, timeframe = '5m', since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketKline (this.extend ({
            'market': market['id'],
            'type': this.timeframes[timeframe],
        }, params));
        return this.parseOHLCVs (response, market, timeframe, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privateGetBalance (params);
        let result = { 'info': balances };
        let currencies = Object.keys (balances);
        for (let i = 0; i < currencies.length; i++) {
            let id = currencies[i];
            let balance = balances[id];
            let currency = this.commonCurrencyCode (id);
            let account = {
                'free': parseFloat (balance['available']),
                'used': parseFloat (balance['frozen']),
                'total': 0.0,
            };
            account['total'] = this.sum (account['free'], account['used']);
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    parseOrder (order, market = undefined) {
        // TODO: check if it's actually milliseconds, since examples were in seconds
        let timestamp = this.safeInteger (order, 'create_time') * 1000;
        let price = parseFloat (order['price']);
        let cost = this.safeFloat (order, 'deal_money');
        let amount = this.safeFloat (order, 'amount');
        let filled = this.safeFloat (order, 'deal_amount');
        let symbol = market['symbol'];
        let remaining = this.amountToPrecision (symbol, amount - filled);
        let status = order['status'];
        if (status == 'done') {
            status = 'closed';
        } else {
            // not_deal
            // part_deal
            status = 'open';
        }
        return {
            'id': this.safeString (order, 'id'),
            'datetime': this.iso8601 (timestamp),
            'timestamp': timestamp,
            'status': status,
            'symbol': symbol,
            'type': order['order_type'],
            'side': order['type'],
            'price': price,
            'cost': cost,
            'amount': amount,
            'filled': filled,
            'remaining': remaining,
            'trades': undefined,
            'fee': {
                'currency': market['quote'],
                'cost': parseFloat (order['deal_fee']),
            },
            'info': order,
        };
    }

    parseOrders (orders, market, result = []) {
        for (let i = 0; i < orders.length; i++) {
            let order = orders[i];
            result.push (this.parseOrder (order, market));
        }
        return result;
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privatePostOrder' + this.capitalize (type);
        let market = this.market (symbol);
        amount = parseFloat (amount);
        let request = {
            'market': market['id'],
            'amount': this.amountToPrecision (symbol, amount),
            'type': side,
        };
        if (type == 'limit') {
            price = parseFloat (price);
            request['price'] = this.priceToPrecision (symbol, price);
        }
        let response = await this[method] (this.extend (request, params));
        let order = this.parseOrder (response, market);
        let id = order['id'];
        this.orders[id] = order;
        return order;
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let result = await this.privateDeleteOrderPending (this.extend ({
            'id': id,
            'market': market['id'],
        }, params));
        return this.parseOrder (result, market);
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let order = await this.privateGetOrder (this.extend ({
            'id': id,
            'market': market['id'],
        }, params));
        return this.parseOrder (order, market);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'market': market['id'],
        };
        if (limit)
            request['limit'] = limit;
        let orders = await this.privateGetOrderPending (this.extend (request, params));
        return this.parseOrders (orders['data'], market);
    }

    async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'market': market['id'],
        };
        if (limit)
            request['limit'] = limit;
        let orders = await this.privateGetOrderFinished (this.extend (request, params));
        return this.parseOrders (orders['data'], market);
    }

    // async fetchOrderTrades (id, symbol = undefined, params = {}) {
    //     await this.loadMarkets ();
    //     let market = this.market (symbol);
    //     let trades = await this.privateGetOrderFinishedId (this.extend ({
    //         'id': id,
    //         'market': market['id'],
    //         'page': 1,
    //         'limit': 100,
    //     }, params));
    //     return trades['data'];
    // }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api == 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            query = this.extend ({
                'access_id': this.apiKey,
                'tonce': nonce.toString (),
            }, query);
            query = this.keysort (query);
            let encQuery = this.urlencode (query);
            let signature = this.hash (encQuery + '&secret_key=' + this.secret);
            headers = {
                'Authorization': signature.toUpperCase (),
                'Content-Type': 'application/json',
            };
            if (method == 'GET') {
                url += '?' + encQuery;
            } else {
                body = this.json (query);
            }
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        let code = this.safeString (response, 'code');
        if (code != '0' || !this.safeValue (response, 'data')) {
            let responseCodes = {
                '24': AuthenticationError,
                '25': AuthenticationError,
                '107': InsufficientFunds,
                '600': OrderNotFound,
                '601': InvalidOrder,
                '602': InvalidOrder,
                '606': InvalidOrder,
            };
            let errorClass = this.safeValue (responseCodes, code, ExchangeError);
            throw new errorClass (response['message']);
        }
        // code and message will always be the same here (0, 'Ok'), so ignore them
        return response['data'];
    }
}
<|endoftext|>


<commit_before>var Session = require('./models/session.js');

exports.instructionsMessage = "Welcome, my tv-addicted friend! What you want me to do today?"
exports.whichSeriesMessage = function(firstName) { return "Ok " + firstName + " ! Which series do you want?";}
exports.whichSeasonMessage = "Good! Which season?"
exports.whichEpisodeMessage = "Great! Which episode?";
exports.whichLanguageMessage = "Great! Which language do I have to search for?";

exports.failedSeriesMessage = "Sorry, no series found with that name \u2639\uFE0F";
exports.ambiguousSeriesMessage = "Mmh ambiguous! \uD83E\uDD14 Which of these? (if none of these is the series you are looking for, try GET again with a more precise name)"
exports.notANumberMessage = "This doesn't seem to be a valid number, dude... retry!";
exports.seasonNotFoundMessage = "Season not found or not out yet. Retry or restart GET!";
exports.episodeNotFoundMessage = "Episode doesn't exist or not found. Retry or restart GET!";
exports.languageNotFoundMessage = "Sorry, language not found! Try typing your language as three-letter code, international form or native form!"
exports.subtitleNofFoundInAddic7edMessage = "Oh noes! We can't find your subtitles in our magic system! I guess nobody has subbed this yet... try again with a different language or a new request!"
exports.LoadingSubtitleMessage = "Great! I'm fetching for your subtitle now mate \uD83D\uDCE5";

exports.getCommand = "Get \uD83D\uDCE5";
exports.startAlertCommand = "Start Alert \uD83D\uDCE2";
exports.stopAlertCommand = "Stop Alert \uD83D\uDEAB";
exports.showAlertsCommand = "Show Alerts \uD83D\uDCC5";

exports.GETregExp = new RegExp(this.getCommand);
exports.STARTregExp = new RegExp(this.startAlertCommand);
exports.STOPregExp = new RegExp(this.stopAlertCommand);
exports.SHOWregExp = new RegExp(this.showAlertsCommand);

exports.notACommand = function (userInput) {
    return userInput != this.getCommand &&
        userInput != this.startAlertCommand &&
        userInput != this.stopAlertCommand &&
        userInput != this.showAlertsCommand;
}

exports.isEmpty = function (obj) {
    for (var key in obj) {
        if (obj.hasOwnProperty(key))
            return false;
    }
    return true;
}

exports.buildLinkMessage = function (link) {
    return 'There it is! If you want more subtitles of this episode please visit: www.addic7ed.com' + link;
}

exports.checkSessions = function (sessions, msg) {
    let userSession = sessions.find(function (session) {
        return session.chatId === msg.id;
    }) || new Session();
    userSession.chatId = msg.id;
    userSession.firstName = msg.first_name;
    return userSession;
}

exports.pushInSessions = function (sessions, session) {
    if (sessions.length == 0) sessions.push(session);
    else {
        var sessionIdx = sessions.findIndex(function (element) {
            return session.chatId == element.chatId;
        });
        if(sessionIdx == -1) sessions.push(session);
        else sessions[sessionIdx] = session;
    }
}

exports.removeSession = function (sessions, session) {
    if (sessions.length == 0) return;
    var sessionIdx = sessions.findIndex(function (element) {
        return session.chatId == element.chatId;
    });
    if(sessionIdx != -1) sessions.splice(sessionIdx, 1);
}

exports.resetValues = function(session) {
    session.choosingSeries = false;
    session.choosingSeason = false;
    session.choosingEpisode = false;
    session.ambiguousSeries = {};
}<commit_msg>fixed<commit_after>var Session = require('./models/session.js');

exports.instructionsMessage = "Welcome, my tv-addicted friend! What you want me to do today?"
exports.whichSeriesMessage = function(firstName) { return "Ok " + firstName + " ! Which series do you want?";}
exports.whichSeasonMessage = "Good! Which season?"
exports.whichEpisodeMessage = "Great! Which episode?";
exports.whichLanguageMessage = "Great! Which language do I have to search for?";

exports.failedSeriesMessage = "Sorry, no series found with that name \u2639\uFE0F Please try with another great tv-series title";
exports.ambiguousSeriesMessage = "Mmh ambiguous! \uD83E\uDD14 Which of these? (if none of these is the series you are looking for, try GET again with a more precise name)"
exports.notANumberMessage = "This doesn't seem to be a valid number, dude... retry!";
exports.seasonNotFoundMessage = "Season not found or not out yet. Retry or restart GET!";
exports.episodeNotFoundMessage = "Episode doesn't exist or not found. Retry or restart GET!";
exports.languageNotFoundMessage = "Sorry, language not found! Try typing your language as three-letter code, international form or native form!"
exports.subtitleNofFoundInAddic7edMessage = "Oh noes! We can't find your subtitles in our magic system! I guess nobody has subbed this yet... try again with a different language or a new request!"
exports.LoadingSubtitleMessage = "Great! I'm fetching for your subtitle now mate \uD83D\uDCE5";

exports.getCommand = "Get \uD83D\uDCE5";
exports.startAlertCommand = "Start Alert \uD83D\uDCE2";
exports.stopAlertCommand = "Stop Alert \uD83D\uDEAB";
exports.showAlertsCommand = "Show Alerts \uD83D\uDCC5";

exports.GETregExp = new RegExp(this.getCommand);
exports.STARTregExp = new RegExp(this.startAlertCommand);
exports.STOPregExp = new RegExp(this.stopAlertCommand);
exports.SHOWregExp = new RegExp(this.showAlertsCommand);

exports.notACommand = function (userInput) {
    return userInput != this.getCommand &&
        userInput != this.startAlertCommand &&
        userInput != this.stopAlertCommand &&
        userInput != this.showAlertsCommand;
}

exports.isEmpty = function (obj) {
    for (var key in obj) {
        if (obj.hasOwnProperty(key))
            return false;
    }
    return true;
}

exports.buildLinkMessage = function (link) {
    return 'There it is! If you want more subtitles of this episode please visit: www.addic7ed.com' + link;
}

exports.checkSessions = function (sessions, msg) {
    let userSession = sessions.find(function (session) {
        return session.chatId === msg.id;
    }) || new Session();
    userSession.chatId = msg.id;
    userSession.firstName = msg.first_name;
    return userSession;
}

exports.pushInSessions = function (sessions, session) {
    if (sessions.length == 0) sessions.push(session);
    else {
        var sessionIdx = sessions.findIndex(function (element) {
            return session.chatId == element.chatId;
        });
        if(sessionIdx == -1) sessions.push(session);
        else sessions[sessionIdx] = session;
    }
}

exports.removeSession = function (sessions, session) {
    if (sessions.length == 0) return;
    var sessionIdx = sessions.findIndex(function (element) {
        return session.chatId == element.chatId;
    });
    if(sessionIdx != -1) sessions.splice(sessionIdx, 1);
}

exports.resetValues = function(session) {
    session.choosingSeries = false;
    session.choosingSeason = false;
    session.choosingEpisode = false;
    session.ambiguousSeries = {};
}<|endoftext|>


<commit_before>requirejs.config({
    baseUrl: 'js',
    paths: {
        'jquery': '../lib/jquery/jquery',
        'jed': '../node_modules/jed/jed',
        'js.cookie': '../lib/js-cookie/js.cookie',
        'bootstrap': '../lib/bootstrap/bootstrap',
        'bootstraptypehead': '../lib/bootstrap3-typeahead/bootstrap3-typeahead',
        'bootstrap-dialog': '../lib/bootstrap3-dialog/bootstrap-dialog.min',
        'bootstrap-datepicker': '../lib/bootstrap-datepicker/bootstrap-datepicker.min',
        'leaflet': '../lib/leaflet/leaflet',
	'text': '../lib/requirejs-plugins/text',
        'leafletmarker': '../lib/leaflet.markercluster/dist/leaflet.markercluster',
        'leaflethash': '../lib/leaflet-hash/leaflet-hash',
        'normalize': '../lib/require-less/normalize',
        'css-builder': '../lib/require-css/css-builder',
        'lessc': '../lib/require-less/lessc',
        'less': '../lib/require-less/less',
        'css': '../lib/require-css/css',
	'leaflet-layer-overpass': '../bower_components/leaflet-layer-overpass/dist/OverPassLayer',
	'rsvp': '../node_modules/rsvp/dist/rsvp',
	'lib': '../lib',
	'data': '../data',
	'img': '../img',
	'docx': '../docx',
    },
    shim: {
	'jquery': {
	    exports: '$',
	},
        jquerycookie: {
            deps: ['jquery'],
            exports: '$.cookie',
        },
        leafletmarker: {
            deps: ['leaflet'],
        },
        leaflethash: {
            deps: ['leaflet'],
        },
        bootstrap: {
            deps: ['jquery'],
        },
        bootstraptypehead: {
            deps: ['bootstrap'],
        },
        'bootstrap-dialog': {
            deps: ['jquery', 'bootstrap'],
        },
	'leaflet-layer-overpass': {
	    deps: ['leaflet'],
	}

    }
});
<commit_msg>Added moment.js and german datepicker<commit_after>requirejs.config({
    baseUrl: 'js',
    paths: {
        'jquery': '../lib/jquery/jquery',
        'jed': '../node_modules/jed/jed',
        'js.cookie': '../lib/js-cookie/js.cookie',
        'bootstrap': '../lib/bootstrap/bootstrap',
        'bootstraptypehead': '../lib/bootstrap3-typeahead/bootstrap3-typeahead',
        'bootstrap-dialog': '../lib/bootstrap3-dialog/bootstrap-dialog.min',
        'bootstrap-datepicker': '../lib/bootstrap-datepicker/bootstrap-datepicker.min',
	'bootstrap-datepicker-de': '../bower_components/bootstrap-datepicker/js/locales/bootstrap-datepicker.de',
        'leaflet': '../lib/leaflet/leaflet',
	'text': '../lib/requirejs-plugins/text',
        'leafletmarker': '../lib/leaflet.markercluster/dist/leaflet.markercluster',
        'leaflethash': '../lib/leaflet-hash/leaflet-hash',
        'normalize': '../lib/require-less/normalize',
        'css-builder': '../lib/require-css/css-builder',
        'lessc': '../lib/require-less/lessc',
        'less': '../lib/require-less/less',
        'css': '../lib/require-css/css',
	'moment': '../lib/moment/moment',
	'leaflet-layer-overpass': '../bower_components/leaflet-layer-overpass/dist/OverPassLayer',
	'rsvp': '../node_modules/rsvp/dist/rsvp',
	'lib': '../lib',
	'data': '../data',
	'img': '../img',
	'docx': '../docx',
    },
    shim: {
	'jquery': {
	    exports: '$',
	},
        jquerycookie: {
            deps: ['jquery'],
            exports: '$.cookie',
        },
        leafletmarker: {
            deps: ['leaflet'],
        },
        leaflethash: {
            deps: ['leaflet'],
        },
        bootstrap: {
            deps: ['jquery'],
        },
        bootstraptypehead: {
            deps: ['bootstrap'],
        },
        'bootstrap-dialog': {
            deps: ['jquery', 'bootstrap'],
        },
	'leaflet-layer-overpass': {
	    deps: ['leaflet'],
	},
	 'bootstrap-datepicker-de': {
	    deps: ['bootstrap-datepicker'],
	 }
    }
});
<|endoftext|>


<commit_before>const fs = require('fs')
const Immutable = require('immutable')
const Excel = require('exceljs')
const join = require('path').join
const yaml = require('js-yaml')

const Utils = require('./utils')
const config = require('./config')

if (!Utils.existsDirectory(config.jsonDefXlsxDir)) {
  console.log(`ディレクトリが存在しません。${config.jsonDefXlsxDir}`) // eslint-disable-line no-console
  return
}
const files = fs.readdirSync(config.jsonDefXlsxDir)

const promises = files.filter((file) => {
  return !file.startsWith('~$') && file.endsWith('.xlsx')
}).map((file) => {
  return (books) => {
    return new Promise((resolve) => {
      console.log(`reading ${config.jsonDefXlsxDir}/${file} ...`) // eslint-disable-line no-console
      const workbook = new Excel.Workbook()
      workbook.xlsx.readFile(`${config.jsonDefXlsxDir}/${file}`).then(() => {
        const sheets = []
        workbook.eachSheet((worksheet) => {
          if (!worksheet.name.match(/.*/)) return
          const rows = []
          worksheet.eachRow((row, rowNumber) => {
            const cells = []
            row.eachCell({includeEmpty: true}, (cell, colNumber) => {
              if (cell.type === Excel.ValueType.RichText) {
                cells.push(cell.value.richText.filter((v) => !Immutable.fromJS(v).getIn(['font', 'strike'])).map((v) => v.text).join('').replace(/^[\r\n]*/g, '').replace(/\r\n/g, ' '))
              } else {
                cells.push(cell.type === Excel.ValueType.RichText ? cell.value : cell.toString())
              }
            })
            rows.push({cells})
          })
          sheets.push({name: worksheet.name, apiId: worksheet.getCell(1, 2).toString(), apiName: worksheet.getCell(1, 4).toString(), rows})
        })
        books.push({name: file, sheets})
        resolve(books)
      })
    })
  }
})

promises.push((books) => {
  return new Promise(() => {
    console.log('generate yml ...') // eslint-disable-line no-console
    books.map((book) => {
      book.sheets.map((sheet) => {
        const api = sheet.rows.reduce((r, row) => {
          // リクエストとレスポンスのオブジェクトに分ける
          if (row.cells.length <= 1) return r
          if (row.cells[0].toLowerCase() === 'request') {
            r.request = []
          } else if (row.cells[0].toLowerCase() === 'response') {
            r.response = []
          }
          const obj = (Number.isInteger(Number(row.cells[1]))) ? {
            level: Number(row.cells[1]),
            logicalName: row.cells[2],
            description: row.cells[3],
            countDef: row.cells[4],
            emptyDef: row.cells[5],
            physicalName: row.cells[6],
            type: row.cells[7],
            remark: row.cells[8]
          } : undefined
          if (r.response) {
            r.response.push(obj)
          } else if (r.request) {
            r.request.push(obj)
          }
          return r
        }, {})
        api.id = sheet.apiId
        api.name = sheet.apiName

        const createYaml = (structDef, apiType) => {
          const schema = Immutable.fromJS(structDef).reduce((r, v) => {
            // levelを元にして階層構造を構築
            if (v.get('level') === 1) {
              return r.push(v)
            }
            const findParentKey = (p, v) => {
              if (p.last().get('level') === v.get('level') - 1) {
                return Immutable.List.of(p.findLastKey(() => true))
              }
              return Immutable.fromJS([p.findLastKey(() => true), 'children']).push(...findParentKey(p.last().get('children'), v))
            }
            const parentKey = findParentKey(r, v)
            return r.setIn(parentKey.push('children'), (r.getIn(parentKey).get('children') || Immutable.List.of()).push(v))
          }, Immutable.List.of())
          .reduce((r, v) => {
            // JSON Schema 形式にする
            const getProperty = (v) => {
              const type = Utils.jsonType(v.get('type'))
              const children = (type === 'object') ? v.get('children').reduce((r, child) => {
                return r.mergeDeepIn(['properties'], getProperty(child))
              }, Immutable.fromJS({properties: {}})) : Immutable.fromJS({})
              return Immutable.fromJS({[v.get('physicalName')]: {title: v.get('logicalName'), description: v.get('description'), type: [type]}}).mergeDeepIn([v.get('physicalName')], children)
            }
            return r.mergeDeepIn(['properties'], getProperty(v))
          }, Immutable.fromJS({
            $schema: 'http://json-schema.org/draft-04/hyper-schema',
            title: api.id,
            description: api.name,
            type: ['object'],
            properties: {}
          })).toJS()
          fs.writeFileSync(`${__dirname}/../../../../docs/schema/gen/API${api.id}${apiType}.yml`, yaml.safeDump(schema))
        }
        createYaml(api.request, 'Request')
        createYaml(api.response, 'Response')
      })
      // return {title: '', description: book.name, type: ['object'], properties: {}}
    })
    // ejs.renderFile(join(__dirname, '/template/api_def.ejs'), {Immutable, books}, {}, (err, html) => {
    //   if (err) {
    //     console.log(`HTMLのrender処理でエラーが発生しました。\n${err}`) // eslint-disable-line no-console
    //   } else {
    //     fs.writeFileSync('./docs/excel/excel.html', html)
    //   }
    // })
  })
})

promises.reduce((r, v) => r.then(v), Promise.resolve([])).catch((err) => console.log(err)) // eslint-disable-line no-console
<commit_msg>不要なコメントアウトとrequire削除<commit_after>const fs = require('fs')
const Immutable = require('immutable')
const Excel = require('exceljs')
const yaml = require('js-yaml')

const Utils = require('./utils')
const config = require('./config')

if (!Utils.existsDirectory(config.jsonDefXlsxDir)) {
  console.log(`ディレクトリが存在しません。${config.jsonDefXlsxDir}`) // eslint-disable-line no-console
  return
}
const files = fs.readdirSync(config.jsonDefXlsxDir)

const promises = files.filter((file) => {
  return !file.startsWith('~$') && file.endsWith('.xlsx')
}).map((file) => {
  return (books) => {
    return new Promise((resolve) => {
      console.log(`reading ${config.jsonDefXlsxDir}/${file} ...`) // eslint-disable-line no-console
      const workbook = new Excel.Workbook()
      workbook.xlsx.readFile(`${config.jsonDefXlsxDir}/${file}`).then(() => {
        const sheets = []
        workbook.eachSheet((worksheet) => {
          if (!worksheet.name.match(/.*/)) return
          const rows = []
          worksheet.eachRow((row, rowNumber) => {
            const cells = []
            row.eachCell({includeEmpty: true}, (cell, colNumber) => {
              if (cell.type === Excel.ValueType.RichText) {
                cells.push(cell.value.richText.filter((v) => !Immutable.fromJS(v).getIn(['font', 'strike'])).map((v) => v.text).join('').replace(/^[\r\n]*/g, '').replace(/\r\n/g, ' '))
              } else {
                cells.push(cell.type === Excel.ValueType.RichText ? cell.value : cell.toString())
              }
            })
            rows.push({cells})
          })
          sheets.push({name: worksheet.name, apiId: worksheet.getCell(1, 2).toString(), apiName: worksheet.getCell(1, 4).toString(), rows})
        })
        books.push({name: file, sheets})
        resolve(books)
      })
    })
  }
})

promises.push((books) => {
  return new Promise(() => {
    console.log('generate yml ...') // eslint-disable-line no-console
    books.map((book) => {
      book.sheets.map((sheet) => {
        const api = sheet.rows.reduce((r, row) => {
          // リクエストとレスポンスのオブジェクトに分ける
          if (row.cells.length <= 1) return r
          if (row.cells[0].toLowerCase() === 'request') {
            r.request = []
          } else if (row.cells[0].toLowerCase() === 'response') {
            r.response = []
          }
          const obj = (Number.isInteger(Number(row.cells[1]))) ? {
            level: Number(row.cells[1]),
            logicalName: row.cells[2],
            description: row.cells[3],
            countDef: row.cells[4],
            emptyDef: row.cells[5],
            physicalName: row.cells[6],
            type: row.cells[7],
            remark: row.cells[8]
          } : undefined
          if (r.response) {
            r.response.push(obj)
          } else if (r.request) {
            r.request.push(obj)
          }
          return r
        }, {})
        api.id = sheet.apiId
        api.name = sheet.apiName

        const createYaml = (structDef, apiType) => {
          const schema = Immutable.fromJS(structDef).reduce((r, v) => {
            // levelを元にして階層構造を構築
            if (v.get('level') === 1) {
              return r.push(v)
            }
            const findParentKey = (p, v) => {
              if (p.last().get('level') === v.get('level') - 1) {
                return Immutable.List.of(p.findLastKey(() => true))
              }
              return Immutable.fromJS([p.findLastKey(() => true), 'children']).push(...findParentKey(p.last().get('children'), v))
            }
            const parentKey = findParentKey(r, v)
            return r.setIn(parentKey.push('children'), (r.getIn(parentKey).get('children') || Immutable.List.of()).push(v))
          }, Immutable.List.of())
          .reduce((r, v) => {
            // JSON Schema 形式にする
            const getProperty = (v) => {
              const type = Utils.jsonType(v.get('type'))
              const children = (type === 'object') ? v.get('children').reduce((r, child) => {
                return r.mergeDeepIn(['properties'], getProperty(child))
              }, Immutable.fromJS({properties: {}})) : Immutable.fromJS({})
              return Immutable.fromJS({[v.get('physicalName')]: {title: v.get('logicalName'), description: v.get('description'), type: [type]}}).mergeDeepIn([v.get('physicalName')], children)
            }
            return r.mergeDeepIn(['properties'], getProperty(v))
          }, Immutable.fromJS({
            $schema: 'http://json-schema.org/draft-04/hyper-schema',
            title: api.id,
            description: api.name,
            type: ['object'],
            properties: {}
          })).toJS()
          fs.writeFileSync(`${__dirname}/../../../../docs/schema/gen/API${api.id}${apiType}.yml`, yaml.safeDump(schema))
        }
        createYaml(api.request, 'Request')
        createYaml(api.response, 'Response')
      })
    })
  })
})

promises.reduce((r, v) => r.then(v), Promise.resolve([])).catch((err) => console.log(err)) // eslint-disable-line no-console
<|endoftext|>


<commit_before>/*
 * whip-o-matic
 * https://github.com/brianshumate/whip-o-matic
 * Based on:
 *
 * WTF Engine
 * Copyright 2011, Justin Windle
 * http://blog.soulwire.co.uk/
 * Code Licensed under the MIT licence.
 * https://github.com/soulwire/WTFEngine/blob/master/MIT-LICENSE.txt
 *
 * Concept based on WTFSIMFD
 * http://whatthefuckshouldimakefordinner.com/
 * by Zach Golden
 * http://www.zachgolden.com/
 *
 */

var templates = [
  "@adjective @properNoun was perfect",
  "@amount people appeared at the @adjective jam session in @place at @time",
  "He picked up a @noun and hit me upside the @noun once and in the @noun @amount times",
  "I love you like a @noun",
  "I saw @properNoun jamming live to a crowd of @amount in @place at @time on @date",
  "I then got off the @adjective @noun and @verbPast like a @adjective @noun",
  "I whipped @properNoun's ass",
  "It whipped a @noun's ass",
  "It whipped a @noun's ass real good",
  "@name can really jam hard like a @adjective @noun",
  "@name was mad as a @noun",
  "@name threatened my life with a @weapon",
  "@name tried to @verb my @adjective @noun at least @amount times",
  "@name pointed a @weapon at me in @place at @time on @date",
  "Suddenly, @noun and @noun went to @place and rocked the @noun",
  "The @adjective joyride transformed into a @adjective @noun",
  "The @adjective @noun was out of this world",
  "The @adjective @noun weighed @mass at @time",
  "The @noun is the reason why people @verb you",
  "The @noun was whipping the @noun's ass",
  "Tree my @noun and @verb me of my @noun",
  "When I went to @place that same @day, I picked up a @noun",
  "You can really @verb @name's @noun",
  "You are the most dangerous @noun that I have ever felt",
  "Your @adjective @noun is the @noun to our @noun"
];

var phrases = [
  "About to take you on a joyride...",
  "A magical joyride appears...",
	"This is a random joyride...",
  "This joyride brought to you by entropy..."
];

var labels = [
	"Whip it again!"
];

corpus = {};

corpus.address = ["737 New Hampshire Street", "4358 South Cottage Grove Avenue"];

corpus.adjective = ["12-gauge", "40-minute", "beautiful", "black", "chronic", "dead", "drunk", "early", "everlasting", "fabulous", "fat", "fatal", "fatty", "filthy", "first-degree", "freaking", "fucking", "good", "good-for-nothing", "good time", "greatest", "healthy", "high", "life-threatening", "little", "lowdown", "loving", "merry", "metal", "miserable", "nasty", "no-good", "poor", "psychotic", "punk", "rock and roll", "rotten", "shitty", "smelly", "stupid"];

corpus.adjectiveAn = ["affordable", "artistic", "awesome"];

corpus.adverb = ["vulgarly"];

corpus.age = ["thirty", "35", "46", "47", "52"];

corpus.amount = ["14", "200", "800", "900", "950", "1400", "4,000", "5,000", "35,000", "50,000", "100,000", "300,000", "one thousand", "six", "ten million", "twenty"];

corpus.date = ["April 4", "April 4", "August 31", "February 5", "March 5", "March 10"];

corpus.day = ["Saturday"];

corpus.distance = ["326 miles"];

corpus.duration = ["18 years", "25 years", "40-minute", "three-hour", "thirty minutes"];

corpus.exclamatoin = ["Amen!", "punk!"];

corpus.height = ["35,000 feet"];

corpus.name = ["Aftab Noorani", "Al Capone", "Alanis Morissette", "Arnold Schwarzenegger", "Ben Wigman", "Bill Clinton", "Bon Jovi", "Carla Winterbottom", "Clarence Weeks", "Courtney Love", "Dale Meiners", "Dave Grohl", "Eazy E", "Elvis Presley", "Jello Biafra", "Jesus Christ", "Jim Simm", "John Cook", "Johnny Depp", "John Dillard", "Johnny Inkslinger", "John Pole", "Johnny Rotten", "John Snap", "Kris Kringle", "Kurt Cobain", "Larry Nevers", "Liz Phair", "Louie Griff", "Louis Farrakhan", "Malice Green", "Michael Jackson", "Officer James Dudley", "O.J. Simpson", "Oprah Winfrey", "Reverend Henry E. Miller", "Reverend Richard Price", "Rick Sims", "Rodney King", "Saddam Hussein", "Trooper D. R. Johnson", "Walter Willis Shabazz", "Wesley Willis", "William Bell"];

corpus.noun = ["addict", "agents", "airplane", "alcohol", "album", "antelope shit", "artwork", "ass", "asscrack", "asshole", "baboon", "band", "beating", "blood", "bootyhole", "brother", "buffalo", "bullshit", "bus", "bus ride", "camel", "cannabis", "car", "caribou", "chain", "cheetah", "chicken", "chop", "church", "clink", "city", "cityscape", "cocaine", "cow", "crack", "crack rock", "creep", "daddy", "death metal", "demon", "dick", "dog", "dog shit", "dope", "drugs", "dumpster", "electric eel", "face", "family", "friend", "gangster", "ghetto", "godfather", "godson", "grave", "head", "hell", "hellride", "hospital", "house", "hyena", "inkpen", "jackoff", "jam", "jerk", "job", "joyride", "keyboard", "kiss", "law", "life", "lights", "lion", "llama", "loser", "love", "magikist", "man", "metal band", "millionaire", "milkshake", "money", "mother", "motherfucker", "mule shit", "mullet", "music joyride", "music", "oil", "outburst", "panda bear", "paraphernalia pipe", "people", "police", "policeman", "prison", "pulpit", "reindeer", "rock and roll", "scalawag", "schizophrenia", "schmuck", "sedatives", "session", "show", "skull", "skyscraper", "song", "stage", "star", "star ship", "snow leopard", "state police", "stoplight", "sweetheart", "tiger", "time", "trooper", "vampire", "van", "violence", "vulture", "wagon", "war hell ride", "weed", "whiskey", "woman", "woolly mammoth"];

corpus.place = ["America", "Aragon Ballroom", "Bottleneck", "California", "Chapel A.M.E. Zion Church", "Chicago", "Des Moines", "Detroit", "East Orange", "Europe", "Fort Dodge", "Hollywood", "Illinois", "Iowa", "jail", "Kansas", "Lawrence", "Los Angeles", "New Jersey", "Russia", "San Diego", "Seattle", "Texas", "the City Centre Theater", "Washington", "Wrigley Field"];

corpus.properNoun = ["88.1 KICB", "Agent Orange", "Alice in Chains", "Batman", "Big Mac", "Birdman", "Bolt Thrower", "Burger King", "Bushwick Bill", "CTA Bus", "Carquest", "Chevrolet", "Christmas", "CompUSA", "Dead Kennedys", "Earth", "El Dorado", "Electra 225", "FBI", "Folgers", "Ford Windstar", "God", "Greyhound", "Harpo Studios", "Illinois State Police", "In Utero", "Jadroplov", "KKK", "Knights of Columbus", "Maverick", "McDonalds", "Milk Bone", "Miracle Whip", "Mitsubishi", "Nirvana", "Northwest Airlines", "Packard Bell", "Pantera", "Pontiac", "Quarter Pounder", "Raid", "Smith & Wesson", "Sprint", "Sports Authority", "Subway", "Superman", "Technics KN3000 keyboard", "Taco Bell", "The Empty Bottle", "The Foo Fighters", "The Frogs", "The Home Depot", "The Metro", "The Wesley Willis Fiasco", "Western Union", "Viper Room", "Walgreens", "Westone",  "Wheaties", "White Castle", "WMFU", "Xerox"];

corpus.speed = ["90 miles per hour", "150 miles per hour"];

corpus.time = ["1:30 AM", "2:10 AM", "11:20 AM", "11:30 AM", "11:55 AM", "1:55 PM", "2:30 PM", "4:30 PM", "6:00 PM", "6:30 PM", "7:30 PM", "8:55 PM", "9:30 PM", "10:00 PM", "midnight"];

corpus.verb = ["beat", "blast", "brandish", "burn", "bust", "crack", "curse", "cut", "drive", "duke", "eat", "eject", "feel", "fill", "fuck", "hit", "knock", "kick", "kill", "kiss", "love", "make", "murder", "persecute", "play", "pull", "ride", "roar", "rock", "run", "screw", "shoot", "sing", "slim", "smash", "smoke", "stab", "suck", "throw","turn", "whip", "whip", "yell"];

corpus.verbPast = ["beat", "blasted", "brandished", "burned", "busted", "cracked", "cursed", "cut", "ate", "drove", "felt", "filled", "fucked", "hit", "knocked", "kicked", "killed", "kissed", "loved", "made", "murdered", "persecuted", "played", "pulled", "rode", "roared", "rocked", "ran", "sang", "screwed", "shot", "slashed", "slimmed", "smoked", "stabbed", "sucked", "threw", "turned", "whipped", "yelled"];

corpus.weapon = [".357 Magnum", ".38", ".38 caliber revolver", "12-gauge",  "baseball bat", "beating stick", "billy club", "box cutter", "gun", "handgun", "karate stick", "pistol", "semi-automatic", "Uzi submachine gun"];

corpus.mass = ["26 grams", "28 grams", "360 pounds", "397 pounds"];

corpus.year = ["1930", "1987", "1990", "1991", "1992", "1996", "1997"];

<commit_msg>even moar corpus twerking<commit_after>/*
 * whip-o-matic
 * https://github.com/brianshumate/whip-o-matic
 * Based on:
 *
 * WTF Engine
 * Copyright 2011, Justin Windle
 * http://blog.soulwire.co.uk/
 * Code Licensed under the MIT licence.
 * https://github.com/soulwire/WTFEngine/blob/master/MIT-LICENSE.txt
 *
 * Concept based on WTFSIMFD
 * http://whatthefuckshouldimakefordinner.com/
 * by Zach Golden
 * http://www.zachgolden.com/
 *
 */

var templates = [
  "@adjective @propernoun was perfect",
  "@amount people appeared at the @adjective jam session in @place at @time",
  "He picked up a @noun and hit me upside the @noun once and in the @noun @amount times",
  "I love you like a @noun",
  "I saw @propernoun jamming live to a crowd of @amount in @place at @time on @date",
  "I then got off the @adjective @noun and @pastverb like a @adjective @noun",
  "I whipped @propernoun's ass",
  "It whipped a @noun's ass",
  "It whipped a @noun's ass real good",
  "@name can really jam hard like a @adjective @noun",
  "@name was mad as a @noun",
  "@name threatened my life with a @weapon",
  "@name tried to @verb my @adjective @noun at least @amount times",
  "@name pointed a @weapon at me in @place at @time on @date",
  "Suddenly, @noun and @noun went to @place and rocked the @noun",
  "The @adjective joyride transformed into a @adjective @noun",
  "The @adjective @noun was out of this world",
  "The @adjective @noun weighed @mass at @time",
  "The @noun is the reason why people @verb you",
  "The @noun was whipping the @noun's ass",
  "Tree my @noun and @verb me of my @noun",
  "When I went to @place that same @day, I picked up a @noun",
  "You can really @verb @name's @noun",
  "You are the most dangerous @noun that I have ever felt",
  "Your @adjective @noun is the @noun to our @noun"
];

var phrases = [
  "About to take you on a joyride...",
  "A magical joyride appears...",
	"This is a random joyride...",
  "This joyride brought to you by entropy..."
];

var labels = [
	"Whip it again!"
];

corpus = {};

corpus.address = ["737 New Hampshire Street", "4358 South Cottage Grove Avenue"];

corpus.adjective = ["12-gauge", "40-minute", "beautiful", "black", "chronic", "dead", "drunk", "early", "everlasting", "fabulous", "fat", "fatal", "fatty", "filthy", "first-degree", "freaking", "fucking", "good", "good-for-nothing", "good time", "greatest", "healthy", "high", "life-threatening", "little", "lowdown", "loving", "merry", "metal", "miserable", "nasty", "no-good", "poor", "psychotic", "punk", "rock and roll", "rotten", "shitty", "smelly", "stupid"];

corpus.adverb = ["vulgarly"];

corpus.age = ["thirty", "35", "46", "47", "52"];

corpus.anadjective = ["affordable", "artistic", "awesome"];

corpus.amount = ["14", "200", "800", "900", "950", "1400", "4,000", "5,000", "35,000", "50,000", "100,000", "300,000", "one thousand", "six", "ten million", "twenty"];

corpus.date = ["April 4", "April 4", "August 31", "February 5", "March 5", "March 10"];

corpus.day = ["Saturday"];

corpus.distance = ["326 miles"];

corpus.duration = ["18 years", "25 years", "40-minute", "three-hour", "thirty minutes"];

corpus.exclamatoin = ["Amen!", "punk!"];

corpus.height = ["35,000 feet"];

corpus.mass = ["26 grams", "28 grams", "360 pounds", "397 pounds"];

corpus.name = ["Aftab Noorani", "Al Capone", "Alanis Morissette", "Arnold Schwarzenegger", "Ben Wigman", "Bill Clinton", "Bon Jovi", "Carla Winterbottom", "Clarence Weeks", "Courtney Love", "Dale Meiners", "Dave Grohl", "Eazy E", "Elvis Presley", "Jello Biafra", "Jesus Christ", "Jim Simm", "John Cook", "Johnny Depp", "John Dillard", "Johnny Inkslinger", "John Pole", "Johnny Rotten", "John Snap", "Kris Kringle", "Kurt Cobain", "Larry Nevers", "Liz Phair", "Louie Griff", "Louis Farrakhan", "Malice Green", "Michael Jackson", "Officer James Dudley", "O.J. Simpson", "Oprah Winfrey", "Reverend Henry E. Miller", "Reverend Richard Price", "Rick Sims", "Rodney King", "Saddam Hussein", "Trooper D. R. Johnson", "Walter Willis Shabazz", "Wesley Willis", "William Bell"];

corpus.noun = ["addict", "agents", "airplane", "alcohol", "album", "antelope shit", "artwork", "ass", "asscrack", "asshole", "baboon", "band", "beating", "blood", "bootyhole", "brother", "buffalo", "bullshit", "bus", "bus ride", "camel", "cannabis", "car", "caribou", "chain", "cheetah", "chicken", "chop", "church", "clink", "city", "cityscape", "cocaine", "cow", "crack", "crack rock", "creep", "daddy", "death metal", "demon", "dick", "dog", "dog shit", "dope", "drugs", "dumpster", "electric eel", "face", "family", "friend", "gangster", "ghetto", "godfather", "godson", "grave", "head", "hell", "hellride", "hospital", "house", "hyena", "inkpen", "jackoff", "jam", "jerk", "job", "joyride", "keyboard", "kiss", "law", "life", "lights", "lion", "llama", "loser", "love", "magikist", "man", "metal band", "millionaire", "milkshake", "money", "mother", "motherfucker", "mule shit", "mullet", "music joyride", "music", "oil", "outburst", "panda bear", "paraphernalia pipe", "people", "police", "policeman", "prison", "pulpit", "reindeer", "rock and roll", "scalawag", "schizophrenia", "schmuck", "sedatives", "session", "show", "skull", "skyscraper", "song", "stage", "star", "star ship", "snow leopard", "state police", "stoplight", "sweetheart", "tiger", "time", "trooper", "vampire", "van", "violence", "vulture", "wagon", "war hell ride", "weed", "whiskey", "woman", "woolly mammoth"];

corpus.pastverb = ["beat", "blasted", "brandished", "burned", "busted", "cracked", "cursed", "cut", "ate", "drove", "felt", "filled", "fucked", "hit", "knocked", "kicked", "killed", "kissed", "loved", "made", "murdered", "persecuted", "played", "pulled", "rode", "roared", "rocked", "ran", "sang", "screwed", "shot", "slashed", "slimmed", "smoked", "stabbed", "sucked", "threw", "turned", "whipped", "yelled"];

corpus.place = ["America", "Aragon Ballroom", "Bottleneck", "California", "Chapel A.M.E. Zion Church", "Chicago", "Des Moines", "Detroit", "East Orange", "Europe", "Fort Dodge", "Hollywood", "Illinois", "Iowa", "jail", "Kansas", "Lawrence", "Los Angeles", "New Jersey", "Russia", "San Diego", "Seattle", "Texas", "the City Centre Theater", "Washington", "Wrigley Field"];

corpus.propernoun = ["88.1 KICB", "Agent Orange", "Alice in Chains", "Batman", "Big Mac", "Birdman", "Bolt Thrower", "Burger King", "Bushwick Bill", "CTA Bus", "Carquest", "Chevrolet", "Christmas", "CompUSA", "Dead Kennedys", "Earth", "El Dorado", "Electra 225", "FBI", "Folgers", "Ford Windstar", "God", "Greyhound", "Harpo Studios", "Illinois State Police", "In Utero", "Jadroplov", "KKK", "Knights of Columbus", "Maverick", "McDonalds", "Milk Bone", "Miracle Whip", "Mitsubishi", "Nirvana", "Northwest Airlines", "Packard Bell", "Pantera", "Pontiac", "Quarter Pounder", "Raid", "Smith & Wesson", "Sprint", "Sports Authority", "Subway", "Superman", "Technics KN3000 keyboard", "Taco Bell", "The Empty Bottle", "The Foo Fighters", "The Frogs", "The Home Depot", "The Metro", "The Wesley Willis Fiasco", "Western Union", "Viper Room", "Walgreens", "Westone",  "Wheaties", "White Castle", "WMFU", "Xerox"];

corpus.speed = ["90 miles per hour", "150 miles per hour"];

corpus.time = ["1:30 AM", "2:10 AM", "11:20 AM", "11:30 AM", "11:55 AM", "1:55 PM", "2:30 PM", "4:30 PM", "6:00 PM", "6:30 PM", "7:30 PM", "8:55 PM", "9:30 PM", "10:00 PM", "midnight"];

corpus.verb = ["beat", "blast", "brandish", "burn", "bust", "crack", "curse", "cut", "drive", "duke", "eat", "eject", "feel", "fill", "fuck", "hit", "knock", "kick", "kill", "kiss", "love", "make", "murder", "persecute", "play", "pull", "ride", "roar", "rock", "run", "screw", "shoot", "sing", "slim", "smash", "smoke", "stab", "suck", "throw", "turn", "whip", "whip", "yell"];

corpus.weapon = [".357 Magnum", ".38", ".38 caliber revolver", "12-gauge",  "baseball bat", "beating stick", "billy club", "box cutter", "gun", "handgun", "karate stick", "pistol", "semi-automatic", "Uzi submachine gun"];

corpus.year = ["1930", "1987", "1990", "1991", "1992", "1996", "1997"];

<|endoftext|>