<commit_before>/**
 * renderer.js v0.2.0
 * Copyright (c) 2016. <NAME>.
 * Licensed under MIT (https://github.com/collinhaines/terminal-game/blob/master/LICENSE)
 */

'use strict';

/**
 * Constructor
 */
function Visuals () {
  this.utils    = '';
  this.renderer = '';
  this.terminal = '';
}

/**
 * Event Listeners
 *
 * Attaches a mouse over, mouse out, and click event listener to each
 * `$('.text span')` element.
 *
 * Mouse over will determine if the character is a part of a population
 * of important notice (e.g. word, surrounding characters) and add a class
 * that visually shows the nearby characters are grouped for a reason.
 *
 * Mouse out will remove the visual.
 *
 * Click will do the initial discovery that mouse over does and then will
 * determine what occurs afterwards. Resulting in either a replenish, a dud
 * removal, an attempt decrease, a loss, a win, or nothing at all.
 */
Visuals.prototype.attachEventListeners = function () {
  const self = this;

  $(document).on('keydown', function (event) {
    // First, check if it was enter, and if there's something highlighted.
    if (event.which === 13 && $('.text span.is-hover').length > 0) {
      self.processInput();

      return false;
    }

    // Otherwise, if it was not an arrow key, neglect it.
    if ([37, 38, 39, 40].indexOf(event.which) === -1) {
      return false;
    }

    // Either highlight the "origin" of the board, or process where to go.
    if ($('.text span.is-hover').length === 0) {
      self.highlightAdd($('#text-1 > div:first-child > span:first-child'));
    } else {
      const $exact = $('.text span.is-hover[data-exact=true]');
      const $row   = $exact.parent();
      const $text  =   $row.parent();

      // Detect if unable to move left.
      if (event.which === 37 && $exact.is(':first-child') && $text.is('#text-1')) {
        return false;
      }

      // Detect if unable to move up.
      if (event.which === 38 && $row.is(':first-child')) {
        return false;
      }

      // Detect if unable to move right.
      if (event.which === 39 && $exact.is(':last-child') && $text.is('#text-2')) {
        return false;
      }

      // Detect if unable to move down.
      if (event.which === 40 && $row.is(':last-child')) {
        return false;
      }

      // From here, it's assumed the arrow key can move.
      self.highlightRemove($exact);

      // Detect if need to move from `#text-1` to `#text-2`.
      if (event.which === 39 && $exact.is(':last-child') && $text.is('#text-1')) {
        self.highlightAdd($('#text-2 > div:eq(' + $row.data('row') + ') > span').first());

        return false;
      }

      // Detect if need to move from `#text-2` to `#text-1`.
      if (event.which === 37 && $exact.is(':first-child') && $text.is('#text-2')) {
        self.highlightAdd($('#text-1 > div:eq(' + $row.data('row') + ') > span').last());

        return false;
      }

      // Default moving.
      switch (event.which) {
        // The left arrow key.
        case 37:
          let $left = $exact.prev();

          // Skip over the word, rather than go through each letter.
          if ($exact.is('[data-word]') && $left.is('[data-word]')) {
            const $word = $('[data-word="' + $left.data('word') + '"]');

            $left = $word.first().prev();

            // However, if the word is on two lines, do not skip the word.
            if ($left.parent().data('row') !== $exact.parent().data('row')) {
              $left = $exact.prev();
            }

            // Also, if the word is at the beginning of `#text-2`, mimic column shift.
            if ($row.find('> span:first-child').is($word) && $text.is('#text-2')) {
              $left = $('#text-1 > div:eq(' + $row.data('row') + ') > span').last();
            }
          }

          self.highlightAdd($left);
          break;

        // The up arrow key.
        case 38:
          self.highlightAdd($row.prev().find('[data-column="' + $exact.data('column') + '"]'));
          break;

        // The right arrow key.
        case 39:
          let $right = $exact.next();

          // Skip over the word, rather than go through each letter.
          if ($exact.is('[data-word]') && $right.is('[data-word]')) {
            const $word = $('[data-word="' + $right.data('word') + '"]');

            $right = $word.last().next();

            // However, if the word is on two lines, do not skip the word.
            if ($right.parent().data('row') !== $exact.parent().data('row')) {
              $right = $exact.next();
            }

            // Also, if the word is at the end of `#text-1`, mimic column shift.
            if ($row.find('> span:last-child').is($word) && $text.is('#text-1')) {
              $right = $('#text-2 > div:eq(' + $row.data('row') + ') > span').first();
            }
          }

          self.highlightAdd($right);
          break;

        // The down arrow key.
        case 40:
          self.highlightAdd($row.next().find('[data-column="' + $exact.data('column') + '"]'));
          break;
      }
    }
  });

  $('.text span')
    .mouseover(function () {
      $('.text span.is-hover').removeClass('is-hover');

      self.highlightAdd($(this));
    })
    .mouseout(function () {
      self.highlightRemove($(this));
    })
    .click(function () {
      self.processInput();
    });
};

/**
 * Ending Determiner
 *
 * Determines the ending bracket is located based on the beginning bracket.
 *
 * @param  {String} text -- The text to search.
 * @return {Integer}
 */
Visuals.prototype.endingBracketLocation = function (text) {
  const brackets = ['>', ']', '}', ')'];

  // Run through each character within the text, cross-reference with all
  // ending brackets.
  for (let i = 0; i < text.length; i++) {
    for (let x = 0; x < brackets.length; x++) {
      if (text.charAt(i) === brackets[x]) {
        return i;
      }
    }
  }

  return -1;
};

/**
 * Determines if the highlighted element has any notable relatives nearby.
 *
 * @param  {Element} element -- The initial highlighted element.
 * @return {Element or NodeList}
 */
Visuals.prototype.getPopulation = function ($element) {
  if (this.isBeginningBracket($element) && $element.attr('data-skip') === undefined) {
    return this.locateEnding($element);
  } else if ($element.is('[data-word]')) {
    return $('span[data-word="' + $element.attr('data-word') + '"]');
  } else {
    return $element;
  }
};

/**<commit_msg>Allow for Correct Ending Block Selection<commit_after>/**
 * renderer.js v0.2.0
 * Copyright (c) 2016. <NAME>.
 * Licensed under MIT (https://github.com/collinhaines/terminal-game/blob/master/LICENSE)
 */

'use strict';

/**
 * Constructor
 */
function Visuals () {
  this.utils    = '';
  this.renderer = '';
  this.terminal = '';
}

/**
 * Event Listeners
 *
 * Attaches a mouse over, mouse out, and click event listener to each
 * `$('.text span')` element.
 *
 * Mouse over will determine if the character is a part of a population
 * of important notice (e.g. word, surrounding characters) and add a class
 * that visually shows the nearby characters are grouped for a reason.
 *
 * Mouse out will remove the visual.
 *
 * Click will do the initial discovery that mouse over does and then will
 * determine what occurs afterwards. Resulting in either a replenish, a dud
 * removal, an attempt decrease, a loss, a win, or nothing at all.
 */
Visuals.prototype.attachEventListeners = function () {
  const self = this;

  $(document).on('keydown', function (event) {
    // First, check if it was enter, and if there's something highlighted.
    if (event.which === 13 && $('.text span.is-hover').length > 0) {
      self.processInput();

      return false;
    }

    // Otherwise, if it was not an arrow key, neglect it.
    if ([37, 38, 39, 40].indexOf(event.which) === -1) {
      return false;
    }

    // Either highlight the "origin" of the board, or process where to go.
    if ($('.text span.is-hover').length === 0) {
      self.highlightAdd($('#text-1 > div:first-child > span:first-child'));
    } else {
      const $exact = $('.text span.is-hover[data-exact=true]');
      const $row   = $exact.parent();
      const $text  =   $row.parent();

      // Detect if unable to move left.
      if (event.which === 37 && $exact.is(':first-child') && $text.is('#text-1')) {
        return false;
      }

      // Detect if unable to move up.
      if (event.which === 38 && $row.is(':first-child')) {
        return false;
      }

      // Detect if unable to move right.
      if (event.which === 39 && $exact.is(':last-child') && $text.is('#text-2')) {
        return false;
      }

      // Detect if unable to move down.
      if (event.which === 40 && $row.is(':last-child')) {
        return false;
      }

      // From here, it's assumed the arrow key can move.
      self.highlightRemove($exact);

      // Detect if need to move from `#text-1` to `#text-2`.
      if (event.which === 39 && $exact.is(':last-child') && $text.is('#text-1')) {
        self.highlightAdd($('#text-2 > div:eq(' + $row.data('row') + ') > span').first());

        return false;
      }

      // Detect if need to move from `#text-2` to `#text-1`.
      if (event.which === 37 && $exact.is(':first-child') && $text.is('#text-2')) {
        self.highlightAdd($('#text-1 > div:eq(' + $row.data('row') + ') > span').last());

        return false;
      }

      // Default moving.
      switch (event.which) {
        // The left arrow key.
        case 37:
          let $left = $exact.prev();

          // Skip over the word, rather than go through each letter.
          if ($exact.is('[data-word]') && $left.is('[data-word]')) {
            const $word = $('[data-word="' + $left.data('word') + '"]');

            $left = $word.first().prev();

            // However, if the word is on two lines, do not skip the word.
            if ($left.parent().data('row') !== $exact.parent().data('row')) {
              $left = $exact.prev();
            }

            // Also, if the word is at the beginning of `#text-2`, mimic column shift.
            if ($row.find('> span:first-child').is($word) && $text.is('#text-2')) {
              $left = $('#text-1 > div:eq(' + $row.data('row') + ') > span').last();
            }
          }

          self.highlightAdd($left);
          break;

        // The up arrow key.
        case 38:
          self.highlightAdd($row.prev().find('[data-column="' + $exact.data('column') + '"]'));
          break;

        // The right arrow key.
        case 39:
          let $right = $exact.next();

          // Skip over the word, rather than go through each letter.
          if ($exact.is('[data-word]') && $right.is('[data-word]')) {
            const $word = $('[data-word="' + $right.data('word') + '"]');

            $right = $word.last().next();

            // However, if the word is on two lines, do not skip the word.
            if ($right.parent().data('row') !== $exact.parent().data('row')) {
              $right = $exact.next();
            }

            // Also, if the word is at the end of `#text-1`, mimic column shift.
            if ($row.find('> span:last-child').is($word) && $text.is('#text-1')) {
              $right = $('#text-2 > div:eq(' + $row.data('row') + ') > span').first();
            }
          }

          self.highlightAdd($right);
          break;

        // The down arrow key.
        case 40:
          self.highlightAdd($row.next().find('[data-column="' + $exact.data('column') + '"]'));
          break;
      }
    }
  });

  $('.text span')
    .mouseover(function () {
      $('.text span.is-hover').removeClass('is-hover');

      self.highlightAdd($(this));
    })
    .mouseout(function () {
      self.highlightRemove($(this));
    })
    .click(function () {
      self.processInput();
    });
};

/**
 * Ending Determiner
 *
 * Determines the ending bracket is located based on the beginning bracket.
 *
 * @param  {String} text -- The text to search.
 * @return {Integer}
 */
Visuals.prototype.endingBracketLocation = function (text) {
  let   bracket  = '';
  const brackets = ['>', ']', '}', ')'];

  switch ($('[data-exact="true"]').text()) {
    case '<':
      bracket = brackets[0];
      break;
    case '[':
      bracket = brackets[1];
      break;
    case '{':
      bracket = brackets[2];
      break;
    case '(':
      bracket = brackets[3];
      break;
  }

  const isBrace   = bracket === bracket[2];
  const isParen   = bracket === bracket[3];
  const isBracket = bracket === bracket[1];
  const isGreater = bracket === bracket[0];

  // Run through each character within the text, cross-reference with all
  // ending brackets.
  for (let i = 0; i < text.length; i++) {
    // There has to be a better way to optimize this.
    if (text.charAt(i) === bracket[0] && isGreater) {
      return i;
    } else if (text.charAt(i) === bracket[1] && isBracket) {
      return i;
    } else if (text.charAt(i) === bracket[2] && isBrace) {
      return i;
    } else if (text.charAt(i) === bracket[3] && isParen) {
      return i;
    }
  }

  return -1;
};

/**
 * Determines if the highlighted element has any notable relatives nearby.
 *
 * @param  {Element} element -- The initial highlighted element.
 * @return {Element or NodeList}
 */
Visuals.prototype.getPopulation = function ($element) {
  if (this.isBeginningBracket($element) && $element.attr('data-skip') === undefined) {
    return this.locateEnding($element);
  } else if ($element.is('[data-word]')) {
    return $('span[data-word="' + $element.attr('data-word') + '"]');
  } else {
    return $element;
  }
};

/**
{'fraction_non_alphanumeric': 0.18374067027659885, 'fraction_numerical': 0.009585833455290502, 'mean_word_length': 2.2271546635183, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 33, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '719063', 'n_tokens_mistral': 4438, 'n_tokens_neox': 4164, 'n_words': 1186}