<commit_before>/*!
 * numeral.js
 * version : 1.5.3
 * author : Adam Draper
 * license : MIT
 * http://adamwdraper.github.com/Numeral-js/
 */

define(["underscore"], function(_) {

    var languages = {};
    var defaultFormat = '0,0';
    var defaultLanguage = 'en';

    /**
     * Implementation of toFixed() that treats floats more like decimals
     *
     * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
     * problems for accounting- and finance-related software.
     */
    function toFixed(value, precision, roundingFunction, optionals) {
        var power = Math.pow(10, precision),
            optionalsRegExp,
            output;

        // roundingFunction = (roundingFunction !== undefined ? roundingFunction : Math.round);
        // Multiply up by precision, round accurately, then divide and use native toFixed():
        output = (roundingFunction(value * power) / power).toFixed(precision);

        if (optionals) {
            optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
            output = output.replace(optionalsRegExp, '');
        }

        return output;
    }

    // determine what type of formatting we need to do
    function formatNumeral(value, format, language, roundingFunction) {
        var output;

        // figure out what kind of format we are dealing with
        if (format.indexOf('$') > -1) { // currency!!!!!
            output = formatCurrency(value, format, language, roundingFunction);
        } else if (format.indexOf('%') > -1) { // percentage
            output = formatPercentage(value, format, language, roundingFunction);
        } else if (format.indexOf(':') > -1) { // time
            output = formatTime(value, format, language);
        } else { // plain ol' numbers or bytes
            output = formatNumber(value, format, language, roundingFunction);
        }

        return output;
    }

    function formatCurrency(value, format, language, roundingFunction) {
        var symbolIndex = format.indexOf('$'),
            openParenIndex = format.indexOf('('),
            minusSignIndex = format.indexOf('-'),
            space = '',
            spliceIndex,
            output;

        // check for space before or after currency
        if (format.indexOf(' $') > -1) {
            space = ' ';
            format = format.replace(' $', '');
        } else if (format.indexOf('$ ') > -1) {
            space = ' ';
            format = format.replace('$ ', '');
        } else {
            format = format.replace('$', '');
        }

        // format the number
        output = formatNumber(value, format, language, roundingFunction);

        // position the symbol
        if (symbolIndex <= 1) {
            if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
                output = output.split('');
                spliceIndex = 1;
                if (symbolIndex < openParenIndex || symbolIndex < minusSignIndex){
                    // the symbol appears before the "(" or "-"
                    spliceIndex = 0;
                }
                output.splice(spliceIndex, 0, language.currency.symbol + space);
                output = output.join('');
            } else {
                output = language.currency.symbol + space + output;
            }
        } else {
            if (output.indexOf(')') > -1) {
                output = output.split('');
                output.splice(-1, 0, space + language.currency.symbol);
                output = output.join('');
            } else {
                output = output + space + language.currency.symbol;
            }
        }

        return output;
    }

    function formatPercentage(value, format, language, roundingFunction) {
        var space = '',
            output,
            value = value * 100;

        // check for space before %
        if (format.indexOf(' %') > -1) {
            space = ' ';
            format = format.replace(' %', '');
        } else {
            format = format.replace('%', '');
        }

        output = formatNumber(value, format, language, roundingFunction);

        if (output.indexOf(')') > -1 ) {
            output = output.split('');
            output.splice(-1, 0, space + '%');
            output = output.join('');
        } else {
            output = output + space + '%';
        }

        return output;
    }

    function formatTime(value, language) {
        var hours = Math.floor(value/60/60),
            minutes = Math.floor((value - (hours * 60 * 60))/60),
            seconds = Math.round(value - (hours * 60 * 60) - (minutes * 60));
        return hours + ':' + ((minutes < 10) ? '0' + minutes : minutes) + ':' + ((seconds < 10) ? '0' + seconds : seconds);
    }

    function formatNumber(value, format, language, roundingFunction) {
        var negP = false,
            signed = false,
            optDec = false,
            abbr = '',
            abbrK = false, // force abbreviation to thousands
            abbrM = false, // force abbreviation to millions
            abbrB = false, // force abbreviation to billions
            abbrT = false, // force abbreviation to trillions
            abbrForce = false, // force abbreviation
            bytes = '',
            ord = '',
            abs = Math.abs(value),
            suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
            min,
            max,
            power,
            w,
            precision,
            thousands,
            d = '',
            neg = false;

        // see if we should use parentheses for negative number or if we should prefix with a sign
        // if both are present we default to parentheses
        if (format.indexOf('(') > -1) {
            negP = true;
            format = format.slice(1, -1);
        } else if (format.indexOf('+') > -1) {
            signed = true;
            format = format.replace(/\+/g, '');
        }

        // see if abbreviation is wanted
        if (format.indexOf('a') > -1) {
            // check if abbreviation is specified
            abbrK = format.indexOf('aK') >= 0;
            abbrM = format.indexOf('aM') >= 0;
            abbrB = format.indexOf('aB') >= 0;
            abbrT = format.indexOf('aT') >= 0;
            abbrForce = abbrK || abbrM || abbrB || abbrT;

            // check for space before abbreviation
            if (format.indexOf(' a') > -1) {
                abbr = ' ';
                format = format.replace(' a', '');
            } else {
                format = format.replace('a', '');
            }

            if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
                // trillion
                abbr = abbr + language.abbreviations.trillion;
                value = value / Math.pow(10, 12);
            } else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
                // billion
                abbr = abbr + language.abbreviations.billion;
                value = value / Math.pow(10, 9);
            } else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
                // million
                abbr = abbr + language.abbreviations.million;
                value = value / Math.pow(10, 6);
            } else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
                // thousand
                abbr = abbr + language.abbreviations.thousand;
                value = value / Math.pow(10, 3);
            }
        }

        // see if we are formatting bytes
        if (format.indexOf('b') > -1) {
            // check for space before
            if (format.indexOf(' b') > -1) {
                bytes = ' ';
                format = format.replace(' b', '');
            } else {
                format = format.replace('b', '');
            }

            for (power = 0; power <= suffixes.length; power++) {
                min = Math.pow(1024, power);
                max = Math.pow(1024, power+1);

                if (value >= min && value < max) {
                    bytes = bytes + suffixes[power];
                    if (min > 0) {
                        value = value / min;
                    }
                    break;
                }
            }
        }

        // see if ordinal is wanted
        if (format.indexOf('o') > -1) {
            // check for space before
            if (format.indexOf(' o') > -1) {
                ord = ' ';
                format = format.replace(' o', '');
            } else {
                format = format.replace('o', '');
            }

            ord = ord + language.ordinal(value);
        }

        if (format.indexOf('[.]') > -1) {
            optDec = true;
            format = format.replace('[.]', '.');
        }

        w = value.toString().split('.')[0];
        precision = format.split('.')[1];
        thousands = format.indexOf(',');

        if (precision) {
            if (precision.indexOf('[') > -1) {
                precision = precision.replace(']', '');
                precision = precision.split('[');
                d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);
            } else {
                d = toFixed(value, precision.length, roundingFunction);
            }

            w = d.split('.')[0];

            if (d.split('.')[1].length) {
                d = language.delimiters.decimal + d.split('.')[1];
            } else {
                d = '';
            }

            if (optDec && Number(d.slice(1)) === 0) {
                d = '';
            }
        } else {
            w = toFixed(value, null, roundingFunction);
        }

        // format number
        if (w.indexOf('-') > -1) {
            w = w.slice(1);
            neg = true;
        }

        if (thousands > -1) {
            w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + language.delimiters.thousands);
        }

        if (format.indexOf('.') === 0) {
            w = '';
        }

        return ((negP && neg) ? '(' : '') + ((!negP && neg) ? '-' : '') + ((!neg && signed) ? '+' : '') + w + d + ((ord) ? ord : '') + ((abbr) ? abbr : '') + ((bytes) ? bytes : '') + ((negP && neg) ? ')' : '');
    }

    function addLanguage(key, spec) {
        languages[key] = spec;
    }

    addLanguage('en', {
        delimiters: {
            thousands: ',',
            decimal:   '.'
        },
        abbreviations: {
            thousand: 'k',
            million:  'm',
            billion:  'b',
            trillion: 't'
        },
        ordinal: function (number) {
            var b = number % 10;
            return (~~ (number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                (b === 2) ? 'nd' :
                (b === 3) ? 'rd' : 'th';
        },
        currency: {
            symbol: '$'
        }
    });

    function format(input, formatString, language, roundingFunction) {
        return formatNumeral(
            Number(input),
            _.isString(formatString)        ? formatString        : defaultFormat,
            _.isString(language)            ? languages[language] : languages[defaultLanguage],
            _.isUndefined(roundingFunction) ? Math.round          : roundingFunction);
    }

    return {"format": format};
});
<commit_msg>Nicely format long code line in numeral<commit_after>/*!
 * numeral.js
 * version : 1.5.3
 * author : Adam Draper
 * license : MIT
 * http://adamwdraper.github.com/Numeral-js/
 */

define(["underscore"], function(_) {

    var languages = {};
    var defaultFormat = '0,0';
    var defaultLanguage = 'en';

    /**
     * Implementation of toFixed() that treats floats more like decimals
     *
     * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
     * problems for accounting- and finance-related software.
     */
    function toFixed(value, precision, roundingFunction, optionals) {
        var power = Math.pow(10, precision),
            optionalsRegExp,
            output;

        // roundingFunction = (roundingFunction !== undefined ? roundingFunction : Math.round);
        // Multiply up by precision, round accurately, then divide and use native toFixed():
        output = (roundingFunction(value * power) / power).toFixed(precision);

        if (optionals) {
            optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
            output = output.replace(optionalsRegExp, '');
        }

        return output;
    }

    // determine what type of formatting we need to do
    function formatNumeral(value, format, language, roundingFunction) {
        var output;

        // figure out what kind of format we are dealing with
        if (format.indexOf('$') > -1) { // currency!!!!!
            output = formatCurrency(value, format, language, roundingFunction);
        } else if (format.indexOf('%') > -1) { // percentage
            output = formatPercentage(value, format, language, roundingFunction);
        } else if (format.indexOf(':') > -1) { // time
            output = formatTime(value, format, language);
        } else { // plain ol' numbers or bytes
            output = formatNumber(value, format, language, roundingFunction);
        }

        return output;
    }

    function formatCurrency(value, format, language, roundingFunction) {
        var symbolIndex = format.indexOf('$'),
            openParenIndex = format.indexOf('('),
            minusSignIndex = format.indexOf('-'),
            space = '',
            spliceIndex,
            output;

        // check for space before or after currency
        if (format.indexOf(' $') > -1) {
            space = ' ';
            format = format.replace(' $', '');
        } else if (format.indexOf('$ ') > -1) {
            space = ' ';
            format = format.replace('$ ', '');
        } else {
            format = format.replace('$', '');
        }

        // format the number
        output = formatNumber(value, format, language, roundingFunction);

        // position the symbol
        if (symbolIndex <= 1) {
            if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
                output = output.split('');
                spliceIndex = 1;
                if (symbolIndex < openParenIndex || symbolIndex < minusSignIndex){
                    // the symbol appears before the "(" or "-"
                    spliceIndex = 0;
                }
                output.splice(spliceIndex, 0, language.currency.symbol + space);
                output = output.join('');
            } else {
                output = language.currency.symbol + space + output;
            }
        } else {
            if (output.indexOf(')') > -1) {
                output = output.split('');
                output.splice(-1, 0, space + language.currency.symbol);
                output = output.join('');
            } else {
                output = output + space + language.currency.symbol;
            }
        }

        return output;
    }

    function formatPercentage(value, format, language, roundingFunction) {
        var space = '',
            output,
            value = value * 100;

        // check for space before %
        if (format.indexOf(' %') > -1) {
            space = ' ';
            format = format.replace(' %', '');
        } else {
            format = format.replace('%', '');
        }

        output = formatNumber(value, format, language, roundingFunction);

        if (output.indexOf(')') > -1 ) {
            output = output.split('');
            output.splice(-1, 0, space + '%');
            output = output.join('');
        } else {
            output = output + space + '%';
        }

        return output;
    }

    function formatTime(value, language) {
        var hours = Math.floor(value/60/60),
            minutes = Math.floor((value - (hours * 60 * 60))/60),
            seconds = Math.round(value - (hours * 60 * 60) - (minutes * 60));
        return hours + ':' + ((minutes < 10) ? '0' + minutes : minutes) + ':' + ((seconds < 10) ? '0' + seconds : seconds);
    }

    function formatNumber(value, format, language, roundingFunction) {
        var negP = false,
            signed = false,
            optDec = false,
            abbr = '',
            abbrK = false, // force abbreviation to thousands
            abbrM = false, // force abbreviation to millions
            abbrB = false, // force abbreviation to billions
            abbrT = false, // force abbreviation to trillions
            abbrForce = false, // force abbreviation
            bytes = '',
            ord = '',
            abs = Math.abs(value),
            suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
            min,
            max,
            power,
            w,
            precision,
            thousands,
            d = '',
            neg = false;

        // see if we should use parentheses for negative number or if we should prefix with a sign
        // if both are present we default to parentheses
        if (format.indexOf('(') > -1) {
            negP = true;
            format = format.slice(1, -1);
        } else if (format.indexOf('+') > -1) {
            signed = true;
            format = format.replace(/\+/g, '');
        }

        // see if abbreviation is wanted
        if (format.indexOf('a') > -1) {
            // check if abbreviation is specified
            abbrK = format.indexOf('aK') >= 0;
            abbrM = format.indexOf('aM') >= 0;
            abbrB = format.indexOf('aB') >= 0;
            abbrT = format.indexOf('aT') >= 0;
            abbrForce = abbrK || abbrM || abbrB || abbrT;

            // check for space before abbreviation
            if (format.indexOf(' a') > -1) {
                abbr = ' ';
                format = format.replace(' a', '');
            } else {
                format = format.replace('a', '');
            }

            if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
                // trillion
                abbr = abbr + language.abbreviations.trillion;
                value = value / Math.pow(10, 12);
            } else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
                // billion
                abbr = abbr + language.abbreviations.billion;
                value = value / Math.pow(10, 9);
            } else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
                // million
                abbr = abbr + language.abbreviations.million;
                value = value / Math.pow(10, 6);
            } else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
                // thousand
                abbr = abbr + language.abbreviations.thousand;
                value = value / Math.pow(10, 3);
            }
        }

        // see if we are formatting bytes
        if (format.indexOf('b') > -1) {
            // check for space before
            if (format.indexOf(' b') > -1) {
                bytes = ' ';
                format = format.replace(' b', '');
            } else {
                format = format.replace('b', '');
            }

            for (power = 0; power <= suffixes.length; power++) {
                min = Math.pow(1024, power);
                max = Math.pow(1024, power+1);

                if (value >= min && value < max) {
                    bytes = bytes + suffixes[power];
                    if (min > 0) {
                        value = value / min;
                    }
                    break;
                }
            }
        }

        // see if ordinal is wanted
        if (format.indexOf('o') > -1) {
            // check for space before
            if (format.indexOf(' o') > -1) {
                ord = ' ';
                format = format.replace(' o', '');
            } else {
                format = format.replace('o', '');
            }

            ord = ord + language.ordinal(value);
        }

        if (format.indexOf('[.]') > -1) {
            optDec = true;
            format = format.replace('[.]', '.');
        }

        w = value.toString().split('.')[0];
        precision = format.split('.')[1];
        thousands = format.indexOf(',');

        if (precision) {
            if (precision.indexOf('[') > -1) {
                precision = precision.replace(']', '');
                precision = precision.split('[');
                d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);
            } else {
                d = toFixed(value, precision.length, roundingFunction);
            }

            w = d.split('.')[0];

            if (d.split('.')[1].length) {
                d = language.delimiters.decimal + d.split('.')[1];
            } else {
                d = '';
            }

            if (optDec && Number(d.slice(1)) === 0) {
                d = '';
            }
        } else {
            w = toFixed(value, null, roundingFunction);
        }

        // format number
        if (w.indexOf('-') > -1) {
            w = w.slice(1);
            neg = true;
        }

        if (thousands > -1) {
            w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + language.delimiters.thousands);
        }

        if (format.indexOf('.') === 0) {
            w = '';
        }

        return
            ((negP && neg) ? '(' : '') +
            ((!negP && neg) ? '-' : '') +
            ((!neg && signed) ? '+' : '') +
            w +
            d +
            ((ord) ? ord : '') +
            ((abbr) ? abbr : '') +
            ((bytes) ? bytes : '') +
            ((negP && neg) ? ')' : '');
    }

    function addLanguage(key, spec) {
        languages[key] = spec;
    }

    addLanguage('en', {
        delimiters: {
            thousands: ',',
            decimal:   '.'
        },
        abbreviations: {
            thousand: 'k',
            million:  'm',
            billion:  'b',
            trillion: 't'
        },
        ordinal: function (number) {
            var b = number % 10;
            return (~~ (number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                (b === 2) ? 'nd' :
                (b === 3) ? 'rd' : 'th';
        },
        currency: {
            symbol: '$'
        }
    });

    function format(input, formatString, language, roundingFunction) {
        return formatNumeral(
            Number(input),
            _.isString(formatString)        ? formatString        : defaultFormat,
            _.isString(language)            ? languages[language] : languages[defaultLanguage],
            _.isUndefined(roundingFunction) ? Math.round          : roundingFunction);
    }

    return {"format": format};
});
<|endoftext|>


<commit_before>const rx = require('rx');
const _ = require('underscore-plus');

class PlayerInteraction {
  // Public: Poll players that want to join the game during a specified period
  // of time.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  // maxPlayers - (Optional) The maximum number of players to allow
  //
  // Returns an {Observable} that will `onNext` for each player that joins and
  // `onCompleted` when time expires or the max number of players join.
  static pollPotentialPlayers(messages, channel, scheduler=rx.Scheduler.timeout, timeout=10, maxPlayers=10) {
    let formatMessage = t => `Who wants to play? Respond with 'yes' in this channel in the next ${t} seconds.`;
    let timeExpired = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);

    // Look for messages containing the word 'yes' and map them to a unique
    // user ID, constrained to `maxPlayers` number of players.
    let newPlayers = messages.where(e => e.text && e.text.toLowerCase().match(/\byes\b/))
      .map(e => e.user)
      .distinct()
      .take(maxPlayers)
      .publish();

    newPlayers.connect();
    timeExpired.connect();

    // Once our timer has expired, we're done accepting new players.
    return newPlayers.takeUntil(timeExpired);
  }

  // Public: Poll a specific player to take a poker action, within a timeout.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // player - The player being polled
  // previousActions - A map of players to their most recent action
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  //
  // Returns an {Observable} indicating the action the player took. If time
  // expires, a 'timeout' action is returned.
  static getActionForPlayer(messages, channel, player, previousActions,
    scheduler=rx.Scheduler.timeout, timeout=30) {
    let availableActions = PlayerInteraction.getAvailableActions(player, previousActions);
    let formatMessage = t => PlayerInteraction.buildActionMessage(player, availableActions, t);

    let timeExpired = null;
    let expiredDisp = null;
    if (timeout > 0) {
      timeExpired = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);
      expiredDisp = timeExpired.connect();
    } else {
      channel.send(formatMessage(0));
      timeExpired = rx.Observable.never();
      expiredDisp = rx.Disposable.empty;
    }

    // Look for text that conforms to a player action.
    let playerAction = messages.where(e => e.user === player.id)
      .map(e => PlayerInteraction.actionFromMessage(e.text, availableActions))
      .where(action => action !== null)
      .publish();

    playerAction.connect();

    // If the user times out, they will be auto-folded unless they can check.
    let actionForTimeout = timeExpired.map(() =>
      availableActions.indexOf('check') > -1 ?
        { name: 'check' } :
        { name: 'fold' });

    let botAction = player.isBot ?
      player.getAction(availableActions, previousActions) :
      rx.Observable.never();

    // NB: Take the first result from the player action, the timeout, and a bot
    // action (only applicable to bots).
    return rx.Observable.merge(playerAction, actionForTimeout, botAction)
      .take(1)
      .do(() => expiredDisp.dispose());
  }

  // Private: Posts a message to the channel with some timeout, that edits
  // itself each second to provide a countdown.
  //
  // channel - The channel to post in
  // formatMessage - A function that will be invoked once per second with the
  //                 remaining time, and returns the formatted message content
  // scheduler - The scheduler to use for timing events
  // timeout - The duration of the message, in seconds
  //
  // Returns an {Observable} sequence that signals expiration of the message
  static postMessageWithTimeout(channel, formatMessage, scheduler, timeout) {
    let timeoutMessage = channel.send(formatMessage(timeout));

    let timeExpired = rx.Observable.timer(0, 1000, scheduler)
      .take(timeout + 1)
      .do((x) => timeoutMessage.updateMessage(formatMessage(`${timeout - x}`)))
      .publishLast();

    return timeExpired;
  }

  // Private: Builds up a formatted countdown message containing the available
  // actions.
  //
  // player - The player who is acting
  // availableActions - An array of the actions available to this player
  // timeRemaining - Number of seconds remaining for the player to act
  //
  // Returns the formatted string
  static buildActionMessage(player, availableActions, timeRemaining) {
    let message = `${player.name}, it's your turn. Respond with:\n`;
    for (let action of availableActions) {
      message += `*(${action.charAt(0).toUpperCase()})${action.slice(1)}*\t`;
    }

    if (timeRemaining > 0) {
      message += `\nin the next ${timeRemaining} seconds.`;
    }

    return message;
  }

  // Private: Given an array of actions taken previously in the hand, returns
  // an array of available actions.
  //
  // player - The player who is acting
  // previousActions - A map of players to their most recent action
  //
  // Returns an array of strings
  static getAvailableActions(player, previousActions) {
    let actions = _.values(previousActions);
    let betActions = _.filter(actions, a => a.name === 'bet' || a.name === 'raise');
    let hasBet = betActions.length > 0;

    let availableActions = [];

    if (player.hasOption) {
      availableActions.push('check');
      availableActions.push('raise');
    } else if (hasBet) {
      availableActions.push('call');
      availableActions.push('raise');
    } else {
      availableActions.push('check');
      availableActions.push('bet');
    }

    // Prevent players from raising when they don't have enough chips.
    let raiseIndex = availableActions.indexOf('raise');
    if (raiseIndex > -1) {
      let previousWager = player.lastAction ? player.lastAction.amount : 0;
      let availableChips = player.chips + previousWager;

      if (_.max(betActions, a => a.amount).amount >= availableChips) {
        availableActions.splice(raiseIndex, 1);
      }
    }

    availableActions.push('fold');
    return availableActions;
  }

  // Private: Parse player input into a valid action.
  //
  // text - The text that the player entered
  // availableActions - An array of the actions available to this player
  //
  // Returns an object representing the action, with keys for the name and
  // bet amount, or null if the input was invalid.
  static actionFromMessage(text, availableActions) {
    if (!text) return null;

    let input = text.trim().toLowerCase().split(/\s+/);
    if (!input[0]) return null;

    let name = '';
    let amount = 0;

    switch (input[0]) {
    case 'c':
      name = availableActions[0];
      break;
    case 'call':
      name = 'call';
      break;
    case 'check':
      name = 'check';
      break;
    case 'f':
    case 'fold':
      name = 'fold';
      break;
    case 'b':
    case 'bet':
      name = 'bet';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    case 'r':
    case 'raise':
      name = 'raise';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    default:
      return null;
    }

    // NB: Unavailable actions are always invalid.
    return availableActions.indexOf(name) > -1 ?
      { name: name, amount: amount } :
      null;
  }
}

module.exports = PlayerInteraction;
<commit_msg>Update player-interaction.js<commit_after>const rx = require('rx');
const _ = require('underscore-plus');

class PlayerInteraction {
  // Public: Poll players that want to join the game during a specified period
  // of time.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  // maxPlayers - (Optional) The maximum number of players to allow
  //
  // Returns an {Observable} that will `onNext` for each player that joins and
  // `onCompleted` when time expires or the max number of players join.
  static pollPotentialPlayers(messages, channel, scheduler=rx.Scheduler.timeout, timeout=20, maxPlayers=10) {
    let formatMessage = t => `Who wants to play? Respond with 'yes' in this channel in the next ${t} seconds.`;
    let timeExpired = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);

    // Look for messages containing the word 'yes' and map them to a unique
    // user ID, constrained to `maxPlayers` number of players.
    let newPlayers = messages.where(e => e.text && e.text.toLowerCase().match(/\byes\b/))
      .map(e => e.user)
      .distinct()
      .take(maxPlayers)
      .publish();

    newPlayers.connect();
    timeExpired.connect();

    // Once our timer has expired, we're done accepting new players.
    return newPlayers.takeUntil(timeExpired);
  }

  // Public: Poll a specific player to take a poker action, within a timeout.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // player - The player being polled
  // previousActions - A map of players to their most recent action
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  //
  // Returns an {Observable} indicating the action the player took. If time
  // expires, a 'timeout' action is returned.
  static getActionForPlayer(messages, channel, player, previousActions,
    scheduler=rx.Scheduler.timeout, timeout=30) {
    let availableActions = PlayerInteraction.getAvailableActions(player, previousActions);
    let formatMessage = t => PlayerInteraction.buildActionMessage(player, availableActions, t);

    let timeExpired = null;
    let expiredDisp = null;
    if (timeout > 0) {
      timeExpired = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);
      expiredDisp = timeExpired.connect();
    } else {
      channel.send(formatMessage(0));
      timeExpired = rx.Observable.never();
      expiredDisp = rx.Disposable.empty;
    }

    // Look for text that conforms to a player action.
    let playerAction = messages.where(e => e.user === player.id)
      .map(e => PlayerInteraction.actionFromMessage(e.text, availableActions))
      .where(action => action !== null)
      .publish();

    playerAction.connect();

    // If the user times out, they will be auto-folded unless they can check.
    let actionForTimeout = timeExpired.map(() =>
      availableActions.indexOf('check') > -1 ?
        { name: 'check' } :
        { name: 'fold' });

    let botAction = player.isBot ?
      player.getAction(availableActions, previousActions) :
      rx.Observable.never();

    // NB: Take the first result from the player action, the timeout, and a bot
    // action (only applicable to bots).
    return rx.Observable.merge(playerAction, actionForTimeout, botAction)
      .take(1)
      .do(() => expiredDisp.dispose());
  }

  // Private: Posts a message to the channel with some timeout, that edits
  // itself each second to provide a countdown.
  //
  // channel - The channel to post in
  // formatMessage - A function that will be invoked once per second with the
  //                 remaining time, and returns the formatted message content
  // scheduler - The scheduler to use for timing events
  // timeout - The duration of the message, in seconds
  //
  // Returns an {Observable} sequence that signals expiration of the message
  static postMessageWithTimeout(channel, formatMessage, scheduler, timeout) {
    let timeoutMessage = channel.send(formatMessage(timeout));

    let timeExpired = rx.Observable.timer(0, 1000, scheduler)
      .take(timeout + 1)
      .do((x) => timeoutMessage.updateMessage(formatMessage(`${timeout - x}`)))
      .publishLast();

    return timeExpired;
  }

  // Private: Builds up a formatted countdown message containing the available
  // actions.
  //
  // player - The player who is acting
  // availableActions - An array of the actions available to this player
  // timeRemaining - Number of seconds remaining for the player to act
  //
  // Returns the formatted string
  static buildActionMessage(player, availableActions, timeRemaining) {
    let message = `${player.name}, it's your turn. Respond with:\n`;
    for (let action of availableActions) {
      message += `*(${action.charAt(0).toUpperCase()})${action.slice(1)}*\t`;
    }

    if (timeRemaining > 0) {
      message += `\nin the next ${timeRemaining} seconds.`;
    }

    return message;
  }

  // Private: Given an array of actions taken previously in the hand, returns
  // an array of available actions.
  //
  // player - The player who is acting
  // previousActions - A map of players to their most recent action
  //
  // Returns an array of strings
  static getAvailableActions(player, previousActions) {
    let actions = _.values(previousActions);
    let betActions = _.filter(actions, a => a.name === 'bet' || a.name === 'raise');
    let hasBet = betActions.length > 0;

    let availableActions = [];

    if (player.hasOption) {
      availableActions.push('check');
      availableActions.push('raise');
    } else if (hasBet) {
      availableActions.push('call');
      availableActions.push('raise');
    } else {
      availableActions.push('check');
      availableActions.push('bet');
    }

    // Prevent players from raising when they don't have enough chips.
    let raiseIndex = availableActions.indexOf('raise');
    if (raiseIndex > -1) {
      let previousWager = player.lastAction ? player.lastAction.amount : 0;
      let availableChips = player.chips + previousWager;

      if (_.max(betActions, a => a.amount).amount >= availableChips) {
        availableActions.splice(raiseIndex, 1);
      }
    }

    availableActions.push('fold');
    return availableActions;
  }

  // Private: Parse player input into a valid action.
  //
  // text - The text that the player entered
  // availableActions - An array of the actions available to this player
  //
  // Returns an object representing the action, with keys for the name and
  // bet amount, or null if the input was invalid.
  static actionFromMessage(text, availableActions) {
    if (!text) return null;

    let input = text.trim().toLowerCase().split(/\s+/);
    if (!input[0]) return null;

    let name = '';
    let amount = 0;

    switch (input[0]) {
    case 'c':
      name = availableActions[0];
      break;
    case 'call':
      name = 'call';
      break;
    case 'check':
      name = 'check';
      break;
    case 'f':
    case 'fold':
      name = 'fold';
      break;
    case 'b':
    case 'bet':
      name = 'bet';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    case 'r':
    case 'raise':
      name = 'raise';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    default:
      return null;
    }

    // NB: Unavailable actions are always invalid.
    return availableActions.indexOf(name) > -1 ?
      { name: name, amount: amount } :
      null;
  }
}

module.exports = PlayerInteraction;
<|endoftext|>


<commit_before>var data = {
	sources: [],
	table: null,
	create: function(par){
		par = JSON.parse(par);
		var form = $("#form-source");
		$.ajax({
			type: 'POST',
	        url: app.config.services,
	        data: $.extend({
	            service: 'sources',
	            crud: 'upload',
	            extension: par.file.extension,
	            filename: par.file.name,
	            separator: $("#input-separator").val(),
	            enclosure: $("#input-enclosure").val(),
	            col: $("#input-columns").val()
	        }, app.config.userData),
	        success: function(res){
	            var response = JSON.parse(res);
	            $('#modal-data').modal('hide');
	            if(response.success){
	            	showSuccessMessage('sources');
	            }
	            else{
	            	showErrorMessage('sources');
	            }
	            data.list();
	        }
	    })
	    .fail( function(e){
	        return {success: false};
	    });

	},
	list: function(){
		if(data.table){
			console.info('reload');
			data.table.ajax.reload();
		}
		else{
			console.info('load');
			data.table  = $('#source-list').DataTable({
				"paging": true,
				"lengthChange": false,
				"searching": false,
				"ordering": true,
				"autoWidth": false,
				"ajax":{
					"url": app.config.services,
					"dataSrc": "source",
					"data": $.extend({
			            service: 'sources',
			            crud: 'list'
			        }, app.config.userData),
			        "type":"POST"
				},
				"columns": [
		            { "data": "type" , render: function(data){
		            	return '';
		            }},
		            { "data": "table" },
		            { "data": "file_name" },
		            { "data": "size" },
		            { "data": "type" , render: function(data){
		            	return '.'+data;
		            }},
		            { "data": "id" },
		            { "data": "id" }
		        ]
		    });
		}
	},
	preview: function(e){
		var ext = $("input#input-file").val().split(".").pop().toLowerCase();
		if($.inArray(ext, ["csv"]) == -1) {
			alert('Upload CSV');
			return false;
		}
		if(e.target.files != undefined){
			var reader = new FileReader();
			reader.onload = function(e){
				var csvval=e.target.result.split("\n");
				var csvvalue=csvval[0].split(';');
				var inputrad="";
				for(var i=0;i<csvvalue.length;i++){
					data.previewStructure.push(csvvalue[i]);
					var inputrad=inputrad+""+csvvalue[i]+"	";
				}
				$("#csvimporthint table thead").html("
"+inputrad+"
");
				inputrad="";
				if(csvval.length>1){
					var qtd = csvval.length>4 ? 4 : csvval.length;
					for(var b=1;b<qtd;b++){
						csvvalue=csvval[b].split(';');
						for(var i=0;i<csvvalue.length;i++){
							var inputrad=inputrad+""+csvvalue[i]+"	";
						}
						inputrad = "
"+inputrad+"
";
					}
					$("#csvimporthint table tbody").html(inputrad);
				}
				else{
					$("#csvimporthint table tbody").html("No data	");
				}
				$("#csvimporthinttitle").show();
			};
			reader.readAsText(e.target.files.item(0));
			$('#csvimporthint').parent().removeClass('hidden');
		}
		return false;
	},
	previewStructure: []
};
$(function($){
	data.list();
	$(document)
	.on('change','#input-file', function(e){
		data.preview(e);
	});
	$("#form-source")
	.on('submit',(function(e) {
        e.preventDefault();
        $.ajax({
            url: "core/services/upload.php",
            type: "POST",
            data:  new FormData(this),
            contentType: false,
            cache: false,
            processData:false,
            success: function(res){
                data.create(res);
            }
       });
    }))
    .validate();
});

<commit_msg>Testing integration with Automatic tool<commit_after>var data = {
	sources: [],
	table: null,
	create: function(par){
		par = JSON.parse(par);
		var form = $("#form-source");
		$.ajax({
			type: 'POST',
	        url: app.config.services,
	        data: $.extend({
	            service: 'sources',
	            crud: 'upload',
	            extension: par.file.extension,
	            filename: par.file.name,
	            separator: $("#input-separator").val(),
	            enclosure: $("#input-enclosure").val(),
	            col: $("#input-columns").val()
	        }, app.config.userData),
	        success: function(res){
	            var response = JSON.parse(res);
	            $('#modal-data').modal('hide');
	            if(response.success){
	            	showSuccessMessage('sources');
	            }
	            else{
	            	showErrorMessage('sources');
	            }
	            data.list();
	        }
	    })
	    .fail( function(e){
	        return {success: false};
	    });

	},
	list: function(){
		if(data.table){
			console.info('reload');
			data.table.ajax.reload();
		}
		else{
			console.info('load');
			data.table  = $('#source-list').DataTable({
				"paging": true,
				"lengthChange": false,
				"searching": false,
				"ordering": true,
				"autoWidth": false,
				"ajax":{
					"url": app.config.services,
					"dataSrc": "source",
					"data": $.extend({
			            service: 'sources',
			            crud: 'list'
			        }, app.config.userData),
			        "type":"POST"
				},
				"columns": [
		            { "data": "type" , render: function(data){
		            	return '';
		            }},
		            { "data": "table" },
		            { "data": "file_name" },
		            { "data": "size" },
		            { "data": "type" , render: function(data){
		            	return '.'+data;
		            }},
		            { "data": "id" },
		            { "data": "id" }
		        ]
		    });
		}
	},
	preview: function(e){
		var ext = $("input#input-file").val().split(".").pop().toLowerCase();
		if($.inArray(ext, ["csv"]) == -1) {
			alert('Upload CSV');
			return false;
		}
		if(e.target.files != undefined){
			var reader = new FileReader();
			reader.onload = function(e){
				var csvval=e.target.result.split("\n");
				var csvvalue=csvval[0].split(';');
				var inputrad="";
				for(var i=0;i<csvvalue.length;i++){
					data.previewStructure.push(csvvalue[i]);
					var inputrad=inputrad+""+csvvalue[i]+"	";
				}
				$("#csvimporthint table thead").html("
"+inputrad+"
");
				inputrad="";
				if(csvval.length>1){
					var qtd = csvval.length>4 ? 4 : csvval.length;
					for(var b=1;b<qtd;b++){
						csvvalue=csvval[b].split(';');
						for(var i=0;i<csvvalue.length;i++){
							var inputrad=inputrad+""+csvvalue[i]+"	";
						}
						inputrad = "
"+inputrad+"
";
					}
					$("#csvimporthint table tbody").html(inputrad);
				}
				else{
					$("#csvimporthint table tbody").html("No data	");
				}
				$("#csvimporthinttitle").show();
			};
			reader.readAsText(e.target.files.item(0));
			$('#csvimporthint').parent().removeClass('hidden');
		}
		return false;
	},
	previewStructure: []
};
$(function($){
	data.list();
	$(document)
	.on('change','#input-file', function(e){
		data.preview(e);
	});
	$("#form-source")
	.on('submit',(function(e) {
        e.preventDefault();
        $.ajax({
            url: "core/services/upload.php",
            type: "POST",
            data:  new FormData(this),
            contentType: false,
            cache: false,
            processData:false,
            success: function(res){
                data.create(res);
            }
       });
    }))
    .validate();
});

<|endoftext|>


<commit_before>module.exports = function (callback, templateName, viewData, pdfOptions) {

	// https://www.npmjs.com/package/mustache
	var mustache = require ('mustache');
	// https://www.npmjs.com/package/html-pdf
	var pdf = require('html-pdf');

	// setup mustache template
	fs = require('fs');
	fs.readFile('Templates/'+templateName+'.mustache', 'utf8', function (err,template) {
		if (err)
		{
			callback (err, null);
		}
		else
		{
			// render
			var html = mustache.render( template, viewData );

			console.log(pdfOptions);

			// export as PDF
			pdf.create(html, pdfOptions).toStream(function(err, stream){
				if (err)
				{
					callback (err, null);
				}
				else
				{
					callback (null, stream);
				}
			});
		}
	});
};<commit_msg>removed log<commit_after>module.exports = function (callback, templateName, viewData, pdfOptions) {

	// https://www.npmjs.com/package/mustache
	var mustache = require ('mustache');
	// https://www.npmjs.com/package/html-pdf
	var pdf = require('html-pdf');

	// setup mustache template
	fs = require('fs');
	fs.readFile('Templates/'+templateName+'.mustache', 'utf8', function (err,template) {
		if (err)
		{
			callback (err, null);
		}
		else
		{
			// render
			var html = mustache.render( template, viewData );

			// export as PDF
			pdf.create(html, pdfOptions).toStream(function(err, stream){
				if (err)
				{
					callback (err, null);
				}
				else
				{
					callback (null, stream);
				}
			});
		}
	});
};<|endoftext|>


<commit_before>// Copyright (c) 2012 Romain Vallet <romain.vallet@gmail.com>
// Licensed under the MIT license, read license.txt

var hoverZoomPlugins = hoverZoomPlugins || [];
hoverZoomPlugins.push( {
	name: 'deviantART',
	prepareImgLinks: function(callback) {
		var res = [];
		$('a[data-super-img]').each(function() {
			var _this = $(this),
				url = this.dataset.superImg;
			if (options.showHighRes && this.dataset.superFullImg)
				url = this.dataset.superFullImg;
			_this.data().hoverZoomSrc = [url];
			res.push(_this);
		});
		callback($(res));
	}
});<commit_msg>Fixed deviantArt links with no data-super-img attribute. Fixes issue 404. Fixes issue 412.<commit_after>// Copyright (c) 2012 Romain Vallet <romain.vallet@gmail.com>
// Licensed under the MIT license, read license.txt

var hoverZoomPlugins = hoverZoomPlugins || [];
hoverZoomPlugins.push( {
	name: 'deviantART',
	prepareImgLinks: function(callback) {
		var res = [];
		$('a[data-super-img]').each(function() {
			var _this = $(this),
				url = this.dataset.superImg;
			if (options.showHighRes && this.dataset.superFullImg)
				url = this.dataset.superFullImg;
			_this.data().hoverZoomSrc = [url];
			res.push(_this);
		});
		hoverZoom.urlReplace(res,
			'a:not([data-super-img]) img[src*="deviantart.net/fs"]',
			/\/(fs\d+)\/\d+\w+\//,
			'/$1/',
			':eq(0)'
		);
		callback($(res));
	}
});<|endoftext|>


<commit_before>"use strict";

const fs        = require ('fs')
const countries = require ('./countries')
const asTable   = require ('as-table')
const util      = require ('util')
const execSync  = require ('child_process').execSync
const log       = require ('ololog').unlimited
const ansi      = require ('ansicolor').nice

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

let exchanges
let verbose = false

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

let wikiPath = 'wiki'
let gitWikiPath = 'ccxt.wiki'
let ccxtCertifiedBadge = '[![CCXT Certified](https://img.shields.io/badge/CCXT-certified-green.svg)](https://github.com/ccxt/ccxt/wiki/Certification)'
let spacing = ' '.repeat (7)
let logoHeading = spacing + 'logo' + spacing
let tableHeadings = [ logoHeading, 'id', 'name', 'ver', 'doc', 'certified', ]
let exchangesByCountryHeading = [ 'country / region', ... tableHeadings ]

if (!fs.existsSync (gitWikiPath)) {
    log.bright.cyan ('Checking out ccxt.wiki...')
    execSync ('git clone https://github.com/ccxt/ccxt.wiki.git')
}

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

function replaceInFile (filename, regex, replacement) {
    log.bright.cyan ('Exporting exchanges →', filename.yellow)
    let contents = fs.readFileSync (filename, 'utf8')
    const newContents = contents.replace (regex, replacement)
    fs.truncateSync (filename)
    fs.writeFileSync (filename, newContents)
}

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

const includedIds = fs.readFileSync ('exchanges.cfg')
                        .toString () // Buffer → String
                        .split ('\n') // String → Array
                        .map (line => line.split ('#')[0].trim ()) // trim comments
                        .filter (exchange => exchange); // filter empty lines

const isIncluded = (id) => ((includedIds.length === 0) || includedIds.includes (id))
try {

    exchanges = require ('./config').ids.filter (isIncluded)

} catch (e) {

    log.bright.cyan ('Exporting exchanges...'.yellow)

    const ids = fs.readdirSync ('./js/')
                  .filter (file => file.includes ('.js'))
                  .map (file => file.slice (0, -3))
                  .filter (isIncluded);

    const pad = function (string, n) {
        return (string + ' '.repeat (n)).slice (0, n)
    };

    [
        {
            file: './ccxt.js',
            regex:  /(?:const|var)\s+exchanges\s+\=\s+\{[^\}]+\}/,
            replacement: "const exchanges = {\n" + ids.map (id => pad ("    '" + id + "':", 30) + " require ('./js/" + id + ".js'),").join ("\n") + "    \n}",
        },
        {
            file: './python/ccxt/__init__.py',
            regex: /exchanges \= \[[^\]]+\]/,
            replacement: "exchanges = [\n" + "    '" + ids.join ("',\n    '") + "'," + "\n]",
        },
        {
            file: './python/ccxt/__init__.py',
            regex: /(?:from ccxt\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
            replacement: ids.map (id => pad ('from ccxt.' + id + ' import ' + id, 60) + '# noqa: F401').join ("\n") + "\n\nexchanges",
        },
        {
            file: './python/ccxt/async_support/__init__.py',
            regex: /(?:from ccxt\.async_support\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
            replacement: ids.map (id => pad ('from ccxt.async_support.' + id + ' import ' + id, 74) + '# noqa: F401').join ("\n") + "\n\nexchanges",
        },
        {
            file: './python/ccxt/async_support/__init__.py',
            regex: /exchanges \= \[[^\]]+\]/,
            replacement: "exchanges = [\n" + "    '" + ids.join ("',\n    '") + "'," + "\n]",
        },
        {
            file: './php/Exchange.php',
            regex: /public static \$exchanges \= array \([^\)]+\)/,
            replacement: "public static $exchanges = array (\n        '" + ids.join ("',\n        '") + "',\n    )",
        },

    ].forEach (({ file, regex, replacement }) => {
        replaceInFile (file, regex, replacement)
    })

    exchanges = {}
    ids.forEach (id => {
        exchanges[id] = { 'verbose': verbose, 'apiKey': '', 'secret': '' }
    })

    log.bright.green ('Base sources updated successfully.')
}

// ----------------------------------------------------------------------------
// strategically placed exactly here

const ccxt = require ('./ccxt.js')

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

for (let id in exchanges) {
    ccxt[id].prototype.checkRequiredDependencies = () => {}
    exchanges[id] = new (ccxt)[id] (exchanges[id])
    exchanges[id].verbose = verbose
}

// console.log (Object.values (ccxt).length)

var countryName = function (code) {
    return ((countries[code] !== undefined) ? countries[code] : code)
}

let sleep = async ms => await new Promise (resolve => setTimeout (resolve, ms))

// ---------------------------------------------------------------------------
// list all supported exchanges

let values = Object.values (exchanges).map (exchange => {
    let logo = exchange.urls['logo']
    let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
    let url = exchange.urls.referral || website
    let countries = Array.isArray (exchange.countries) ? exchange.countries.map (countryName).join (', ') : countryName (exchange.countries)
    let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
    let version = exchange.version ? exchange.version : '\*'
    let matches = version.match (/[^0-9]*([0-9].*)/)
    if (matches)
        version = matches[1];
    return [
        '[![' + exchange.id + '](' + logo + ')](' + url + ')',
        exchange.id,
        '[' + exchange.name + '](' + url + ')',
        version,
        '[API](' + doc + ')',
        exchange.certified ? ccxtCertifiedBadge : '',
        countries,
    ]
})

values.splice (0, 0, tableHeadings)

function makeTable (jsonArray) {
    let table = asTable.configure ({ 'delimiter': ' | ' }) (jsonArray)
    let lines = table.split ("\n")
    lines.splice (1,0, lines[0].replace (/[^\|]/g, '-'))
    let headerLine = lines[1].split ('|')
    headerLine[3] = ':' + headerLine[3].slice (1, headerLine[3].length - 1) + ':'
    headerLine[4] = ':' + headerLine[4].slice (1, headerLine[4].length - 1) + ':'
    lines[1] = headerLine.join ('|')
    return lines.map (line => '|' + line + '|').join ("\n")
}

let exchangesTable = makeTable (values)
let numExchanges = Object.keys (exchanges).length
let beginning = "The ccxt library currently supports the following "
let ending = " cryptocurrency exchange markets and trading APIs:\n\n"
let totalString = beginning + numExchanges + ending
let howMany = totalString + exchangesTable + "$1"
let allExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^#]+\\|([\n][\n]|[\n]$|$)", 'm')
replaceInFile ('README.md', allExchangesRegex, howMany)
replaceInFile (wikiPath + '/Manual.md', allExchangesRegex, howMany)
replaceInFile (wikiPath + '/Exchange-Markets.md', allExchangesRegex, howMany)

let certifiedFieldIndex = tableHeadings.indexOf ('certified')
let certified = values.filter ((x) => x[certifiedFieldIndex] !== '' )
let allCertifiedRegex = new RegExp ("^(## Certified Cryptocurrency Exchanges\n{3})(?:\\|.+\\|$\n)+", 'm')
let certifiedTable = makeTable (certified)
let certifiedTableReplacement = '$1' + certifiedTable + "\n"
replaceInFile ('README.md', allCertifiedRegex, certifiedTableReplacement)

let exchangesByCountries = []
Object.keys (countries).forEach (code => {
    let country = countries[code]
    let result = []
    Object.keys (exchanges).forEach (id => {
        let exchange = exchanges[id]
        let logo = exchange.urls['logo']
        let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
        let url = exchange.urls.referral || website
        let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
        let version = exchange.version ? exchange.version : '\*'
        let matches = version.match (/[^0-9]*([0-9].*)/)
        if (matches)
            version = matches[1];
        let shouldInclude = false
        if (Array.isArray (exchange.countries)) {
            if (exchange.countries.indexOf (code) > -1)
                shouldInclude = true
        } else {
            if (code == exchange.countries)
                shouldInclude = true
        }
        if (shouldInclude) {
            let entry = [
                '[![' + exchange.id + '](' + logo + ')](' + url + ')',
                country,
                exchange.id,
                '[' + exchange.name + '](' + url + ')',
                exchange.certified ? ccxtCertifiedBadge : '',
                version,
                '[API](' + doc + ')',
            ]
            result.push (entry)
        }
    })
    exchangesByCountries = exchangesByCountries.concat (result)
});

let countryKeyIndex = exchangesByCountryHeading.indexOf ('country / region')
exchangesByCountries = exchangesByCountries.sort ((a, b) => {
    let countryA = a[countryKeyIndex].toLowerCase ()
    let countryB = b[countryKeyIndex].toLowerCase ()
    if (countryA > countryB) {
        return 1
    } else if (countryA < countryB) {
        return -1;
    } else {
        if (a['id'] > b['id'])
            return 1;
        else if (a['id'] < b['id'])
            return -1;
        else
            return 0;
    }
})

exchangesByCountries.splice (0, 0, exchangesByCountryHeading)
let lines = makeTable (exchangesByCountries)
let result = "# Exchanges By Country\n\nThe ccxt library currently supports the following cryptocurrency exchange markets and trading APIs:\n\n" + lines + "\n\n"
let filename = wikiPath + '/Exchange-Markets-By-Country.md'
fs.truncateSync (filename)
fs.writeFileSync (filename, result)

log.bright ('Exporting exchange ids to'.cyan, 'exchanges.json'.yellow)
fs.writeFileSync ('exchanges.json', JSON.stringify ({ ids: Object.keys (exchanges) }, null, 4))

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

const ccxtWikiFileMapping = {
    'README.md': 'Home.md',
    'Install.md': 'Install.md',
    'Manual.md': 'Manual.md',
    'Exchange-Markets.md': 'Exchange-Markets.md',
    'Exchange-Markets-By-Country.md': 'Exchange-Markets-By-Country.md',
}

Object.keys (ccxtWikiFileMapping)
      .forEach (file =>
            fs.writeFileSync (gitWikiPath + '/' + ccxtWikiFileMapping[file], fs.readFileSync (wikiPath + '/' + file)))

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

log.bright.green ('Exchanges exported successfully.')
<commit_msg>fix exchanges-by-country<commit_after>"use strict";

const fs        = require ('fs')
const countries = require ('./countries')
const asTable   = require ('as-table')
const util      = require ('util')
const execSync  = require ('child_process').execSync
const log       = require ('ololog').unlimited
const ansi      = require ('ansicolor').nice

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

let exchanges
let verbose = false

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

let wikiPath = 'wiki'
let gitWikiPath = 'ccxt.wiki'
let ccxtCertifiedBadge = '[![CCXT Certified](https://img.shields.io/badge/CCXT-certified-green.svg)](https://github.com/ccxt/ccxt/wiki/Certification)'
let spacing = ' '.repeat (7)
let logoHeading = spacing + 'logo' + spacing
let tableHeadings = [ logoHeading, 'id', 'name', 'ver', 'doc', 'certified', ]
let exchangesByCountryHeading = [ 'country / region', ... tableHeadings ]

if (!fs.existsSync (gitWikiPath)) {
    log.bright.cyan ('Checking out ccxt.wiki...')
    execSync ('git clone https://github.com/ccxt/ccxt.wiki.git')
}

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

function replaceInFile (filename, regex, replacement) {
    log.bright.cyan ('Exporting exchanges →', filename.yellow)
    let contents = fs.readFileSync (filename, 'utf8')
    const newContents = contents.replace (regex, replacement)
    fs.truncateSync (filename)
    fs.writeFileSync (filename, newContents)
}

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

const includedIds = fs.readFileSync ('exchanges.cfg')
    .toString () // Buffer → String
    .split ('\n') // String → Array
    .map (line => line.split ('#')[0].trim ()) // trim comments
    .filter (exchange => exchange); // filter empty lines

const isIncluded = (id) => ((includedIds.length === 0) || includedIds.includes (id))
try {

    exchanges = require ('./config').ids.filter (isIncluded)

} catch (e) {

    log.bright.cyan ('Exporting exchanges...'.yellow)

    const ids = fs.readdirSync ('./js/')
        .filter (file => file.includes ('.js'))
        .map (file => file.slice (0, -3))
        .filter (isIncluded);

    const pad = function (string, n) {
        return (string + ' '.repeat (n)).slice (0, n)
    };

    [
        {
            file: './ccxt.js',
            regex:  /(?:const|var)\s+exchanges\s+\=\s+\{[^\}]+\}/,
            replacement: "const exchanges = {\n" + ids.map (id => pad ("    '" + id + "':", 30) + " require ('./js/" + id + ".js'),").join ("\n") + "    \n}",
        },
        {
            file: './python/ccxt/__init__.py',
            regex: /exchanges \= \[[^\]]+\]/,
            replacement: "exchanges = [\n" + "    '" + ids.join ("',\n    '") + "'," + "\n]",
        },
        {
            file: './python/ccxt/__init__.py',
            regex: /(?:from ccxt\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
            replacement: ids.map (id => pad ('from ccxt.' + id + ' import ' + id, 60) + '# noqa: F401').join ("\n") + "\n\nexchanges",
        },
        {
            file: './python/ccxt/async_support/__init__.py',
            regex: /(?:from ccxt\.async_support\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
            replacement: ids.map (id => pad ('from ccxt.async_support.' + id + ' import ' + id, 74) + '# noqa: F401').join ("\n") + "\n\nexchanges",
        },
        {
            file: './python/ccxt/async_support/__init__.py',
            regex: /exchanges \= \[[^\]]+\]/,
            replacement: "exchanges = [\n" + "    '" + ids.join ("',\n    '") + "'," + "\n]",
        },
        {
            file: './php/Exchange.php',
            regex: /public static \$exchanges \= array \([^\)]+\)/,
            replacement: "public static $exchanges = array (\n        '" + ids.join ("',\n        '") + "',\n    )",
        },

    ].forEach (({ file, regex, replacement }) => {
        replaceInFile (file, regex, replacement)
    })

    exchanges = {}
    ids.forEach (id => {
        exchanges[id] = { 'verbose': verbose, 'apiKey': '', 'secret': '' }
    })

    log.bright.green ('Base sources updated successfully.')
}

// ----------------------------------------------------------------------------
// strategically placed exactly here

const ccxt = require ('./ccxt.js')

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

for (let id in exchanges) {
    ccxt[id].prototype.checkRequiredDependencies = () => {}
    exchanges[id] = new (ccxt)[id] (exchanges[id])
    exchanges[id].verbose = verbose
}

// console.log (Object.values (ccxt).length)

var countryName = function (code) {
    return ((countries[code] !== undefined) ? countries[code] : code)
}

let sleep = async ms => await new Promise (resolve => setTimeout (resolve, ms))

// ---------------------------------------------------------------------------
// list all supported exchanges

let values = Object.values (exchanges).map (exchange => {
    let logo = exchange.urls['logo']
    let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
    let url = exchange.urls.referral || website
    let countries = Array.isArray (exchange.countries) ? exchange.countries.map (countryName).join (', ') : countryName (exchange.countries)
    let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
    let version = exchange.version ? exchange.version : '\*'
    let matches = version.match (/[^0-9]*([0-9].*)/)
    if (matches)
        version = matches[1];
    return [
        '[![' + exchange.id + '](' + logo + ')](' + url + ')',
        exchange.id,
        '[' + exchange.name + '](' + url + ')',
        version,
        '[API](' + doc + ')',
        exchange.certified ? ccxtCertifiedBadge : '',
        countries,
    ]
})

values.splice (0, 0, tableHeadings)

function makeTable (jsonArray) {
    let table = asTable.configure ({ 'delimiter': ' | ' }) (jsonArray)
    let lines = table.split ("\n")
    lines.splice (1,0, lines[0].replace (/[^\|]/g, '-'))
    let headerLine = lines[1].split ('|')
    headerLine[3] = ':' + headerLine[3].slice (1, headerLine[3].length - 1) + ':'
    headerLine[4] = ':' + headerLine[4].slice (1, headerLine[4].length - 1) + ':'
    lines[1] = headerLine.join ('|')
    return lines.map (line => '|' + line + '|').join ("\n")
}

let exchangesTable = makeTable (values)
let numExchanges = Object.keys (exchanges).length
let beginning = "The ccxt library currently supports the following "
let ending = " cryptocurrency exchange markets and trading APIs:\n\n"
let totalString = beginning + numExchanges + ending
let howMany = totalString + exchangesTable + "$1"
let allExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^#]+\\|([\n][\n]|[\n]$|$)", 'm')
replaceInFile ('README.md', allExchangesRegex, howMany)
replaceInFile (wikiPath + '/Manual.md', allExchangesRegex, howMany)
replaceInFile (wikiPath + '/Exchange-Markets.md', allExchangesRegex, howMany)

let certifiedFieldIndex = tableHeadings.indexOf ('certified')
let certified = values.filter ((x) => x[certifiedFieldIndex] !== '' )
let allCertifiedRegex = new RegExp ("^(## Certified Cryptocurrency Exchanges\n{3})(?:\\|.+\\|$\n)+", 'm')
let certifiedTable = makeTable (certified)
let certifiedTableReplacement = '$1' + certifiedTable + "\n"
replaceInFile ('README.md', allCertifiedRegex, certifiedTableReplacement)

let exchangesByCountries = []
Object.keys (countries).forEach (code => {
    let country = countries[code]
    let result = []
    Object.keys (exchanges).forEach (id => {
        let exchange = exchanges[id]
        let logo = exchange.urls['logo']
        let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
        let url = exchange.urls.referral || website
        let doc = Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
        let version = exchange.version ? exchange.version : '\*'
        let matches = version.match (/[^0-9]*([0-9].*)/)
        if (matches)
            version = matches[1];
        let shouldInclude = false
        if (Array.isArray (exchange.countries)) {
            if (exchange.countries.indexOf (code) > -1)
                shouldInclude = true
        } else {
            if (code == exchange.countries)
                shouldInclude = true
        }
        if (shouldInclude) {
            let entry = [
                country,
                '[![' + exchange.id + '](' + logo + ')](' + url + ')',
                exchange.id,
                '[' + exchange.name + '](' + url + ')',
                version,
                '[API](' + doc + ')',
                exchange.certified ? ccxtCertifiedBadge : '',
            ]
            result.push (entry)
        }
    })
    exchangesByCountries = exchangesByCountries.concat (result)
});

let countryKeyIndex = exchangesByCountryHeading.indexOf ('country / region')
exchangesByCountries = exchangesByCountries.sort ((a, b) => {
    let countryA = a[countryKeyIndex].toLowerCase ()
    let countryB = b[countryKeyIndex].toLowerCase ()
    if (countryA > countryB) {
        return 1
    } else if (countryA < countryB) {
        return -1;
    } else {
        if (a['id'] > b['id'])
            return 1;
        else if (a['id'] < b['id'])
            return -1;
        else
            return 0;
    }
})

exchangesByCountries.splice (0, 0, exchangesByCountryHeading)
let lines = makeTable (exchangesByCountries)
let result = "# Exchanges By Country\n\nThe ccxt library currently supports the following cryptocurrency exchange markets and trading APIs:\n\n" + lines + "\n\n"
let filename = wikiPath + '/Exchange-Markets-By-Country.md'
fs.truncateSync (filename)
fs.writeFileSync (filename, result)

log.bright ('Exporting exchange ids to'.cyan, 'exchanges.json'.yellow)
fs.writeFileSync ('exchanges.json', JSON.stringify ({ ids: Object.keys (exchanges) }, null, 4))

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

const ccxtWikiFileMapping = {
    'README.md': 'Home.md',
    'Install.md': 'Install.md',
    'Manual.md': 'Manual.md',
    'Exchange-Markets.md': 'Exchange-Markets.md',
    'Exchange-Markets-By-Country.md': 'Exchange-Markets-By-Country.md',
}

Object.keys (ccxtWikiFileMapping)
    .forEach (file =>
        fs.writeFileSync (gitWikiPath + '/' + ccxtWikiFileMapping[file], fs.readFileSync (wikiPath + '/' + file)))

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

log.bright.green ('Exchanges exported successfully.')
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @emails react-core
 */

'use strict';

var React;
var ReactTestUtils;

var mocks;
var warn;

describe('ReactTestUtils', function() {

  beforeEach(function() {
    mocks = require('mocks');

    React = require('React');
    ReactTestUtils = require('ReactTestUtils');

    warn = console.warn;
    console.warn = mocks.getMockFunction();
  });

  afterEach(function() {
    console.warn = warn;
  });

  it('should have shallow rendering', function() {
    var SomeComponent = React.createClass({
      render: function() {
        return (

        );
      }
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});

    var result = shallowRenderer.getRenderOutput();

    expect(result.type).toBe('div');
    expect(result.props.children).toEqual([
      ,

    ]);
  });

  it('should have shallow unmounting', function() {
    var componentWillUnmount = mocks.getMockFunction();

    var SomeComponent = React.createClass({
      render: function() {
        return
;
      },
      componentWillUnmount
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});
    shallowRenderer.unmount();

    expect(componentWillUnmount).toBeCalled();
  });

  it('can shallow render to null', function() {
    var SomeComponent = React.createClass({
      render: function() {
        return null;
      }
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});

    var result = shallowRenderer.getRenderOutput();

    expect(result).toBe(null);
  });

  it('lets you update shallowly rendered components', function() {
    var SomeComponent = React.createClass({
      getInitialState: function() {
        return {clicked: false};
      },

      onClick: function() {
        this.setState({clicked: true});
      },

      render: function() {
        var className = this.state.clicked ? 'was-clicked' : '';

        if (this.props.aNew === 'prop') {
          return (

              Test link

          );
        } else {
          return (

          );
        }
      }
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});
    var result = shallowRenderer.getRenderOutput();
    expect(result.type).toBe('div');
    expect(result.props.children).toEqual([
      ,

    ]);

    shallowRenderer.render(<SomeComponent aNew="prop" />, {});
    var updatedResult = shallowRenderer.getRenderOutput();
    expect(updatedResult.type).toBe('a');

    var mockEvent = {};
    updatedResult.props.onClick(mockEvent);

    var updatedResultCausedByClick = shallowRenderer.getRenderOutput();
    expect(updatedResultCausedByClick.type).toBe('a');
    expect(updatedResultCausedByClick.props.className).toBe('was-clicked');
  });

  it('Test scryRenderedDOMComponentsWithClass with TextComponent', function() {
    var renderedComponent = ReactTestUtils.renderIntoDocument(
Hello Jim
);
    var scryResults = ReactTestUtils.scryRenderedDOMComponentsWithClass(
      renderedComponent,
      'NonExistantClass'
    );
    expect(scryResults.length).toBe(0);

  });
});
<commit_msg>Add regression test for scry order<commit_after>/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @emails react-core
 */

'use strict';

var React;
var ReactTestUtils;

var mocks;
var warn;

describe('ReactTestUtils', function() {

  beforeEach(function() {
    mocks = require('mocks');

    React = require('React');
    ReactTestUtils = require('ReactTestUtils');

    warn = console.warn;
    console.warn = mocks.getMockFunction();
  });

  afterEach(function() {
    console.warn = warn;
  });

  it('should have shallow rendering', function() {
    var SomeComponent = React.createClass({
      render: function() {
        return (

        );
      }
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});

    var result = shallowRenderer.getRenderOutput();

    expect(result.type).toBe('div');
    expect(result.props.children).toEqual([
      ,

    ]);
  });

  it('should have shallow unmounting', function() {
    var componentWillUnmount = mocks.getMockFunction();

    var SomeComponent = React.createClass({
      render: function() {
        return
;
      },
      componentWillUnmount
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});
    shallowRenderer.unmount();

    expect(componentWillUnmount).toBeCalled();
  });

  it('can shallow render to null', function() {
    var SomeComponent = React.createClass({
      render: function() {
        return null;
      }
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});

    var result = shallowRenderer.getRenderOutput();

    expect(result).toBe(null);
  });

  it('lets you update shallowly rendered components', function() {
    var SomeComponent = React.createClass({
      getInitialState: function() {
        return {clicked: false};
      },

      onClick: function() {
        this.setState({clicked: true});
      },

      render: function() {
        var className = this.state.clicked ? 'was-clicked' : '';

        if (this.props.aNew === 'prop') {
          return (

              Test link

          );
        } else {
          return (

          );
        }
      }
    });

    var shallowRenderer = ReactTestUtils.createRenderer();
    shallowRenderer.render(<SomeComponent />, {});
    var result = shallowRenderer.getRenderOutput();
    expect(result.type).toBe('div');
    expect(result.props.children).toEqual([
      ,

    ]);

    shallowRenderer.render(<SomeComponent aNew="prop" />, {});
    var updatedResult = shallowRenderer.getRenderOutput();
    expect(updatedResult.type).toBe('a');

    var mockEvent = {};
    updatedResult.props.onClick(mockEvent);

    var updatedResultCausedByClick = shallowRenderer.getRenderOutput();
    expect(updatedResultCausedByClick.type).toBe('a');
    expect(updatedResultCausedByClick.props.className).toBe('was-clicked');
  });

  it('Test scryRenderedDOMComponentsWithClass with TextComponent', function() {
    var renderedComponent = ReactTestUtils.renderIntoDocument(
Hello Jim
);
    var scryResults = ReactTestUtils.scryRenderedDOMComponentsWithClass(
      renderedComponent,
      'NonExistantClass'
    );
    expect(scryResults.length).toBe(0);

  });

  it('traverses children in the correct order', function() {
    var container = document.createElement('div');

    React.render(

        {null}

purple

,
      container
    );
    var tree = React.render(

orange

purple

,
      container
    );

    var log = [];
    ReactTestUtils.findAllInRenderedTree(tree, function(child) {
      log.push(child.getDOMNode().textContent);
    });

    // Should be document order, not mount order (which would be purple, orange)
    expect(log).toEqual(['orangepurple', 'orange', 'purple']);
  });
});
<|endoftext|>


<commit_before>/**
 * Controller for the login form
 * @author     Tobias Leugger <vibes@nothing.ch>
 * @module LoginCtrl
 */
angular.module('flokModule').controller('LoginCtrl', [
    '$scope', '$location', '$translate', 'sessionService','alertService',
    function($scope, $location, $translate, sessionService,alertService) {
        'use strict';

        $scope.form = {
            email: '',
            password: ''
        };

        var handleError = function(errorMessage) {
            alertService.addAlert(errorMessage,'error');
        };

        /**
         * Submits the form as login action
         */
        $scope.submitLogin = function() {
            $scope.message = '';
            sessionService.login($scope.form.email, $scope.form.password)
                .then(function() {
                    alertService.addAlert($translate.instant('flok.message.loginSuccess'),'success'); //'Welcome back robot!')
                    $location.url('/');
                })
                .catch(handleError);
        };

        /**
         * Submits the form as registration action
         */
        $scope.submitRegistration = function() {
            $scope.message = '';
            sessionService.register($scope.form.email, $scope.form.password)
                .then(function() {
                    alertService.addAlert($translate.instant('flok.message.registrationSuccess'),'success');
                })
                .catch(handleError);
        };
    }
]);
<commit_msg>Fixing a bug that would not show the login error message correctly.<commit_after>/**
 * Controller for the login form
 * @author     Tobias Leugger <vibes@nothing.ch>
 * @module LoginCtrl
 */
angular.module('flokModule').controller('LoginCtrl', [
    '$scope', '$location', '$translate', 'sessionService','alertService',
    function($scope, $location, $translate, sessionService,alertService) {
        'use strict';

        $scope.form = {
            email: '',
            password: ''
        };

        var handleError = function(response) {
            alertService.addAlert(response.data.error, 'error');
        };

        /**
         * Submits the form as login action
         */
        $scope.submitLogin = function() {
            $scope.message = '';
            sessionService.login($scope.form.email, $scope.form.password)
                .then(function() {
                    alertService.addAlert($translate.instant('flok.message.loginSuccess'),'success'); //'Welcome back robot!')
                    $location.url('/');
                })
                .catch(handleError);
        };

        /**
         * Submits the form as registration action
         */
        $scope.submitRegistration = function() {
            $scope.message = '';
            sessionService.register($scope.form.email, $scope.form.password)
                .then(function() {
                    alertService.addAlert($translate.instant('flok.message.registrationSuccess'),'success');
                })
                .catch(handleError);
        };
    }
]);
<|endoftext|>


<commit_before>(function() {
    'use strict';
    var PriorityQueue = {};

    if (typeof define === 'function' && define.amd) {
        define(function() {
            return PriorityQueue;
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        module.exports = PriorityQueue;
    } else {
        window.PriorityQueue = PriorityQueue;
    }
})();
<commit_msg>boilerplate added<commit_after>(function() {
    'use strict';
    var PriorityQueue = function() {
    	var count = 0;

    	function add() {

    	}

    	function remove() {

    	}

    	function contains() {

    	}

    	function getRoot() {

    	}

    	function isEmpty() {
    		return count === 0;
    	}

    	function size() {
    		return count;
    	}

    	return {
    		add: add,
    		remove: remove,
    		contains: contains,
    		getRoot: getRoot,
    		isEmpty: isEmpty,
    		size: size
    	}
    }

    if (typeof define === 'function' && define.amd) {
        define(function() {
            return PriorityQueue;
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        module.exports = PriorityQueue;
    } else {
        window.PriorityQueue = PriorityQueue;
    }
})();
<|endoftext|>


<commit_before>/*
    Interface with SockJS clients

    history:
		2014-09-15:	initialize

    NOTE:
        this extension relies on the sockjs module

        to install:
            npm install sockjs
*/

var sockjs = require('sockjs');

// connection handler to notify socket connect/disconnect
var l_connHandler = undefined;

var l_convert = function (str) {
	var obj = {};
	str = str.split('; ');
	for (var i = 0; i < str.length; i++) {
    	var tmp = str[i].split('=');
    	obj[tmp[0]] = tmp[1];
	}
	return obj;
}

// start server
exports.start = function (http_server, onDone) {

	//l_connHandler = SR.Settings.FRONTIER.getConnectionHandler();

	var ss = SR.Call('socketserver.get');
	l_connHandler = ss.getConnectionHandler();

	// create sockjs server
	// NOTE: it's a local variable that will be passed to outside
	var server = sockjs.createServer();

	// on new connection event
	server.on('connection', function (sock_conn) {

		// NOTE: cookie is not exposed with SockJS
		//var cookie = SR.REST.getCookie(conn);
		// see: https://www.npmjs.org/package/sockjs under "Various issues and design considerations" / Authorisation
		// see: https://github.com/sockjs/sockjs-node/pull/29#issuecomment-2733120
		var cookie = undefined;
		var conn_obj = undefined;

		if (l_connHandler) {

			// on receive new data from client event
			sock_conn.on('data', function (message) {
				//console.log(message);
				//broadcast(JSON.parse(message));

				// for first time we assume message is cookie
				if (!cookie) {

					cookie = SR.REST.getCookie(message);
					LOG.warn('cookie received: ', 'SR.SockJS');
					LOG.warn(cookie, 'SR.SockJS');

					var host = sock_conn.remoteAddress.split(':');
					host = host[host.length-1];

					var from = {host: host,
								port: sock_conn.remotePort,
								cookie: cookie};

					// create connection object for Scalra
					conn_obj = l_connHandler.addConnection(
						function (res_obj) {

							if (!res_obj)
								return false;

							sock_conn.write(JSON.stringify(res_obj));
							return true;

						}, 'sockjs', from);

					// necessary?
					sock_conn.connID = conn_obj.connID;

					LOG.sys('recording new sockjs connection: ' + conn_obj.connID, 'SR.SockJS');
				}
				else {

					var obj = JSON.parse(message);
					var event = SR.EventManager.unpack(obj, conn_obj, conn_obj.cookie);
					SR.EventManager.checkin(event);
				}
			});

			// on connection close event
			sock_conn.on('close', function() {

            	LOG.warn('user disconnected', 'SR.SockJS');

				// remove connection object
				if (conn_obj)
					l_connHandler.removeConnection(conn_obj);
			});
		}

		// when error occurs (used at all?)
		sock_conn.on('error', function (code) {
			LOG.error('error code: ', 'SR.SockJS');
			LOG.error(code);
		});
	});

	// assocate sockJS server with HTTP server
	http_server.addListener('upgrade', function (req, res){
    	res.end();
	});

	// Integrate SockJS and listen on /echo
	server.installHandlers(http_server, {prefix: '/sockjs'});

	//LOG.warn('SockJS server started');
	UTIL.safeCall(onDone, server);
}

exports.stop = function (type) {

	// TODO: anything to shutdown?

	//LOG.warn('SockJS server stopped');

	/*
	// destroy io object
    if (io !== undefined)
        io = undefined;
	*/
}
<commit_msg>modified: retrieving cookie from header<commit_after>/*
    Interface with SockJS clients

    history:
		2014-09-15:	initialize

    NOTE:
        this extension relies on the sockjs module

        to install:
            npm install sockjs
*/

var sockjs = require('sockjs');

// connection handler to notify socket connect/disconnect
var l_connHandler = undefined;

var l_convert = function (str) {
	var obj = {};
	str = str.split('; ');
	for (var i = 0; i < str.length; i++) {
		var tmp = str[i].split('=');
		obj[tmp[0]] = tmp[1];
	}
	return obj;
};

// start server
exports.start = function (http_server, onDone) {

	//l_connHandler = SR.Settings.FRONTIER.getConnectionHandler();

	var ss = SR.Call('socketserver.get');
	l_connHandler = ss.getConnectionHandler();

	// create sockjs server
	// NOTE: it's a local variable that will be passed to outside
	var server = sockjs.createServer();

	// on new connection event
	server.on('connection', function (sock_conn) {

		// NOTE: cookie is not exposed with SockJS
		//var cookie = SR.REST.getCookie(conn);
		// see: https://www.npmjs.org/package/sockjs under "Various issues and design considerations" / Authorisation
		// see: https://github.com/sockjs/sockjs-node/pull/29#issuecomment-2733120
		var cookie = undefined;
		var conn_obj = undefined;

		if (l_connHandler) {

			// on receive new data from client event
			sock_conn.on('data', function (message) {
				//console.log(message);
				//broadcast(JSON.parse(message));

				// for first time we assume message is cookie
				if (!cookie) {
					// console.dir('no cookie, message');
					// console.dir(message);

					var cookieHeader = sock_conn._session.recv.ws._stream._readableState.pipes._driver._request.headers.cookie;
					if (cookieHeader && typeof cookieHeader === 'string') {
						cookieHeader.split(';').forEach(cookie_str => {
							var parts = cookie_str.split('=');
							// cookie[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
							cookie = parts[1];
						});
					}
					// console.dir('cookieHeader');
					// console.dir(cookieHeader);
					// console.dir('cookie');
					// console.dir(cookie);

					if (!cookie && message && message !== '') {
						cookie = SR.REST.getCookie(message);
						// console.dir('get cookie from message');
						// console.dir(cookie);
					}

					LOG.warn('cookie received: ', 'SR.SockJS');
					LOG.warn(cookie, 'SR.SockJS');

					var host = sock_conn.remoteAddress.split(':');
					host = host[host.length-1];

					var from = {
						host: host,
						port: sock_conn.remotePort,
						cookie: cookie
					};

					// create connection object for Scalra
					conn_obj = l_connHandler.addConnection(
						function (res_obj) {

							if (!res_obj)
								return false;

							sock_conn.write(JSON.stringify(res_obj));
							return true;
						}, 'sockjs', from);

					// necessary?
					sock_conn.connID = conn_obj.connID;

					LOG.sys('recording new sockjs connection: ' + conn_obj.connID, 'SR.SockJS');
				} else {
					console.info('got cookie');
					console.info(cookie);
					try {
						// console.dir(message);
						if (message && message !== '') {
							var obj = JSON.parse(message);
						}

						var event = SR.EventManager.unpack(obj, conn_obj, conn_obj.cookie);
						SR.EventManager.checkin(event);
					} catch (e) {
						// console.error(message);
						// console.error(e);
					}
				}
			});

			// on connection close event
			sock_conn.on('close', function() {

            	LOG.warn('user disconnected', 'SR.SockJS');

				// remove connection object
				if (conn_obj)
					l_connHandler.removeConnection(conn_obj);
			});
		}

		// when error occurs (used at all?)
		sock_conn.on('error', function (code) {
			LOG.error('error code: ', 'SR.SockJS');
			LOG.error(code);
		});
	});

	// assocate sockJS server with HTTP server
	http_server.addListener('upgrade', function (req, res){
    	res.end();
	});

	// Integrate SockJS and listen on /echo
	server.installHandlers(http_server, {prefix: '/sockjs'});

	//LOG.warn('SockJS server started');
	UTIL.safeCall(onDone, server);
};

						}, 'sockjs', from);

					// necessary?
					sock_conn.connID = conn_obj.connID;

					LOG.sys('recording new sockjs connection: ' + conn_obj.connID, 'SR.SockJS');
				}
				else {

					var obj = JSON.parse(message);
					var event = SR.EventManager.unpack(obj, conn_obj, conn_obj.cookie);
					SR.EventManager.checkin(event);
				}
			});

			// on connection close event
			sock_conn.on('close', function() {

            	LOG.warn('user disconnected', 'SR.SockJS');

				// remove connection object
				if (conn_obj)
					l_connHandler.removeConnection(conn_obj);
			});
		}

		// when error occurs (used at all?)
		sock_conn.on('error', function (code) {
			LOG.error('error code: ', 'SR.SockJS');
			LOG.error(code);
		});
	});

	// assocate sockJS server with HTTP server
	http_server.addListener('upgrade', function (req, res){
    	res.end();
	});

	// Integrate SockJS and listen on /echo
	server.installHandlers(http_server, {prefix: '/sockjs'});

	//LOG.warn('SockJS server started');
	UTIL.safeCall(onDone, server);
}

exports.stop = function (type) {

	// TODO: anything to shutdown?

	//LOG.warn('SockJS server stopped');

	/*
	// destroy io object
    if (io !== undefined)
        io = undefined;
	*/
}
<|endoftext|>


<commit_before>import "babel-polyfill";
import ROM from "./rom/ROM";
import BackgroundLayer from "./rom/BackgroundLayer";
import Engine from "./Engine";
let state = {
	layers: [153, 298]
};
let search = location.search.substr(1);
if (search.length) {
	state.layers = search.split("-").map(e => Number.parseInt(e));
	for (let i = 0; i < state.layers.length; ++i) {
		let layer = state.layers[i];
		if (layer > 326) {
			state.layers[i] = 326;
		}
		if (layer < 0) {
			state.layers[i] = 0;
		}
	}
}
let rom;
let engine;
let setupEngine = ({
	layers = state.layers,
	frameSkip = 1,
	aspectRatio = 0
} = {}) => {
	let [layer1, layer2] = layers;
	let [fps, alpha] = [30, 0.5];
	if (layer2 === 0) {
		alpha = 1;
	}
	let bgLayer1 = getLayer(layer1);
	let bgLayer2 = getLayer(layer2);
	engine = new Engine([bgLayer1, bgLayer2]);
	engine.animate();
}
let byteArray = null;
function updateState() {
	history.replaceState(null, null, `${location.pathname}?${state.layers.join("-")}`);
}
function getLayer(index) {
	return new BackgroundLayer(index);
	/* Caching doesn't really cut it */
	if (!ROM.layerCache[index]) {
		ROM.layerCache[index] = new BackgroundLayer(index);
	}
	return ROM.layerCache[index];
}
function updateLayer(index) {
	engine.layers[index] = getLayer(state.layers[index]);
}
function selectNext(secondLayer) {
	if (!secondLayer) {
		if (state.layers[0] < 326) {
			++state.layers[0];
			updateLayer(0);
		}
		else {
			return;
		}
	}
	else {
		if (state.layers[1] < 326) {
			++state.layers[1];
			updateLayer(1);
		}
		else {
			return;
		}
	}
	updateState();
}
function selectPrevious(secondLayer) {
	if (!secondLayer) {
		if (state.layers[0] > 1) {
			--state.layers[0];
			updateLayer(0);
		}
		else {
			return;
		}
	}
	else {
		if (state.layers[0] > 1) {
			--state.layers[1];
			updateLayer(1);
		}
		else {
			return;
		}
	}
	updateState();
}
(async () => {
	try {
		let response = await fetch("src/data/backgrounds-truncated.dat");
		let data = await response.arrayBuffer();
		let bgsData = new Uint8Array(data);
		let padding = new Uint8Array(655872);
		byteArray = new Uint8Array(padding.byteLength + bgsData.byteLength);
		byteArray.set(new Uint8Array(padding), 0);
		byteArray.set(new Uint8Array(bgsData), padding.byteLength);
		rom = new ROM(byteArray);
		setupEngine();
	}
	catch (e) {
		console.error(e);
	}
})();
document.body.addEventListener("keydown", e => {
	switch (e.code) {
		case "BracketRight":
			selectNext(e.shiftKey);
			break;
		case "Slash":
			selectPrevious(e.shiftKey);
			break;
	}
});
<commit_msg>Added feature to average alpha blending over all valid layers<commit_after>import "babel-polyfill";
import ROM from "./rom/ROM";
import BackgroundLayer from "./rom/BackgroundLayer";
import Engine from "./Engine";
let state = {
	layers: [153, 298]
};
let search = location.search.substr(1);
if (search.length) {
	state.layers = search.split("-").map(e => Number.parseInt(e));
	for (let i = 0; i < state.layers.length; ++i) {
		let layer = state.layers[i];
		if (layer > 326) {
			state.layers[i] = 326;
		}
		if (layer < 0) {
			state.layers[i] = 0;
		}
	}
}
let rom;
let engine;
let setupEngine = ({
	layers = state.layers,
	frameSkip = 1,
	aspectRatio = 0
} = {}) => {
	let [layer1, layer2] = layers;
	let bgLayer1 = getLayer(layer1);
	let bgLayer2 = getLayer(layer2);
	engine = new Engine([bgLayer1, bgLayer2]);
	engine.animate();
}
let byteArray = null;
function updateState() {
	history.replaceState(null, null, `${location.pathname}?${state.layers.join("-")}`);
}
function getLayer(index) {
	return new BackgroundLayer(index);
	/* Caching doesn't really cut it */
	if (!ROM.layerCache[index]) {
		ROM.layerCache[index] = new BackgroundLayer(index);
	}
	return ROM.layerCache[index];
}
function updateLayer(index) {
	let layer = getLayer(state.layers[index]);
	engine.layers[index] = layer;
	let layerCount = state.layers.length;
	let emptyLayers = state.layers.map((x, i) => x === 0 ? i : null).filter(x => x !== null);
	let averageAlpha = 1 / (layerCount - emptyLayers.length) || 0;
	let alphas = [];
	for (let i = 0; i < engine.layers.length; ++i) {
		let layer = engine.layers[i];
		if (layer.entry === 0) {
			alphas[i] = 0;
		}
		else {
			alphas[i] = averageAlpha;
		}
	}
	engine.alpha = alphas;
}
function selectNext(secondLayer) {
	if (!secondLayer) {
		if (state.layers[0] < 326) {
			++state.layers[0];
			updateLayer(0);
		}
		else {
			return;
		}
	}
	else {
		if (state.layers[1] < 326) {
			++state.layers[1];
			updateLayer(1);
		}
		else {
			return;
		}
	}
	updateState();
}
function selectPrevious(secondLayer) {
	if (!secondLayer) {
		if (state.layers[0] > 0) {
			--state.layers[0];
			updateLayer(0);
		}
		else {
			return;
		}
	}
	else {
		if (state.layers[1] > 0) {
			--state.layers[1];
			updateLayer(1);
		}
		else {
			return;
		}
	}
	updateState();
}
(async () => {
	try {
		let response = await fetch("src/data/backgrounds-truncated.dat");
		let data = await response.arrayBuffer();
		let bgsData = new Uint8Array(data);
		let padding = new Uint8Array(655872);
		byteArray = new Uint8Array(padding.byteLength + bgsData.byteLength);
		byteArray.set(new Uint8Array(padding), 0);
		byteArray.set(new Uint8Array(bgsData), padding.byteLength);
		rom = new ROM(byteArray);
		setupEngine();
	}
	catch (e) {
		console.error(e);
	}
})();
document.body.addEventListener("keydown", e => {
	switch (e.code) {
		case "BracketRight":
			selectNext(e.shiftKey);
			break;
		case "Slash":
			selectPrevious(e.shiftKey);
			break;
	}
});
<|endoftext|>