<commit_before>var RemovalAction = createActionType("RemovalAction", Action, {
  isRemoval: function() { return true; },
  validateData: function() {
    this.ensureFields(["actionId", "uid"]);
  }
});


// An action that is managed by the drawing layer.  Requires bounds and draw methods.
var DrawingAction = createActionType("DrawingAction", Action, {
  isPersistent: function() { return true; },
  apply: function(board) {
    board.drawingLayer.addAction(this);
  },

  // Returns the bounding box of the drawing action as an array of arrays as: [[LEFT, TOP], [RIGHT, BOTTOM]]
  bounds: function() {
    if (this.boundData == null) {
      this.boundData = this.calculateBounds();
    }
    return this.boundData;
  },

  calculateBounds: function() {
    return [[0,0], [1,1]];
  },

  // Given a drawing object, applies the drawing action to it
  draw: function(drawing) { }
});


var LineCollectionAction = createActionType("LineCollectionAction", DrawingAction, {
  calculateBounds: function() {
    var l, t, r, b;
    var margin = this.properties.width / 2;
    var points = _.reduce(this.properties.lines, function(memo, line) { memo.push(line.start); memo.push(line.end); return memo; }, []);
    _.each(points, function(p) {
      if (l == null || p[0] < l) l = p[0];
      if (t == null || p[1] < t) t = p[1];
      if (r == null || p[0] > r) r = p[0];
      if (b == null || p[1] > b) b = p[1];
    });
    return [[l - margin, t - margin], [r + margin, b + margin]];
  }
});


var TemplateAction = createActionType("TemplateAction", Action, {
  isPersistent: function() { return true; },
  isTemplate: true,
  calculateCells: function() { return []; },
  drawExtras: function(board) { },
  internalTranslateData: function(action, dx, dy, cellSize){},
  cloneAndTranslate: function(dx, dy, cellSize) {
    var clone = this.clone();
    this.internalTranslateData(clone, dx, dy, cellSize);
    return clone;
  },
  apply: function(board) {
    board.template_actions.push(this);
    this.ensureCells(board);
    board.drawing.drawTemplate(this.cells, this.border, this.properties.color);
    this.drawExtras(board);
  },
  validateData: function() {
    throw "This shouldn't happen; templateAction isn't a real action";
  },
  ensureCells: function(board) {
    if (!this.cells) {
      this.cells = this.calculateCells(board);
      this.border = Geometry.getBorder(this.cells, board.drawing.cellSize);
    }
  },
  containsCell: function(board, cell) {
    this.ensureCells(board);
    return _.find(this.cells, function(c) { return c[0] == cell[0] && c[1] == cell[1]; });
  },
  getCells: function(board) {
    this.ensureCells(board);
    return this.cells;
  },
  getBorder: function(board) {
    this.ensureCells(board);
    return this.border;
  }
});


_.extend(actionTypes, {
    labelAction: createActionType("LabelAction", DrawingAction, {
    draw: function(drawing) {
      drawing.drawLabel(this.properties.point, this.properties.text, this.properties.color, "rgba(0, 0, 0, 0.5)", "rgba(255, 255, 255, 0.25");
    },
    calculateBounds: function() {
      return this.properties.bound;
    },
    validateData: function() {
      this.ensureFields(["color", "text", "point", "bound", "uid"]);
    }
  }),

  // A pen action consists of a color, a width, and a collection of lines that are to be drawn on the drawing layer
  penAction: createActionType("PenAction", LineCollectionAction, {
    draw: function(drawing) {
      drawing.drawLines(this.properties.color, this.properties.width, this.properties.lines);
    },

    validateData: function() {
      this.ensureFields(["color", "width", "lines", "uid"]);
    }
  }),

  addFogPenAction: createActionType("AddFogPenAction", LineCollectionAction, {
    apply: function(board) {
      board.drawingLayer.addFogAction(this);
    },
    draw: function(drawing) {
      drawing.drawLines('rgba(1, 1, 1, 1)', this.properties.width, this.properties.lines);
    },
    validateData: function() {
      this.ensureFields(["width", "lines", "uid"]);
    }
  }),

  // An remove fog action consists of a width, and a collection of lines that are to be drawn on the fog layer
  removeFogPenAction: createActionType("RemoveFogPenAction", LineCollectionAction, {
    apply: function(board) {
      board.drawingLayer.addFogAction(this);
    },
    draw: function(drawing) {
      drawing.eraseLines(this.properties.width, this.properties.lines);
    },
    validateData: function() {
      this.ensureFields(["width", "lines", "uid"]);
    }
  }),

  // Draws a square.  Requires topLeft, bottomRight, color, and width
  squarePenAction: createActionType("SquarePenAction", DrawingAction, {
    draw: function(drawing) {
      drawing.drawSquare(this.properties.topLeft, this.properties.bottomRight, this.properties.color, this.properties.width);
    },

    calculateBounds: function() {
      var margin = parseInt(this.properties.width / 2);
      return [[this.properties.topLeft[0] - margin, this.properties.topLeft[1] - margin], [this.properties.bottomRight[0] + margin, this.properties.bottomRight[1] + margin]];
    },

    validateData: function() {
      this.ensureFields(["color", "width", "topLeft", "bottomRight", "uid"]);
    }
  }),

  // Draws a circle.  Requires center, radius, color, and width
  circlePenAction: createActionType("CirclePenAction", DrawingAction, {
    draw: function(drawing) {
      drawing.drawCircle(this.properties.center[0], this.properties.center[1], this.properties.radius, this.properties.width, this.properties.color);
    },

    calculateBounds: function() {
      var center = this.properties.center;
      var radius = this.properties.radius;
      return [[center[0] - radius, center[1] - radius], [center[0] + radius, center[1] + radius]];
    },

    validateData: function() {
      this.ensureFields(["color", "width", "center", "radius", "uid"]);
    }
  }),

  // Draws a straight line.  Requires start, end, color, and width
  linePenAction: createActionType("LinePenAction", DrawingAction, {
    draw: function(drawing) {
      var lines = [{start: this.properties.start, end: this.properties.end}];
      drawing.drawLines(this.properties.color, this.properties.width, lines);
    },

    calculateBounds: function() {
      var start = this.properties.start;
      var end = this.properties.end;
      var t = Math.min(start[1], end[1]);
      var l = Math.min(start[0], end[0]);
      var b = Math.max(start[1], end[1]);
      var r = Math.max(start[0], end[0]);
      return [[l, t], [r, b]];
    },

    validateData: function() {
      this.ensureFields(["color", "width", "start", "end", "uid"]);
    }
  }),

  // An erase action consists of a width and a collection of lines
  eraseAction: createActionType("EraseAction", LineCollectionAction, {
    draw: function(drawing) {
      drawing.eraseLines(this.properties.width, this.properties.lines);
    },

    validateData: function() {
      this.ensureFields(["width", "lines", "uid"]);
    }
  }),

  // References a drawing action to remove
  removeDrawingAction: createActionType("RemoveDrawingAction", RemovalAction, {
    apply: function(board) {
      board.drawingLayer.removeAction(this.properties.actionId);<commit_msg>Fixed more pen bounding bugs<commit_after>var RemovalAction = createActionType("RemovalAction", Action, {
  isRemoval: function() { return true; },
  validateData: function() {
    this.ensureFields(["actionId", "uid"]);
  }
});


// An action that is managed by the drawing layer.  Requires bounds and draw methods.
var DrawingAction = createActionType("DrawingAction", Action, {
  isPersistent: function() { return true; },
  apply: function(board) {
    board.drawingLayer.addAction(this);
  },

  // Returns the bounding box of the drawing action as an array of arrays as: [[LEFT, TOP], [RIGHT, BOTTOM]]
  bounds: function() {
    if (this.boundData == null) {
      this.boundData = this.calculateBounds();
    }
    return this.boundData;
  },

  calculateBounds: function() {
    return [[0,0], [1,1]];
  },

  // Given a drawing object, applies the drawing action to it
  draw: function(drawing) { }
});


var LineCollectionAction = createActionType("LineCollectionAction", DrawingAction, {
  calculateBounds: function() {
    var l, t, r, b;
    var margin = this.properties.width / 2;
    var points = _.reduce(this.properties.lines, function(memo, line) { memo.push(line.start); memo.push(line.end); return memo; }, []);
    _.each(points, function(p) {
      if (l == null || p[0] < l) l = p[0];
      if (t == null || p[1] < t) t = p[1];
      if (r == null || p[0] > r) r = p[0];
      if (b == null || p[1] > b) b = p[1];
    });
    return [[l - margin, t - margin], [r + margin, b + margin]];
  }
});


var TemplateAction = createActionType("TemplateAction", Action, {
  isPersistent: function() { return true; },
  isTemplate: true,
  calculateCells: function() { return []; },
  drawExtras: function(board) { },
  internalTranslateData: function(action, dx, dy, cellSize){},
  cloneAndTranslate: function(dx, dy, cellSize) {
    var clone = this.clone();
    this.internalTranslateData(clone, dx, dy, cellSize);
    return clone;
  },
  apply: function(board) {
    board.template_actions.push(this);
    this.ensureCells(board);
    board.drawing.drawTemplate(this.cells, this.border, this.properties.color);
    this.drawExtras(board);
  },
  validateData: function() {
    throw "This shouldn't happen; templateAction isn't a real action";
  },
  ensureCells: function(board) {
    if (!this.cells) {
      this.cells = this.calculateCells(board);
      this.border = Geometry.getBorder(this.cells, board.drawing.cellSize);
    }
  },
  containsCell: function(board, cell) {
    this.ensureCells(board);
    return _.find(this.cells, function(c) { return c[0] == cell[0] && c[1] == cell[1]; });
  },
  getCells: function(board) {
    this.ensureCells(board);
    return this.cells;
  },
  getBorder: function(board) {
    this.ensureCells(board);
    return this.border;
  }
});


_.extend(actionTypes, {
    labelAction: createActionType("LabelAction", DrawingAction, {
    draw: function(drawing) {
      drawing.drawLabel(this.properties.point, this.properties.text, this.properties.color, "rgba(0, 0, 0, 0.5)", "rgba(255, 255, 255, 0.25");
    },
    calculateBounds: function() {
      return this.properties.bound;
    },
    validateData: function() {
      this.ensureFields(["color", "text", "point", "bound", "uid"]);
    }
  }),

  // A pen action consists of a color, a width, and a collection of lines that are to be drawn on the drawing layer
  penAction: createActionType("PenAction", LineCollectionAction, {
    draw: function(drawing) {
      drawing.drawLines(this.properties.color, this.properties.width, this.properties.lines);
    },

    validateData: function() {
      this.ensureFields(["color", "width", "lines", "uid"]);
    }
  }),

  addFogPenAction: createActionType("AddFogPenAction", LineCollectionAction, {
    apply: function(board) {
      board.drawingLayer.addFogAction(this);
    },
    draw: function(drawing) {
      drawing.drawLines('rgba(1, 1, 1, 1)', this.properties.width, this.properties.lines);
    },
    validateData: function() {
      this.ensureFields(["width", "lines", "uid"]);
    }
  }),

  // An remove fog action consists of a width, and a collection of lines that are to be drawn on the fog layer
  removeFogPenAction: createActionType("RemoveFogPenAction", LineCollectionAction, {
    apply: function(board) {
      board.drawingLayer.addFogAction(this);
    },
    draw: function(drawing) {
      drawing.eraseLines(this.properties.width, this.properties.lines);
    },
    validateData: function() {
      this.ensureFields(["width", "lines", "uid"]);
    }
  }),

  // Draws a square.  Requires topLeft, bottomRight, color, and width
  squarePenAction: createActionType("SquarePenAction", DrawingAction, {
    draw: function(drawing) {
      drawing.drawSquare(this.properties.topLeft, this.properties.bottomRight, this.properties.color, this.properties.width);
    },

    calculateBounds: function() {
      var margin = parseInt(this.properties.width / 2);
      return [[this.properties.topLeft[0] - margin, this.properties.topLeft[1] - margin], [this.properties.bottomRight[0] + margin, this.properties.bottomRight[1] + margin]];
    },

    validateData: function() {
      this.ensureFields(["color", "width", "topLeft", "bottomRight", "uid"]);
    }
  }),

  // Draws a circle.  Requires center, radius, color, and width
  circlePenAction: createActionType("CirclePenAction", DrawingAction, {
    draw: function(drawing) {
      drawing.drawCircle(this.properties.center[0], this.properties.center[1], this.properties.radius, this.properties.width, this.properties.color);
    },

    calculateBounds: function() {
      var center = this.properties.center;
      var radius = this.properties.radius + parseInt(this.properties.width / 2);
      return [[center[0] - radius, center[1] - radius], [center[0] + radius, center[1] + radius]];
    },

    validateData: function() {
      this.ensureFields(["color", "width", "center", "radius", "uid"]);
    }
  }),

  // Draws a straight line.  Requires start, end, color, and width
  linePenAction: createActionType("LinePenAction", DrawingAction, {
    draw: function(drawing) {
      var lines = [{start: this.properties.start, end: this.properties.end}];
      drawing.drawLines(this.properties.color, this.properties.width, lines);
    },

    calculateBounds: function() {
      var start = this.properties.start;
      var end = this.properties.end;
      var margin = parseInt(this.properties.width / 2);
      var t = Math.min(start[1], end[1]);
      var l = Math.min(start[0], end[0]);
      var b = Math.max(start[1], end[1]);
      var r = Math.max(start[0], end[0]);
      return [[l - margin, t - margin], [r + margin, b + margin]];
    },

    validateData: function() {
      this.ensureFields(["color", "width", "start", "end", "uid"]);
    }
  }),

  // An erase action consists of a width and a collection of lines
  eraseAction: createActionType("EraseAction", LineCollectionAction, {
    draw: function(drawing) {
      drawing.eraseLines(this.properties.width, this.properties.lines);
    },

    validateData: function() {
      this.ensureFields(["width", "lines", "uid"]);
    }
  }),

  // References a drawing action to remove
  removeDrawingAction: createActionType("RemoveDrawingAction", RemovalAction, {
    apply: function(board) {
      board.drawingLayer.removeAction(this.properties.actionId);
{'fraction_non_alphanumeric': 0.15360888340530537, 'fraction_numerical': 0.007951196106655699, 'mean_word_length': 3.598172076898834, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '3303375', 'n_tokens_mistral': 4627, 'n_tokens_neox': 4527, 'n_words': 1067}