<commit_before>package lila.round

import akka.stream.OverflowStrategy
import akka.stream.scaladsl._
import chess.Color
import chess.format.Forsyth
import chess.{ Centis, Replay }
import play.api.libs.json._
import scala.concurrent.ExecutionContext

import lila.common.Bus
import lila.game.actorApi.FinishGame
import lila.game.actorApi.MoveGameEvent
import lila.game.{ Game, GameRepo }

final class ApiMoveStream(gameRepo: GameRepo, gameJsonView: lila.game.JsonView)(implicit
    ec: ExecutionContext
) {

  def apply(game: Game, delayMoves: Boolean): Source[JsObject, _] =
    Source futureSource {
      val delayMovesBy         = delayMoves ?? 3
      val delayKeepsFirstMoves = delayMoves ?? 5
      gameRepo.initialFen(game) map { initialFen =>
        val buffer = scala.collection.mutable.Queue.empty[JsObject]
        var moves  = 0
        Source(List(gameJsonView(game, initialFen))) concat
          Source
            .queue[JsObject](16, akka.stream.OverflowStrategy.dropHead)
            .statefulMapConcat { () => js =>
              moves += 1
              if (game.finished || moves <= delayKeepsFirstMoves) List(js)
              else {
                buffer.enqueue(js)
                (buffer.size > delayMovesBy) ?? List(buffer.dequeue())
              }
            }
            .mapMaterializedValue { queue =>
              val clocks = ~(for {
                clk   <- game.clock
                times <- game.bothClockStates
              } yield Vector(clk.config.initTime, clk.config.initTime) ++ times)
              val clockOffset = game.startColor.fold(0, 1)
              Replay.situations(game.pgnMoves, initialFen, game.variant) foreach {<commit_msg>don't delay moves for correspondence games<commit_after>package lila.round

import akka.stream.OverflowStrategy
import akka.stream.scaladsl._
import chess.Color
import chess.format.Forsyth
import chess.{ Centis, Replay }
import play.api.libs.json._
import scala.concurrent.ExecutionContext

import lila.common.Bus
import lila.game.actorApi.FinishGame
import lila.game.actorApi.MoveGameEvent
import lila.game.{ Game, GameRepo }

final class ApiMoveStream(gameRepo: GameRepo, gameJsonView: lila.game.JsonView)(implicit
    ec: ExecutionContext
) {

  def apply(game: Game, delayMoves: Boolean): Source[JsObject, _] =
    Source futureSource {
      val hasMoveDelay         = delayMoves && game.hasClock
      val delayMovesBy         = hasMoveDelay ?? 3
      val delayKeepsFirstMoves = hasMoveDelay ?? 5
      gameRepo.initialFen(game) map { initialFen =>
        val buffer = scala.collection.mutable.Queue.empty[JsObject]
        var moves  = 0
        Source(List(gameJsonView(game, initialFen))) concat
          Source
            .queue[JsObject](16, akka.stream.OverflowStrategy.dropHead)
            .statefulMapConcat { () => js =>
              moves += 1
              if (game.finished || moves <= delayKeepsFirstMoves) List(js)
              else {
                buffer.enqueue(js)
                (buffer.size > delayMovesBy) ?? List(buffer.dequeue())
              }
            }
            .mapMaterializedValue { queue =>
              val clocks = ~(for {
                clk   <- game.clock
                times <- game.bothClockStates
              } yield Vector(clk.config.initTime, clk.config.initTime) ++ times)
              val clockOffset = game.startColor.fold(0, 1)
              Replay.situations(game.pgnMoves, initialFen, game.variant) foreach {
{'fraction_non_alphanumeric': 0.09827089337175793, 'fraction_numerical': 0.004610951008645533, 'mean_word_length': 2.4129793510324484, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, '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': '7475713', 'n_tokens_mistral': 1034, 'n_tokens_neox': 1008, 'n_words': 213}