whenver there is only one element in the redo stack the mask doesnt get redrawn for some reason it works other wise and i debigged the code and im sure that the mask data exists at all stages of the apply state 

    const canvas = document.getElementById('canvas-mask');
    const ctx = canvas.getContext('2d');
    const uploadedImage = document.getElementById('uploaded-image');
    const originalImage = document.getElementById('original-image');
    const zoomSlider = document.getElementById('zoom-slider');
    const imageContainer = document.getElementById('image-container');
    const inpaintButton = document.getElementById('inpaint-button');
    const saveButton = document.getElementById('save-button');
    const toggleImage = document.getElementById('toggle-image');
    const container = document.getElementById('image-container');
    const afterImage = document.querySelector(".slider-after");
    const handle = document.querySelector(".slider-handle");
    let drawingMade = false;
    let zoomLevel = parseFloat(zoomSlider.value);

    let undoStack = [];
    let redoStack = [];
    let currentState = {
    maskData: null,
    imageUrl: null
    };

    window.onload = function() {

        loadStacksFromLocalStorage(); // Load undo/redo stacks
        canvas.width = uploadedImage.width;    // Set up the canvas size to match the image size
        canvas.height = uploadedImage.height;
        updateCursor();
        updateZoom(zoomLevel);
        //saveState()

        // Debugging purposes
        console.debug(undoStack);
        console.debug(redoStack);
        console.debug(currentState);

        // Hide the slider handle initially if the original image is hidden
        if (toggleImage.checked) {
            uploadedImage.style.display = 'block';
            canvas.style.display = 'none';
            originalImage.style.display = 'block';
            handle.style.display = 'block';
        }
    };

    // Brush size interaction
    let brushSize = 10;
    document.getElementById('brush-size').addEventListener('input', function(event) {
        brushSize = event.target.value;
        updateCursor();
    });

    //todo: fix cursor
    function updateCursor() {
        const cursorCanvas = document.createElement('canvas');
        cursorCanvas.width = cursorCanvas.height = brushSize * 2;
        const cursorCtx = cursorCanvas.getContext('2d');

        cursorCtx.beginPath();
        cursorCtx.arc(brushSize, brushSize, brushSize, 0, 2 * Math.PI);
        cursorCtx.fillStyle = 'white';
        cursorCtx.fill();
        cursorCtx.strokeStyle = 'black';
        cursorCtx.lineWidth = 2;
        cursorCtx.stroke();

        const cursorDataUrl = cursorCanvas.toDataURL('image/png');
        //uploadedImage.style.cursor = `url('${cursorDataUrl}'), auto`;
    }

    // Drawing on canvas
    let drawing = false;
    canvas.addEventListener('mousedown', function() {
        drawing = true;
        drawingMade = true;
        updateInpaintButton();
        updateCurrentState();
        saveState();

    });

    canvas.addEventListener('mouseup', function() {
        drawing = false;
        ctx.beginPath();
    });

    canvas.addEventListener('mousemove', function(e) {
        if (drawing) {
            ctx.lineWidth = brushSize;
            ctx.lineCap = 'round';
            ctx.strokeStyle = 'white';

            ctx.lineTo(e.offsetX, e.offsetY);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(e.offsetX, e.offsetY);
        }
    });

    function updateInpaintButton() {
        inpaintButton.disabled = !drawingMade;
    }

    // Zoom functionality with slider
    zoomSlider.addEventListener('input', function() {
        zoomLevel = parseFloat(zoomSlider.value);
        updateZoom(zoomLevel);
    });

    function updateZoom(level) {
        //uploadedImage.style.transform = `scale(${level})`;
        //canvas.style.transform = `scale(${level})`;
        //originalImage.style.transform = `scale(${level})`;
        //handle.style.transform = `scale(${level})`;
        imageContainer.style.transform = `scale(${level})`;

    }

    // Zoom functionality with mouse scroll
    imageContainer.addEventListener('wheel', function(event) {
        event.preventDefault();
        const delta = Math.sign(event.deltaY);
        const rect = imageContainer.getBoundingClientRect();
        const mouseX = event.clientX - rect.left;
        const mouseY = event.clientY - rect.top;

        const oldZoomLevel = zoomLevel;
        zoomLevel = Math.min(Math.max(0.1, zoomLevel - delta * 0.1), 5); // Adjust zoom limits as needed
        zoomSlider.value = zoomLevel;
        updateZoom(zoomLevel);

        const scaleRatio = zoomLevel / oldZoomLevel;

        const offsetX = mouseX * scaleRatio - mouseX;
        const offsetY = mouseY * scaleRatio - mouseY;

        //originalImage.style.transformOrigin = `${mouseX}px ${mouseY}px`;
        //uploadedImage.style.transformOrigin = `${mouseX}px ${mouseY}px`;
        //canvas.style.transformOrigin = `${mouseX}px ${mouseY}px`;
        //handle.style.transformOrigin = `${mouseX}px ${mouseY}px`;
        imageContainer.style.transformOrigin = `${mouseX}px ${mouseY}px`;
    });

    // Toggle image display
    toggleImage.addEventListener('change', function() {
        if (this.checked) {
            uploadedImage.style.display = 'block';
            canvas.style.display = 'none';
            originalImage.style.display = 'block';
            handle.style.display = 'block';


        } else {
            uploadedImage.style.display = 'block';
            canvas.style.display = 'block';
            originalImage.style.display = 'none';
            handle.style.display = 'none';
        }
    });

    // Inpaint button interaction - send mask to server
    inpaintButton.addEventListener('click', function() {
        if (!drawingMade) return;

        saveState();

        const maskData = canvas.toDataURL(); // Capture the mask as base64
        const form = document.createElement('form');
        form.method = 'POST';
        form.action = '{% url "inpaint_view" %}';

        const csrfInput = document.createElement('input');
        csrfInput.type = 'hidden';
        csrfInput.name = 'csrfmiddlewaretoken';
        csrfInput.value = '{{ csrf_token }}';

        const maskInput = document.createElement('input');
        maskInput.type = 'hidden';
        maskInput.name = 'mask';
        maskInput.value = maskData;

        form.appendChild(csrfInput);
        form.appendChild(maskInput);

        // Show overlay while processing
        document.getElementById('overlay').style.display = 'flex';

        // Submit the form
        document.body.appendChild(form);
        form.submit();
    });

    // Save button functionality
    saveButton.addEventListener('click', function() {
        document.getElementById('save-modal').style.display = 'block';
        document.getElementById('overlay').style.display = 'none';
    });

    // Cancel save button functionality
    document.getElementById('cancel-save').addEventListener('click', function() {
        document.getElementById('save-modal').style.display = 'none';
    });

    document.addEventListener("DOMContentLoaded", function () {
    // Set initial handle position and clipPath
    const initialPercentage = 50;
    handle.style.left = `${initialPercentage}%`;
    originalImage.style.clipPath = `inset(0 0 0 ${initialPercentage}%)`;

    let dragging = false;
    let lastX = 0;

    // Add mouse event listeners
    handle.addEventListener("mousedown", (e) => {
      dragging = true;
      lastX = e.clientX;
      e.preventDefault();
    });

    document.addEventListener("mouseup", () => {
      dragging = false;
    });

    document.addEventListener("mouseleave", () => {
      dragging = false;
    });

    document.addEventListener("mousemove", (e) => {
      if (!dragging) return;

      const rect = container.getBoundingClientRect();
      const x = e.clientX - rect.left;
      let widthPercentage = (x / rect.width) * 100;

      // Add constraint to keep the handle within 1% of either edge
      widthPercentage = Math.max(0, Math.min(widthPercentage, 100));

      // Update handle position using requestAnimationFrame
      window.requestAnimationFrame(() => {
        handle.style.left = `${widthPercentage}%`;
        originalImage.style.clipPath = `inset(0 0 0 ${widthPercentage}%)`;
      });

      lastX = x;
    });

    // Add touch event listeners
    handle.addEventListener("touchstart", (e) => {
      dragging = true;
      lastX = e.touches[0].clientX;
      e.preventDefault();
    });

    document.addEventListener("touchend", () => {
      dragging = false;
    });

    container.addEventListener("touchcancel", () => {
      dragging = false;
    });

    container.addEventListener("touchmove", (e) => {
      if (!dragging) return;

      const rect = container.getBoundingClientRect();
      const x = e.touches[0].clientX - rect.left;
      let widthPercentage = (x / rect.width) * 100;

      // Add constraint to keep the handle within 1% of either edge
      widthPercentage = Math.max(0, Math.min(widthPercentage, 100));

      // Update handle position using requestAnimationFrame
      window.requestAnimationFrame(() => {
        handle.style.left = `${widthPercentage}%`;
        originalImage.style.clipPath = `inset(0 0 0 ${widthPercentage}%)`;
        });

      lastX = x;
    });
});

    // Function to save the current state
    function saveState() {
    // Only save the relative path of the image URL
    const relativeImageUrl = uploadedImage.src.replace(window.location.origin, '');
    currentState = {
        maskData: canvas.toDataURL(),
        imageUrl: relativeImageUrl // Save relative path
    };

    undoStack.push(JSON.parse(JSON.stringify(currentState)));
    redoStack = []; // Clear redo stack when a new action is performed

    // Save undoStack and redoStack to localStorage nb
    localStorage.setItem('undoStack', JSON.stringify(undoStack));
    localStorage.setItem('redoStack', JSON.stringify(redoStack));

    updateUndoRedoButtons();
    }

    function loadStacksFromLocalStorage() {
    const savedUndoStack = localStorage.getItem('undoStack');
    const savedRedoStack = localStorage.getItem('redoStack');

    if (savedUndoStack) {
        undoStack = JSON.parse(savedUndoStack);
    }

    if (savedRedoStack) {
        redoStack = JSON.parse(savedRedoStack);
    }
    updateUndoRedoButtons();

    }

    // Function to update the current state
    function updateCurrentState() {
        currentState = {
            maskData: canvas.toDataURL(),
            imageUrl: uploadedImage.src.replace(window.location.origin, '')
        };
    }
    function undo() {
        if (undoStack.length > 0) {
            redoStack.push(JSON.parse(JSON.stringify(currentState))); // Save current state to redoStack
            currentState = undoStack.pop(); // Pop last state from undoStack
            applyState(currentState); // Apply popped state
        }

        updateUndoRedoButtons();
    }

    function redo() {
        if (redoStack.length > 0) {
            undoStack.push(JSON.parse(JSON.stringify(currentState))); // Save current state to undoStack
            currentState = redoStack.pop(); // Pop last state from redoStack

            applyState(currentState); // Apply popped state
        }

        updateUndoRedoButtons();
    }


    // Function to apply a state
    function applyState(state) {
    // Apply the saved mask data
    if (state.maskData) {
        const img = new Image();
        img.onload = function() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.drawImage(img, 0, 0);
        };
        img.src = state.maskData;
        console.debug(state.maskData);
        console.debug(img.src);
    } else {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    // Apply the image data, adjusting to use the relative path
    uploadedImage.src = window.location.origin + state.imageUrl;
}

    // Function to update undo/redo button states
    function updateUndoRedoButtons() {
        document.getElementById('undo-button').disabled = undoStack.length === 0;
        document.getElementById('redo-button').disabled = redoStack.length === 0;
        if(undoStack.length === 0){
        document.getElementById('undo-button').style.display = 'none';}
        else{
        document.getElementById('undo-button').style.display = 'inline-block';
        }
        if(redoStack.length === 0){
        document.getElementById('redo-button').style.display = 'none';}
        else{
        document.getElementById('redo-button').style.display = 'inline-block';
        }
    }


    // Add event listeners for undo and redo buttons
    document.getElementById('undo-button').addEventListener('click', undo);
    document.getElementById('redo-button').addEventListener('click', redo);

    window.onbeforeunload = function() {
    // Clear undo and redo stacks from localStorage
    localStorage.removeItem('undoStack');
    localStorage.removeItem('redoStack');
    };