anchor.diff:  
     static double _waveOuterOpacityForTime(int touchDownMs, int touchUpMs) {
       var touchDown = touchDownMs.toDouble() / 1000;
  -    var outerOpacity = touchDown * 0.3;
  +    var outerOpacity = touchDown * 0.6;
       var waveOpacity = _waveOpacityForTimes(touchUpMs);
       var opacity = max(0, min(outerOpacity, waveOpacity));
       return opacity;
     }
   
  -  static bool _waveDidFinish(Wave wave, double radius) =>
  -      _waveOpacityForTimes(wave.mouseUpMs) < 0.01 &&
  -          radius >= min(wave.maxRadius, _waveMaxRadius);
  -
  -  static bool _waveAtMaximum(Wave wave, double radius) =>
  -      _waveOpacityForTimes(wave.mouseUpMs) > _waveInitialOpacity &&
  -          radius >= min(wave.maxRadius, _waveMaxRadius);
  -
  -  static void _drawRipple(Wave context, int x, int y, double radius,
  +  static bool _waveDidFinish(Wave wave, double radius) {
  +    var mouseUpMs = wave.mouseUpMs;
  +    var didFinish = _waveOpacityForTimes(wave.mouseUpMs) < 0.01 &&
  +        radius >= min(wave.maxRadius, _waveMaxRadius);
  +    window.console.log('After ${mouseUpMs} didFinish: $didFinish.');
  +    return didFinish;
  +  }
  +
  +  static bool _waveAtMaximum(Wave wave, double radius) {
  +    var mouseUpMs = wave.mouseUpMs;
  +    var atMaximum =
  +        wave.mouseUpMs <= 0 && radius >= min(wave.maxRadius, _waveMaxRadius);
  +    window.console.log('After ${mouseUpMs} atMaximum: $atMaximum.');
  +    return atMaximum;
  +  }
  +
  +  static void _drawRipple(Wave wave, int x, int y, double radius,
         double innerAlpha, double outerAlpha, String waveColor) {
  -    context.row.querySelectorAll('.paper-ripple-bg').forEach(
  +    wave.row.querySelectorAll('.paper-ripple-bg').forEach(
           (DivElement element) => element.style.opacity = outerAlpha.toString());
  -    var s = radius / (context.clientSize / 2);
  -    var dx = x - (context.clientWidth / 2);
  -    var dy = y - (context.clientHeight / 2);
  -    context.row
  +    var s = radius / (wave.clientSize / 2);
  +    var dx = x - (wave.clientWidth / 2);
  +    var dy = y - (wave.clientHeight / 2);
  +    wave.row
           .querySelectorAll('.paper-ripple-wave')
           .forEach((DivElement element) {
         element.style.opacity = innerAlpha.toString();
         element.style.transform = 'scale3d($s, $s, 1)';
         element.style.color = waveColor;
       });
  -    context.row
  -        .querySelectorAll('.paper-ripple-wc')
  -        .forEach((DivElement element) {
  +    wave.row.querySelectorAll('.paper-ripple-wc').forEach((DivElement element) {
         element.style.transform = 'translate3d(${dx}px, ${dy}px, 0)';
       });
     }
   
  -  static Wave _createWave(DivElement row) {
  +  Wave _createWave(DivElement row) {
       var fgColor = row.getComputedStyle().color;
       var wave = new List<Element>();
       var wc = new List<Element>();
  -    row.querySelectorAll('.paper-ripple-bg').forEach((DivElement element) =>
  -        element.style.backgroundColor = fgColor.toString());
  -    row.querySelectorAll('.table-body-cell').forEach((DivElement element) {
  +    var listener = row.onMouseOut.listen(onUpOverEntry);
  +    for (DivElement element in row.querySelectorAll('.paper-ripple-bg')) {
  +      element.style.backgroundColor = fgColor.toString();
  +    }
  +    for (DivElement element in row.querySelectorAll('.table-body-cell')) {
         var elementStyle = element.getComputedStyle();
         var inner = document.createElement('div');
         inner.classes.add('paper-ripple-wave');
  
positive.code:     var rectangle = target.client;
      var width = rectangle.width;
      var height = rectangle.height;
      var x = event.offset.x - rectangle.left;
      var y = event.offset.y - rectangle.top;
      wave.startPosition = new Point(x, y);
      if (target.classes.contains('recenteringTouch')) {
  
negative.code: import 'dart:html';
  import 'dart:math';
  import 'dart:async';
  
  import 'package:core_elements/core_animated_pages.dart';
  import 'package:paper_elements/paper_button.dart';
  