<commit_before>var MazeInteraction = (function(MazeGenerator, MazePainter) {
  'user strict';

  var handlerMouseMove;

  var path = [];
  var joinedCells = [];

  var currentCell = null;

  // List of callbacks to call when the maze is solved
  var solutionCallbacks = [];

  function callSolutionCallbacks() {
    solutionCallbacks.forEach(function(callback) {
      callback();
    });
  }

  var mazeInteraction = {

    solution: [],

    init: function(canvas, cellSize, maze) {
      this.canvas = canvas;
      this.cellSize = cellSize;
      this.maze = maze;
      this.solution = [];
      currentCell = null;
      path = [];
      solutionCallbacks = [];
    },

    startListeningUserEvents: function() {
      this.listenMouseDownEvents();
      this.listenMouseUpEvents();
    },

    listenMouseDownEvents: function() {
      this.canvas.addEventListener('mousedown', this.handleMouseDownEvents.bind(this));
    },

    handleMouseDownEvents: function(e) {
      var x = e.clientX - this.canvas.getBoundingClientRect().left;
      var y = e.clientY - this.canvas.getBoundingClientRect().top;
      this.calculateCell(x, y);
      this.listenMouseMoveEvents();
    },

    listenMouseMoveEvents: function() {
      handlerMouseMove = this.handleMouseMoveEvents.bind(this);
      this.canvas.addEventListener('mousemove', handlerMouseMove);
    },

    handleMouseMoveEvents: function(e) {
      var x = e.clientX - this.canvas.getBoundingClientRect().left;
      var y = e.clientY - this.canvas.getBoundingClientRect().top;
      var cell = this.calculateCell(x, y);

      if (currentCell === null) {
        if (MazeGenerator.areTheSameCell(cell, MazeGenerator.entry)) {
          currentCell = cell;
          path.push(cell);
          this.solution.push({cell: cell, clear: false});
        }

        return;
      }

      if (!MazeGenerator.areTheSameCell(currentCell, cell)) {
       if (path.length > 1 && MazeGenerator.areTheSameCell(cell, path[path.length - 2])) {
         this.solution.push({cell: currentCell, clear: true});
         currentCell = cell;
         path.pop();
         return;
       }
      
       if (MazeGenerator.areCellsJoined(currentCell, cell)) {
         currentCell = cell;
         path.push(cell);
         this.solution.push({cell: cell, clear: false});
       }
       
       if (MazeGenerator.areTheSameCell(currentCell, MazeGenerator.exit)) {
         this.solve();
       }

      }
    },

    listenMouseUpEvents: function() {
      this.canvas.addEventListener('mouseup', this.handleMouseUp.bind(this));
    },

    handleMouseUp: function() {
      this.canvas.removeEventListener('mousemove', handlerMouseMove);
    },

    calculateCell: function(x, y) {
      var j = Math.floor(x / this.cellSize);
      var i = Math.floor(y / this.cellSize);
      return [i, j];
    },

    onSolved: function(callback) {
      solutionCallbacks.push(callback);
    },

    solve: function() {
      this.handleMouseUp();
      callSolutionCallbacks();
    }
  
  };

  return mazeInteraction;

}(MazeGenerator, MazePainter));
<commit_msg>Stop listening MouseMove events when mouse leaves<commit_after>var MazeInteraction = (function(MazeGenerator, MazePainter) {
  'user strict';

  var handlerMouseMove;

  var path = [];
  var joinedCells = [];

  var currentCell = null;

  var isMouseDown = false;

  // List of callbacks to call when the maze is solved
  var solutionCallbacks = [];

  function callSolutionCallbacks() {
    solutionCallbacks.forEach(function(callback) {
      callback();
    });
  }

  var mazeInteraction = {

    solution: [],

    init: function(canvas, cellSize, maze) {
      this.canvas = canvas;
      this.cellSize = cellSize;
      this.maze = maze;
      this.solution = [];
      currentCell = null;
      path = [];
      solutionCallbacks = [];
    },

    startListeningUserEvents: function() {
      this.listenMouseDownEvents();
      this.listenMouseUpEvents();
      this.listenMouseLeaveEvents();
    },

    listenMouseDownEvents: function() {
      this.canvas.addEventListener('mousedown', this.handleMouseDownEvents.bind(this));
    },

    handleMouseDownEvents: function(e) {
      isMouseDown = true;
      var x = e.clientX - this.canvas.getBoundingClientRect().left;
      var y = e.clientY - this.canvas.getBoundingClientRect().top;
      this.calculateCell(x, y);
      this.listenMouseMoveEvents();
    },

    listenMouseMoveEvents: function() {
      handlerMouseMove = this.handleMouseMoveEvents.bind(this);
      this.canvas.addEventListener('mousemove', handlerMouseMove);
    },

    handleMouseMoveEvents: function(e) {
      var x = e.clientX - this.canvas.getBoundingClientRect().left;
      var y = e.clientY - this.canvas.getBoundingClientRect().top;
      var cell = this.calculateCell(x, y);

      if (currentCell === null) {
        if (MazeGenerator.areTheSameCell(cell, MazeGenerator.entry)) {
          currentCell = cell;
          path.push(cell);
          this.solution.push({cell: cell, clear: false});
        }

        return;
      }

      if (!MazeGenerator.areTheSameCell(currentCell, cell)) {
       if (path.length > 1 && MazeGenerator.areTheSameCell(cell, path[path.length - 2])) {
         this.solution.push({cell: currentCell, clear: true});
         currentCell = cell;
         path.pop();
         return;
       }
      
       if (MazeGenerator.areCellsJoined(currentCell, cell)) {
         currentCell = cell;
         path.push(cell);
         this.solution.push({cell: cell, clear: false});
       }
       
       if (MazeGenerator.areTheSameCell(currentCell, MazeGenerator.exit)) {
         this.solve();
       }

      }
    },

    listenMouseUpEvents: function() {
      this.canvas.addEventListener('mouseup', this.handleMouseUp.bind(this));
    },

    handleMouseUp: function() {
      this.canvas.removeEventListener('mousemove', handlerMouseMove);
      isMouseDown = false;
    },

    listenMouseLeaveEvents: function() {
      this.canvas.addEventListener('mouseleave', this.handleMouseLeave.bind(this));
    },

    handleMouseLeave: function() {
      if (isMouseDown) {
        this.canvas.removeEventListener('mousemove', handlerMouseMove);
        isMouseDown = false;
      }
    },

    calculateCell: function(x, y) {
      var j = Math.floor(x / this.cellSize);
      var i = Math.floor(y / this.cellSize);
      return [i, j];
    },

    onSolved: function(callback) {
      solutionCallbacks.push(callback);
    },

    solve: function() {
      this.handleMouseUp();
      callSolutionCallbacks();
    }
  
  };

  return mazeInteraction;

}(MazeGenerator, MazePainter));

{'fraction_non_alphanumeric': 0.12650240384615385, 'fraction_numerical': 0.0006009615384615385, 'mean_word_length': 2.6597031335898844, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '5187968', 'n_tokens_mistral': 2025, 'n_tokens_neox': 1943, 'n_words': 362}