text: /**
   * Seek, Load Progress, and Play Progress
   * @param {vjs.Player|Object} player
   * @param {Object=} options
   * @constructor
   */
  vjs.ProgressControl = vjs.Component.extend({
    /** @constructor */
    init: function(player, options){
      vjs.Component.call(this, player, options);
    }
  });
  
  vjs.ProgressControl.prototype.options_ = {
    children: {
      'seekBar': {}
    }
  };
  
  vjs.ProgressControl.prototype.createEl = function(){
    return vjs.Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-progress-control vjs-control'
    });
  };
  
  /**
   * Seek Bar and holder for the progress bars
   * @param {vjs.Player|Object} player
   * @param {Object=} options
   * @constructor
   */
  vjs.SeekBar = vjs.Slider.extend({
    /** @constructor */
    init: function(player, options){
      vjs.Slider.call(this, player, options);
      player.on('timeupdate', vjs.bind(this, this.updateARIAAttributes));
      player.ready(vjs.bind(this, this.updateARIAAttributes));
    }
  });
  
  vjs.SeekBar.prototype.options_ = {
    children: {
      'loadProgressBar': {},
      'playProgressBar': {},
      'seekHandle': {}
    },
    'barName': 'playProgressBar',
    'handleName': 'seekHandle'
  };
  
  vjs.SeekBar.prototype.playerEvent = 'timeupdate';
  
  vjs.SeekBar.prototype.createEl = function(){
    return vjs.Slider.prototype.createEl.call(this, 'div', {
      className: 'vjs-progress-holder',
      'aria-label': 'video progress bar'
    });
  };
  
  vjs.SeekBar.prototype.updateARIAAttributes = function(){
      // Allows for smooth scrubbing, when player can't keep up.
      var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
      this.el_.setAttribute('aria-valuenow',vjs.round(this.getPercent()*100, 2)); // machine readable value of progress bar (percentage complete)
      this.el_.setAttribute('aria-valuetext',vjs.formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete)
  };
  
  vjs.SeekBar.prototype.getPercent = function(){
    return this.player_.currentTime() / this.player_.duration();
  };
  
  vjs.SeekBar.prototype.onMouseDown = function(event){
    vjs.Slider.prototype.onMouseDown.call(this, event);
  
    this.player_.scrubbing = true;
  
    this.videoWasPlaying = !this.player_.paused();
    this.player_.pause();
  };
  
  vjs.SeekBar.prototype.onMouseMove = function(event){
    var newTime = this.calculateDistance(event) * this.player_.duration();
  
    // Don't let video end while scrubbing.
    if (newTime == this.player_.duration()) { newTime = newTime - 0.1; }
  
    // Set new time (tell player to seek to new time)
    this.player_.currentTime(newTime);
  };
  
  vjs.SeekBar.prototype.onMouseUp = function(event){
    vjs.Slider.prototype.onMouseUp.call(this, event);
  
    this.player_.scrubbing = false;
    if (this.videoWasPlaying) {
      this.player_.play();
    }
  };
  
  vjs.SeekBar.prototype.stepForward = function(){
    this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users
  };
  
  vjs.SeekBar.prototype.stepBack = function(){
    this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users
  };
  
  
  /**
   * Shows load progres
   * @param {vjs.Player|Object} player
   * @param {Object=} options
   * @constructor
   */
  vjs.LoadProgressBar = vjs.Component.extend({
    /** @constructor */
    init: function(player, options){
      vjs.Component.call(this, player, options);
      player.on('progress', vjs.bind(this, this.update));
    }
  });
  
  vjs.LoadProgressBar.prototype.createEl = function(){
    return vjs.Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-load-progress',
      innerHTML: '<span class="vjs-control-text">Loaded: 0%</span>'
    });
  };
  
  vjs.LoadProgressBar.prototype.update = function(){
    if (this.el_.style) { this.el_.style.width = vjs.round(this.player_.bufferedPercent() * 100, 2) + '%'; }
  };
  
  
  /**
   * Shows play progress
   * @param {vjs.Player|Object} player
   * @param {Object=} options
   * @constructor
   */
  vjs.PlayProgressBar = vjs.Component.extend({
    /** @constructor */
    init: function(player, options){
      vjs.Component.call(this, player, options);
    }
  });
  
  vjs.PlayProgressBar.prototype.createEl = function(){
    return vjs.Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-play-progress',
      innerHTML: '<span class="vjs-control-text">Progress: 0%</span>'
    });
  };
  
  /**
   * SeekBar component includes play progress bar, and seek handle
   * Needed so it can determine seek position based on handle position/size
   * @param {vjs.Player|Object} player
   * @param {Object=} options
   * @constructor
   */
  vjs.SeekHandle = vjs.SliderHandle.extend();
  
  /** @inheritDoc */
  vjs.SeekHandle.prototype.defaultValue = '00:00';
  
  /** @inheritDoc */
  vjs.SeekHandle.prototype.createEl = function(){
    return vjs.SliderHandle.prototype.createEl.call(this, 'div', {
      className: 'vjs-seek-handle'
    });
  };