anchor.diff:    Duration duration;
   
     SimulationStepper _timeline;
  +  AnimationDirection get direction => _direction;
     AnimationDirection _direction;
  -
  -  /// The direction used to select the current curve
  -  ///
  -  /// Curve direction is only reset when we hit the beginning or the end of the
  -  /// timeline to avoid discontinuities in the value of any variables this
  -  /// performance is used to animate.
  +  AnimationDirection get curveDirection => _curveDirection;
     AnimationDirection _curveDirection;
   
     /// If non-null, animate with this timing instead of a linear timing
  
positive.code:   /// Stops calling the listener every time the status of the performance changes
    void removeStatusListener(PerformanceStatusListener listener);
  
    /// The current status of this animation
    PerformanceStatus get status;
  
    /// The current progress of this animation (a value from 0.0 to 1.0).
    /// This is the value that is used to update any variables when using updateVariable().
  
negative.code:   /// Whether this animation is stopped at the end
    bool get isCompleted => status == PerformanceStatus.completed;
  }
  
  class AlwaysCompletePerformance extends PerformanceView {
    const AlwaysCompletePerformance();
  
    void updateVariable(Animatable variable) {
      variable.setProgress(1.0, AnimationDirection.forward);
    }
  
    // this performance never changes state
    void addListener(PerformanceListener listener) { }
    void removeListener(PerformanceListener listener) { }
    void addStatusListener(PerformanceStatusListener listener) { }
    void removeStatusListener(PerformanceStatusListener listener) { }
    PerformanceStatus get status => PerformanceStatus.completed;
    AnimationDirection get direction => AnimationDirection.forward;
    AnimationDirection get curveDirection => AnimationDirection.forward;
    double get progress => 1.0;
  }
  const AlwaysCompletePerformance alwaysCompletePerformance = const AlwaysCompletePerformance();
  
  class ReversePerformance extends PerformanceView {
    ReversePerformance(this.masterPerformance) {
      masterPerformance.addStatusListener(_statusChangeHandler);
    }
  
    final PerformanceView masterPerformance;
  
    void updateVariable(Animatable variable) {
      variable.setProgress(progress, curveDirection);
    }
  
    void addListener(PerformanceListener listener) {
      masterPerformance.addListener(listener);
    }
    void removeListener(PerformanceListener listener) {
      masterPerformance.removeListener(listener);
    }
  
    final List<PerformanceStatusListener> _statusListeners = new List<PerformanceStatusListener>();
  
    /// Calls listener every time the status of this performance changes
    void addStatusListener(PerformanceStatusListener listener) {
      _statusListeners.add(listener);
    }
  
    /// Stops calling the listener every time the status of this performance changes
    void removeStatusListener(PerformanceStatusListener listener) {
      _statusListeners.remove(listener);
    }
  
    void _statusChangeHandler(PerformanceStatus status) {
      status = _reverseStatus(status);
      List<PerformanceStatusListener> localListeners = new List<PerformanceStatusListener>.from(_statusListeners);
      for (PerformanceStatusListener listener in localListeners)
        listener(status);
    }
  
    PerformanceStatus get status => _reverseStatus(masterPerformance.status);
    AnimationDirection get direction => _reverseDirection(masterPerformance.direction);
    AnimationDirection get curveDirection => _reverseDirection(masterPerformance.curveDirection);
    double get progress => 1.0 - masterPerformance.progress;
  
    PerformanceStatus _reverseStatus(PerformanceStatus status) {
      switch (status) {
        case PerformanceStatus.forward: return PerformanceStatus.reverse;
        case PerformanceStatus.reverse: return PerformanceStatus.forward;
        case PerformanceStatus.completed: return PerformanceStatus.dismissed;
        case PerformanceStatus.dismissed: return PerformanceStatus.completed;
      }
    }
  
    AnimationDirection _reverseDirection(AnimationDirection direction) {
      switch (direction) {
        case AnimationDirection.forward: return AnimationDirection.reverse;
        case AnimationDirection.reverse: return AnimationDirection.forward;
      }
    }
  }
  
  
  /// A timeline that can be reversed and used to update [Animatable]s.
  ///
  