```
class DrawableArea extends EventTarget {
  // A WeakSet to keep track of initialized containers
  static initializedContainers = new WeakSet();

  /**
   * Constructs the DrawableArea.
   * @param {Object} options - Configuration options.
   * @param {HTMLElement} options.container - The DOM element where drawing occurs.
   * @param {RectRegionShapeFactory} options.factory - The pre-configured factory for creating rectangles.
   */
  constructor({ container, factory }) {
    super(); // Initialize EventTarget

    if (!container) {
      throw new TypeError('DrawableArea: "container" element is required.');
    }
    if (!(container instanceof HTMLElement)) {
      throw new TypeError('DrawableArea: "container" must be an instance of HTMLElement.');
    }
    if (!factory) {
      throw new TypeError('DrawableArea: "factory" instance is required.');
    }

    this.container = container;
    this.factory = factory;

    // Bind event handlers to maintain context
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.handleMouseUp = this.handleMouseUp.bind(this);

    // State variables
    this.isDrawing = false;
    this.startX = 0;
    this.startY = 0;
    this.currentRect = null;

    // Internal flags
    this.isInitialized = false;
    this.isStarted = false;
  }

  /**
   * Factory method to create and initialize a DrawableArea instance.
   * @param {Object} options - Configuration options.
   * @returns {DrawableArea} - The initialized DrawableArea instance.
   */
  static create(options) {
    const instance = new DrawableArea(options);
    instance.init();
    return instance;
  }

  /**
   * Initializes the DrawableArea by preparing the container.
   * Ensures that the container has the appropriate positioning context.
   * Dispatches the 'init' event upon successful initialization.
   * @returns {DrawableArea} - The initialized DrawableArea instance for chaining.
   */
  init() {
    if (this.isInitialized) {
      console.warn('DrawableArea: Already initialized.');
      return this;
    }

    // Ensure the container has a positioning context
    const position = getComputedStyle(this.container).position;
    if (!['relative', 'absolute', 'fixed', 'sticky'].includes(position)) {
      this.container.style.position = 'relative';
    }

    // Mark the container as initialized
    DrawableArea.initializedContainers.add(this.container);
    this.isInitialized = true;

    // Dispatch the 'init' event
    this.dispatchEvent(new Event('init'));

    return this; // Enable method chaining
  }

  /**
   * Starts the drawing functionality by attaching event listeners.
   * Dispatches the 'start' event upon successful start.
   * @returns {DrawableArea} - The DrawableArea instance for chaining.
   * @throws {Error} - If the DrawableArea is not initialized.
   */
  start() {
    if (!this.isInitialized) {
      throw new Error('DrawableArea: Must be initialized before starting.');
    }

    if (this.isStarted) {
      console.warn('DrawableArea: Already started.');
      return this;
    }

    // Attach mouse event listeners
    this.container.addEventListener('mousedown', this.handleMouseDown);
    window.addEventListener('mousemove', this.handleMouseMove);
    window.addEventListener('mouseup', this.handleMouseUp);

    this.isStarted = true;

    // Dispatch the 'start' event
    this.dispatchEvent(new Event('start'));

    return this; // Enable method chaining
  }

  /**
   * Stops the drawing functionality by detaching event listeners.
   * Dispatches the 'stop' event upon successful stop.
   * @returns {DrawableArea} - The DrawableArea instance for chaining.
   * @throws {Error} - If the DrawableArea is not initialized.
   */
  stop() {
    if (!this.isInitialized) {
      throw new Error('DrawableArea: Must be initialized before stopping.');
    }

    if (!this.isStarted) {
      console.warn('DrawableArea: Not started or already stopped.');
      return this;
    }

    // Detach mouse event listeners
    this.container.removeEventListener('mousedown', this.handleMouseDown);
    window.removeEventListener('mousemove', this.handleMouseMove);
    window.removeEventListener('mouseup', this.handleMouseUp);

    this.isStarted = false;

    // If currently drawing, cancel the operation
    if (this.isDrawing) {
      this.isDrawing = false;
      if (this.currentRect) {
        this.currentRect.remove();
        this.currentRect = null;
      }
    }

    // Dispatch the 'stop' event
    this.dispatchEvent(new Event('stop'));

    return this; // Enable method chaining
  }

  /**
   * Cleans up event listeners and removes the initialization flag.
   * Dispatches the 'destroy' event upon successful destruction.
   * @returns {DrawableArea} - The DrawableArea instance for chaining.
   * @throws {Error} - If the DrawableArea is not initialized.
   */
  destroy() {
    if (!this.isInitialized) {
      throw new Error('DrawableArea: Not initialized or already destroyed.');
    }

    if (this.isStarted) {
      this.stop();
    }

    // Remove the container from the initialized set
    DrawableArea.initializedContainers.delete(this.container);
    this.isInitialized = false;

    // Dispatch the 'destroy' event
    this.dispatchEvent(new Event('destroy'));

    // Additional cleanup can be performed here (e.g., removing created elements)

    return this; // Enable method chaining
  }

  /**
   * Handles the mousedown event to start drawing.
   * Dispatches 'drawn:start' and 'drawn:failure' or 'drawn:success' events as appropriate.
   * @param {MouseEvent} e
   */
  handleMouseDown(e) {
    // Only respond to left mouse button
    if (e.button !== 0) return;

    // Prevent drawing if clicking on child
    if (e.target !== this.container) return;

    if (e.composed && e.composedPath()[0] !== this.container) return;

    e.preventDefault(); // Prevent text selection and other default behaviors

    this.isDrawing = true;
    const rect = this.container.getBoundingClientRect();
    this.startX = e.clientX - rect.left;
    this.startY = e.clientY - rect.top;

    // Initialize the rectangle with minimal size
    try {
      this.currentRect = this.factory.createRect({ x: this.startX, y: this.startY, width: 0, height: 0 });
      this.dispatchEvent(
        new CustomEvent('drawn:start', {
          rectangle: this.currentRect,
        })
      );
    } catch (error) {
      console.error('DrawableArea: Failed to create rectangle.', error);
      this.isDrawing = false;
      this.dispatchEvent(
        new CustomEvent('drawn:failure', {
          reason: 'creation_failed', 
          error,
        })
      );
    }
  }

  /**
   * Handles the mousemove event to update the drawing rectangle.
   * @param {MouseEvent} e
   */
  handleMouseMove(e) {
    if (!this.isDrawing || !this.currentRect) return;

    const rect = this.container.getBoundingClientRect();
    const currentX = e.clientX - rect.left;
    const currentY = e.clientY - rect.top;

    let x = this.startX;
    let y = this.startY;
    let width = currentX - this.startX;
    let height = currentY - this.startY;

    // Adjust for negative width
    if (width < 0) {
      x = currentX;
      width = Math.abs(width);
    }

    // Adjust for negative height
    if (height < 0) {
      y = currentY;
      height = Math.abs(height);
    }

    // Update the rectangle's properties using the factory's update method
    try {
      this.currentRect.update({ x, y, width, height });
    } catch (error) {
      console.error('DrawableArea: Failed to update rectangle.', error);
      this.currentRect.remove();
      this.currentRect = null;
      this.isDrawing = false;
      this.dispatchEvent(
        new CustomEvent('drawn:failure', {
          reason: 'update_failed',
          error,
        })
      );
    }
  }

  /**
   * Handles the mouseup event to finalize the drawing.
   * Dispatches 'drawn:success' or 'drawn:failure' and a general 'drawn' event.
   * @param {MouseEvent} e
   */
  handleMouseUp(e) {
    if (!this.isDrawing) return;
    this.isDrawing = false;

    // Optional: Validate the final size of the rectangle
    let isSuccess = true;
    let failureReason = null;
    let failureError = null;
    try {
      // fix get param tho
      const {width, height} = this.currentRect.bbox();

      const MIN_SIZE = 10;

      if (width < MIN_SIZE || height < MIN_SIZE) {
        // Remove the rectangle if it's too small
        this.currentRect.remove();
        isSuccess = false;
        failureReason = 'rectangle_too_small';
      }
    } catch (error) {
      console.error('DrawableArea: Failed to finalize rectangle.', error);
      isSuccess = false;
      failureReason = 'finalization_failed';
      failureError = error;
    }

    // Emit events based on success or failure
    if (isSuccess) {
      this.dispatchEvent(
        new CustomEvent('drawn:success', {
          rectangle: this.currentRect,
        })
      );
    } else {
      this.dispatchEvent(
        new CustomEvent('drawn:failure', {
          reason: failureReason,
          error: failureError
        })
      );
    }

    this.currentRect = null;
  }
}

```
when mouse down, the code creates rect at size = 0(no dragging), which will be destroyed after mouseup if size doesnt meet min_size
this is not desirable because now if by default rect has border and vertex, merely mousedown will result into a seeing the border and vertex (not fill tho since size 0)
i want a rect to be created only after (width >= MIN_SIZE || height >= MIN_SIZE), and then if user shrinks it below that size via dragging it is fine, but mouseup will still check the final size and destroy rect if it is smaller than min_size.
show the changed parts of code