<commit_before>// TODO rename to file driver
// TODO support ttyrec (via opts.format == 'ttyrec')

function now() {
  return performance.now();
}

function asciicast(url, w, h, speed, feed, _onFinish) {
  let timeoutId;
  let frames;
  let nextFrameIndex = 0;
  let virtualElapsedTime = 0;
  let startedTime;
  let lastFrameTime;

  function scheduleNextFrame() {
    const nextFrame = frames[nextFrameIndex];

    if (nextFrame) {
      const delay = nextFrame[0] * 1000;
      const actualElapsedTime = now() - startedTime;
      let timeout = (virtualElapsedTime + delay) - actualElapsedTime;

      if (timeout < 0) {
        timeout = 0;
      }

      timeoutId = setTimeout(runFrame, timeout);
    } else {
      console.log('finished');
      // onFinish();
    }
  }

  function runFrame() {
    let frame = frames[nextFrameIndex];
    let actualElapsedTime;

    do {
      feed(frame[1]);
      virtualElapsedTime += (frame[0] * 1000);
      nextFrameIndex++;
      frame = frames[nextFrameIndex];
      actualElapsedTime = now() - startedTime;
    } while (frame && (actualElapsedTime > (virtualElapsedTime + frame[0] * 1000)));

    scheduleNextFrame();
  }

  return {
    // preload: () => {
    //   return new Promise(w,h);
    // },

    start: () => {
      return fetch(url)
      .then(res => res.json())
      .then(asciicast => {
        frames = asciicast['stdout'];

        startedTime = (new Date()).getTime();
        lastFrameTime = startedTime;
        scheduleNextFrame();

        return {
          width: w || asciicast['width'],
          height: h || asciicast['height'],
          duration: asciicast['duration']
        };
      })
    },

    stop: () => {
      clearTimeout(timeoutId);
    },

    // pauseOrResume: () => {
    //   return  pauseTime; // when paused, otherwise no return
    // },

    // seek: (pos) => {
    //   return seekTime;
    // },

    getCurrentTime: () => {
      if (startedTime) {
        return (now() - startedTime) / 1000;
      }
    }
  }
}

export { asciicast };<commit_msg>Basic version of pauseOrResume for asciicast driver<commit_after>// TODO rename to file driver
// TODO support ttyrec (via opts.format == 'ttyrec')

function now() {
  return performance.now();
}

function asciicast(url, w, h, speed, feed, onFinish {
  let frames;
  let timeoutId;
  let isFinished;
  let nextFrameIndex = 0;
  let virtualElapsedTime = 0;
  let startedTime;
  let lastFrameTime;

  function scheduleNextFrame() {
    const nextFrame = frames[nextFrameIndex];

    if (nextFrame) {
      const delay = nextFrame[0] * 1000;
      const actualElapsedTime = now() - startedTime;
      let timeout = (virtualElapsedTime + delay) - actualElapsedTime;

      if (timeout < 0) {
        timeout = 0;
      }

      timeoutId = setTimeout(runFrame, timeout);
    } else {
      timeoutId = null;
      isFinished = true;
      onFinish();
    }
  }

  function runFrame() {
    let frame = frames[nextFrameIndex];
    let actualElapsedTime;

    do {
      feed(frame[1]);
      virtualElapsedTime += (frame[0] * 1000);
      nextFrameIndex++;
      frame = frames[nextFrameIndex];
      actualElapsedTime = now() - startedTime;
    } while (frame && (actualElapsedTime > (virtualElapsedTime + frame[0] * 1000)));

    scheduleNextFrame();
  }

  function start() {
    nextFrameIndex = 0;
    virtualElapsedTime = 0;
    startedTime = now();
    lastFrameTime = startedTime;
    isFinished = false;
    scheduleNextFrame();
  }

  return {
    // preload: () => {
    //   return new Promise(w,h);
    // },

    start: () => {
      return fetch(url)
      .then(res => res.json())
      .then(asciicast => {
        frames = asciicast['stdout'];
        start();

        return {
          width: w || asciicast['width'],
          height: h || asciicast['height'],
          duration: asciicast['duration']
        };
      })
    },

    stop: () => {
      clearTimeout(timeoutId);
    },

    pauseOrResume: () => {
      if (timeoutId) {
        clearTimeout(timeoutId);
        timeoutId = null;
        return false;
      } else {
        if (isFinished) {
          // TODO reset terminal here or in core
          start();
        } else {
          scheduleNextFrame();
        }

        return true;
      }
    },

    // seek: (pos) => {
    //   return seekTime;
    // },

    getCurrentTime: () => {
      if (startedTime) {
        return (now() - startedTime) / 1000;
      }
    }
  }
}

export { asciicast };
{'fraction_non_alphanumeric': 0.13770856507230256, 'fraction_numerical': 0.011123470522803115, 'mean_word_length': 2.1506657323055363, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, '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': '6112116', 'n_tokens_mistral': 1460, 'n_tokens_neox': 1382, 'n_words': 322}