<commit_before>$(function() {
  var models = window.models = {};

  var progressInterval = 10;

  models.Song = Backbone.Model.extend({
    defaults: {
      title: 'Unknown'
    }
  });

  models.Playback = Backbone.Model.extend({
    defaults: {
      progress: 0,
      muted: false
    },

    initialize: function() {
      var audio = new Audio();
      audio.autoplay = true;
      audio.addEventListener(
        'canplaythrough', _.bind(this.audioCanPlay, this));
      this.set({ audio: audio });

      this.on('change:song', this.songChanged, this);
      this.on('change:muted', this.mutedChanged, this);
    },

    reset: function() {
      this.unset('song');
    },

    songChanged: function() {
      var song = this.get('song');
      if (song) {
        this.set({
          started: new Date(
            new Date().valueOf() - song.get('elapsed')
          )
        });
        this.startPlayback();
      } else {
        this.unset('started');
        this.stopPlayback();
      }
    },

    startPlayback: function() {
      this.stopPlayback();
      this._interval = setInterval(
        _.bind(this.updateProgress, this), progressInterval);
      this.startAudio();
    },
    
    stopPlayback: function() {
      if (this._interval) {
        clearInterval(this._interval);
        delete this._interval;
      }
      this.stopAudio();
    },

    startAudio: function() {
      this.stopAudio();
      this.updateProgress();

      if (!this.has('song'))
        return;

      var audio = this.get('audio');
      audio.src = this.get('song').get('song_path');
    },

    audioCanPlay: function() {
      var audio = this.get('audio');
      audio.currentTime = this.get('progress');
      audio.currentTime = this.get('progress');
      audio.play();
    },

    stopAudio: function() {
      var audio = this.get('audio');
      audio.pause();
      audio.src = '';
    },

    mutedChanged: function() {
      this.get('audio').muted = this.get('muted');
    },

    updateProgress: function() {
      var song = this.get('song');
      var started = this.get('started');
      if (!song || !started) {
        this.stopPlayback();
        return;
      }

      var now = new Date();
      var seconds = (now - started) / 1000;
      if (seconds > song.get('duration'))
        seconds = song.get('duration');

      this.set({ progress: seconds });
    },

    mute: function() {
      this.set({ muted: true });<commit_msg>Removed duplicate line of code.<commit_after>$(function() {
  var models = window.models = {};

  var progressInterval = 10;

  models.Song = Backbone.Model.extend({
    defaults: {
      title: 'Unknown'
    }
  });

  models.Playback = Backbone.Model.extend({
    defaults: {
      progress: 0,
      muted: false
    },

    initialize: function() {
      var audio = new Audio();
      audio.autoplay = true;
      audio.addEventListener(
        'canplaythrough', _.bind(this.audioCanPlay, this));
      this.set({ audio: audio });

      this.on('change:song', this.songChanged, this);
      this.on('change:muted', this.mutedChanged, this);
    },

    reset: function() {
      this.unset('song');
    },

    songChanged: function() {
      var song = this.get('song');
      if (song) {
        this.set({
          started: new Date(
            new Date().valueOf() - song.get('elapsed')
          )
        });
        this.startPlayback();
      } else {
        this.unset('started');
        this.stopPlayback();
      }
    },

    startPlayback: function() {
      this.stopPlayback();
      this._interval = setInterval(
        _.bind(this.updateProgress, this), progressInterval);
      this.startAudio();
    },
    
    stopPlayback: function() {
      if (this._interval) {
        clearInterval(this._interval);
        delete this._interval;
      }
      this.stopAudio();
    },

    startAudio: function() {
      this.stopAudio();
      this.updateProgress();

      if (!this.has('song'))
        return;

      var audio = this.get('audio');
      audio.src = this.get('song').get('song_path');
    },

    audioCanPlay: function() {
      var audio = this.get('audio');
      audio.currentTime = this.get('progress');
      audio.play();
    },

    stopAudio: function() {
      var audio = this.get('audio');
      audio.pause();
      audio.src = '';
    },

    mutedChanged: function() {
      this.get('audio').muted = this.get('muted');
    },

    updateProgress: function() {
      var song = this.get('song');
      var started = this.get('started');
      if (!song || !started) {
        this.stopPlayback();
        return;
      }

      var now = new Date();
      var seconds = (now - started) / 1000;
      if (seconds > song.get('duration'))
        seconds = song.get('duration');

      this.set({ progress: seconds });
    },

    mute: function() {
      this.set({ muted: true });
{'fraction_non_alphanumeric': 0.16177070583435332, 'fraction_numerical': 0.0028559771521827824, 'mean_word_length': 2.0855884203901827, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '1321365', 'n_tokens_mistral': 1523, 'n_tokens_neox': 1444, 'n_words': 294}