anchor.diff:    final Text code;
     Image image;
     final Text description;
  +
  +  bool checked = false;
  +
  +  double yTop;
  +  double yBottom;
   }
   
   final List<Train> kTrainData = <Train>[
     new Train('49954', 'https://static.maerklin.de/media/bc/02/bc028d6e5f98ccaeb344118d64927edd1451859002.jpg', 'Type 100 crane car and type 817 boom tender car.'),
     new Train('26602', 'https://static.maerklin.de/media/cc/b9/ccb96e67093f188d67acb4ca97b407da1452597002.jpg', 'Class Köf II Diesel Locomotive with stake cars loaded with bricks and construction steel mats.'),
  -  new Train('46925', 'https://static.maerklin.de/media/ad/3f/ad3fa11c35f10737cb54320b9e5c006a1451857433.jpg', 'Set with 2 Type Kbs Stake Cars transporting brewery tanks (storage tanks).'),
  +  new Train('46925', 'https://static.maerklin.de/media/ad/3f/ad3fa11c35f10737cb54320b9e5c006a1451857433.jpg', 'Set with of two stake cars transporting four brewery tanks (storage tanks).'),
     new Train('46870', 'https://static.maerklin.de/media/ed/36/ed365bf5b8c89cc63d54afa81db80df01451857433.jpg', 'Swiss Federal Railways (SBB) four-axle flat cars with telescoping covers loaded with coils.'),
     new Train('47724', 'https://static.maerklin.de/media/20/fe/20fe74d67d07417352fd08b164f271c41451859002.jpg', 'Swedish State Railways (SJ) two-axle container transport cars loaded with two "Inno freight" WoodTainer XXL containers, painted and lettered for "green cargo".'),
  -  new Train('47319', 'https://static.maerklin.de/media/6e/32/6e32c9c7153637b9e0d484a1958703191451859002.jpg', 'Stake cars with steel and pipe.'),
  +  new Train('47319', 'https://static.maerklin.de/media/6e/32/6e32c9c7153637b9e0d484a1958703191451859002.jpg', 'Four stake cars. One with two sets of short pipes, one with long pipes, one with steel bars, and one with I-beams.'),
   ];
   
   final Text title = new Text(
  
positive.code:     captionSize
    ));
  
    final List<double> columnWidths = captions.map/*<double>*/((Text caption) => caption.naturalMaxWidth).toList();
    for (int index = 0; index < kTrainData.length; index += 1) {
      Train train = kTrainData[index];
      columnWidths[0] = math.max(columnWidths[0], train.code.naturalMaxWidth + horizontalPadding * 2.0);
      columnWidths[1] = math.max(columnWidths[1], (train.image?.width ?? 0.0) + horizontalPadding * 2.0);
      columnWidths[2] = math.max(columnWidths[2], train.description.naturalMaxWidth + horizontalPadding * 2.0);
    }
    // make the image column max 40% (and take into account the device pixel ratio)
    columnWidths[1] = math.min(columnWidths[1] / window.devicePixelRatio, width * 0.4);
    columnWidths[2] = width - (columnWidths[0] + columnWidths[1]);
  
    final Path path = new Path();
  
negative.code:       c.drawImageRect(train.image, sourceRect, destRect, null);
      }
      x += columnWidths[1];
      train.description.paint(c, new Rect.fromLTWH(x + horizontalPadding, y, columnWidths[2] - horizontalPadding * 2.0, rowHeight));
      x += columnWidths[2];
      path.lineTo(x, y - verticalPadding);
      y += rowHeight + verticalPadding;
      train.yBottom = y;
    }
    final double tableBottom = y;
  
  