warning( sprintf( 'OpenRouter image gen %s failure (attempt %d/%d): %s', $class, $attempt, PRAUTOBLOGGER_MAX_RETRIES, $detail ), 'openrouter-image' ); } /** * Sleep between retries with exponential backoff. * * @param int $attempt 1-based attempt that just failed. * @param int $retry_after Retry-After header value (0 if absent). */ public function backoff( int $attempt, int $retry_after = 0 ): void { $delay = $retry_after > 0 ? min( $retry_after, 60 ) : PRAUTOBLOGGER_RETRY_BASE_DELAY_SECONDS * (int) pow( 2, $attempt - 1 ); if ( $delay > 0 ) { sleep( $delay ); } } /** * Greatest common divisor (for aspect ratio calculation). * * @param int $a First number. * @param int $b Second number. * @return int GCD. */ public function gcd( int $a, int $b ): int { while ( 0 !== $b ) { $t = $b; $b = $a % $b; $a = $t; } return max( $a, 1 ); } }