def run(self, stop_event: threading.Event) -> None:
start_time = time.time()
duration = random.uniform(8.0, 15.0)
while not stop_event.is_set():
elapsed = time.time() - start_time
t = min(elapsed / duration, 1.0)
progress = self._ease_out_expo(t) * self._max_progress
progress = min(int(progress), self._max_progress)
jitter = random.uniform(-1.5, 1.5) if progress < self._max_progress - 5 else 0
progress = max(2, min(int(progress + jitter), self._max_progress))
message = self._get_message_for_progress(progress)
self._updater.update(message, progress)
if progress >= self._max_progress:
break
time.sleep(self._update_interval + random.uniform(0, 0.1))