// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('$ReorderableListView', () {
    const double itemHeight = 48.0;
    const List<String> originalListItems = <String>['Item 1', 'Item 2', 'Item 3', 'Item 4'];
    late List<String> listItems;

    void onReorder(int oldIndex, int newIndex) {
      if (oldIndex < newIndex) {
        newIndex -= 1;
      }
      final String element = listItems.removeAt(oldIndex);
      listItems.insert(newIndex, element);
    }

    Widget listItemToWidget(String listItem) {
      return SizedBox(
        key: Key(listItem),
        height: itemHeight,
        width: itemHeight,
        child: Text(listItem),
      );
    }

    Widget build({
      Widget? header,
      Widget? footer,
      Axis scrollDirection = Axis.vertical,
      bool reverse = false,
      EdgeInsets padding = EdgeInsets.zero,
      TextDirection textDirection = TextDirection.ltr,
      TargetPlatform? platform,
    }) {
      return MaterialApp(
        theme: ThemeData(platform: platform),
        home: Directionality(
          textDirection: textDirection,
          child: SizedBox(
            height: itemHeight * 10,
            width: itemHeight * 10,
            child: ReorderableListView(
              header: header,
              footer: footer,
              scrollDirection: scrollDirection,
              onReorder: onReorder,
              reverse: reverse,
              padding: padding,
              children: listItems.map<Widget>(listItemToWidget).toList(),
            ),
          ),
        ),
      );
    }

    setUp(() {
      // Copy the original list into listItems.
      listItems = originalListItems.toList();
    });

    group('in vertical mode', () {
      testWidgets('reorder is not triggered when children length is less or equals to 1', (WidgetTester tester) async {
        bool onReorderWasCalled = false;
        final List<String> currentListItems = listItems.take(1).toList();
        final ReorderableListView reorderableListView = ReorderableListView(
          header: const Text('Header'),
          onReorder: (_, __) => onReorderWasCalled = true,
          children: currentListItems.map<Widget>(listItemToWidget).toList(),
        );
        final List<String> currentOriginalListItems = originalListItems.take(1).toList();
        await tester.pumpWidget(MaterialApp(
          home: SizedBox(
            height: itemHeight * 10,
            child: reorderableListView,
          ),
        ));
        expect(currentListItems, orderedEquals(currentOriginalListItems));
        final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('Item 1')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        expect(currentListItems, orderedEquals(currentOriginalListItems));
        await drag.moveTo(tester.getBottomLeft(find.text('Item 1')) * 2);
        expect(currentListItems, orderedEquals(currentOriginalListItems));
        await drag.up();
        expect(onReorderWasCalled, false);
        expect(currentListItems, orderedEquals(<String>['Item 1']));
      });

      testWidgets('reorders its contents only when a drag finishes', (WidgetTester tester) async {
        await tester.pumpWidget(build());
        expect(listItems, orderedEquals(originalListItems));
        final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('Item 1')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        expect(listItems, orderedEquals(originalListItems));
        await drag.moveTo(tester.getCenter(find.text('Item 4')));
        expect(listItems, orderedEquals(originalListItems));
        await drag.up();
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 1', 'Item 4']));
      });

      testWidgets('allows reordering from the very top to the very bottom', (WidgetTester tester) async {
        await tester.pumpWidget(build());
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 1')),
          tester.getCenter(find.text('Item 4')) + const Offset(0.0, itemHeight * 2),
        );
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));
      });

      testWidgets('allows reordering from the very bottom to the very top', (WidgetTester tester) async {
        await tester.pumpWidget(build());
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 4')),
          tester.getCenter(find.text('Item 1')),
        );
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 2', 'Item 3']));
      });

      testWidgets('allows reordering inside the middle of the widget', (WidgetTester tester) async {
        await tester.pumpWidget(build());
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 3')),
          tester.getCenter(find.text('Item 2')),
        );
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 2', 'Item 4']));
      });

      testWidgets('properly reorders with a header', (WidgetTester tester) async {
        await tester.pumpWidget(build(header: const Text('Header Text')));
        expect(find.text('Header Text'), findsOneWidget);
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 1')),
          tester.getCenter(find.text('Item 4')) + const Offset(0.0, itemHeight * 2),
        );
        await tester.pumpAndSettle();
        expect(find.text('Header Text'), findsOneWidget);
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));
      });

      testWidgets('properly reorders with a footer', (WidgetTester tester) async {
        await tester.pumpWidget(build(footer: const Text('Footer Text')));
        expect(find.text('Footer Text'), findsOneWidget);
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 1')),
          tester.getCenter(find.text('Item 4')) + const Offset(0.0, itemHeight * 2),
        );
        await tester.pumpAndSettle();
        expect(find.text('Footer Text'), findsOneWidget);
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));
      });

      testWidgets('properly determines the vertical drop area extents', (WidgetTester tester) async {
        final Widget reorderableListView = ReorderableListView(
          onReorder: (int oldIndex, int newIndex) { },
          children: const <Widget>[
            SizedBox(
              key: Key('Normal item'),
              height: itemHeight,
              child: Text('Normal item'),
            ),
            SizedBox(
              key: Key('Tall item'),
              height: itemHeight * 2,
              child: Text('Tall item'),
            ),
            SizedBox(
              key: Key('Last item'),
              height: itemHeight,
              child: Text('Last item'),
            ),
          ],
        );
        await tester.pumpWidget(MaterialApp(
          home: SizedBox(
            height: itemHeight * 10,
            child: reorderableListView,
          ),
        ));

        double getListHeight() {
          final RenderSliverList listScrollView = tester.renderObject(find.byType(SliverList));
          return listScrollView.geometry!.maxPaintExtent;
        }

        const double kDraggingListHeight = 4 * itemHeight;
        // Drag a normal text item
        expect(getListHeight(), kDraggingListHeight);
        TestGesture drag = await tester.startGesture(tester.getCenter(find.text('Normal item')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        await tester.pumpAndSettle();
        expect(getListHeight(), kDraggingListHeight);

        // Move it
        await drag.moveTo(tester.getCenter(find.text('Last item')));
        await tester.pumpAndSettle();
        expect(getListHeight(), kDraggingListHeight);

        // Drop it
        await drag.up();
        await tester.pumpAndSettle();
        expect(getListHeight(), kDraggingListHeight);

        // Drag a tall item
        drag = await tester.startGesture(tester.getCenter(find.text('Tall item')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        await tester.pumpAndSettle();
        expect(getListHeight(), kDraggingListHeight);
        // Move it
        await drag.moveTo(tester.getCenter(find.text('Last item')));
        await tester.pumpAndSettle();
        expect(getListHeight(), kDraggingListHeight);

        // Drop it
        await drag.up();
        await tester.pumpAndSettle();
        expect(getListHeight(), kDraggingListHeight);
      });

      testWidgets('Vertical drag in progress golden image', (WidgetTester tester) async {
        debugDisableShadows = false;
        final Widget reorderableListView = ReorderableListView(
          children: <Widget>[
            Container(
              key: const Key('pink'),
              width: double.infinity,
              height: itemHeight,
              color: Colors.pink,
            ),
            Container(
              key: const Key('blue'),
              width: double.infinity,
              height: itemHeight,
              color: Colors.blue,
            ),
            Container(
              key: const Key('green'),
              width: double.infinity,
              height: itemHeight,
              color: Colors.green,
            ),
          ],
          onReorder: (int oldIndex, int newIndex) { },
        );
        await tester.pumpWidget(MaterialApp(
          home: Container(
            color: Colors.white,
            height: itemHeight * 3,
            // Wrap in an overlay so that the golden image includes the dragged item.
            child: Overlay(
              initialEntries: <OverlayEntry>[
                OverlayEntry(builder: (BuildContext context) {
                  // Wrap the list in padding to test that the positioning
                  // is correct when the origin of the overlay is different
                  // from the list.
                  return Padding(
                    padding: const EdgeInsets.all(24),
                    child: reorderableListView,
                  );
                }),
              ],
            ),
          ),
        ));

        // Start dragging the second item.
        final TestGesture drag = await tester.startGesture(tester.getCenter(find.byKey(const Key('blue'))));
        await tester.pump(kLongPressTimeout + kPressTimeout);

        // Drag it up to be partially over the top item.
        await drag.moveBy(const Offset(0, -itemHeight / 3));
        await tester.pumpAndSettle();

        // Should be an image of the second item overlapping the bottom of the
        // first with a gap between the first and third and a drop shadow on
        // the dragged item.
        await expectLater(
          find.byType(Overlay).last,
          matchesGoldenFile('reorderable_list_test.vertical.drop_area.png'),
        );
        debugDisableShadows = true;
      });

      testWidgets('Preserves children states when the list parent changes the order', (WidgetTester tester) async {
        _StatefulState findState(Key key) {
          return find.byElementPredicate((Element element) => element.findAncestorWidgetOfExactType<_Stateful>()?.key == key)
              .evaluate()
              .first
              .findAncestorStateOfType<_StatefulState>()!;
        }
        await tester.pumpWidget(MaterialApp(
          home: ReorderableListView(
            children: <Widget>[
              _Stateful(key: const Key('A')),
              _Stateful(key: const Key('B')),
              _Stateful(key: const Key('C')),
            ],
            onReorder: (int oldIndex, int newIndex) { },
          ),
        ));
        await tester.tap(find.byKey(const Key('A')));
        await tester.pumpAndSettle();
        // Only the 'A' widget should be checked.
        expect(findState(const Key('A')).checked, true);
        expect(findState(const Key('B')).checked, false);
        expect(findState(const Key('C')).checked, false);

        await tester.pumpWidget(MaterialApp(
          home: ReorderableListView(
            children: <Widget>[
              _Stateful(key: const Key('B')),
              _Stateful(key: const Key('C')),
              _Stateful(key: const Key('A')),
            ],
            onReorder: (int oldIndex, int newIndex) { },
          ),
        ));
        // Only the 'A' widget should be checked.
        expect(findState(const Key('B')).checked, false);
        expect(findState(const Key('C')).checked, false);
        expect(findState(const Key('A')).checked, true);
      });

      testWidgets('Preserves children states when rebuilt', (WidgetTester tester) async {
        const Key firstBox = Key('key');
        Widget build() {
          return MaterialApp(
            home: Directionality(
              textDirection: TextDirection.ltr,
              child: SizedBox(
                width: 100,
                height: 100,
                child: ReorderableListView(
                  children: const <Widget>[
                    SizedBox(key: firstBox, width: 10, height: 10),
                  ],
                  onReorder: (_, __) {},
                ),
              ),
            ),
          );
        }

        // When the widget is rebuilt, the state of child should be consistent.
        await tester.pumpWidget(build());
        final Element e0 = tester.element(find.byKey(firstBox));
        await tester.pumpWidget(build());
        final Element e1 = tester.element(find.byKey(firstBox));
        expect(e0, equals(e1));
      });

      testWidgets('Uses the PrimaryScrollController when available', (WidgetTester tester) async {
        final ScrollController primary = ScrollController();
        final Widget reorderableList = ReorderableListView(
          children: const <Widget>[
            SizedBox(width: 100.0, height: 100.0, key: Key('C'), child: Text('C')),
            SizedBox(width: 100.0, height: 100.0, key: Key('B'), child: Text('B')),
            SizedBox(width: 100.0, height: 100.0, key: Key('A'), child: Text('A')),
          ],
          onReorder: (int oldIndex, int newIndex) { },
        );

        Widget buildWithScrollController(ScrollController controller) {
          return MaterialApp(
            home: PrimaryScrollController(
              controller: controller,
              child: SizedBox(
                height: 100.0,
                width: 100.0,
                child: reorderableList,
              ),
            ),
          );
        }

        await tester.pumpWidget(buildWithScrollController(primary));
        Scrollable scrollView = tester.widget(
          find.byType(Scrollable),
        );
        expect(scrollView.controller, primary);

        // Now try changing the primary scroll controller and checking that the scroll view gets updated.
        final ScrollController primary2 = ScrollController();
        await tester.pumpWidget(buildWithScrollController(primary2));
        scrollView = tester.widget(
          find.byType(Scrollable),
        );
        expect(scrollView.controller, primary2);
      });

      testWidgets('Test custom ScrollController behavior when set', (WidgetTester tester) async {
        const Key firstBox = Key('C');
        const Key secondBox = Key('B');
        const Key thirdBox = Key('A');
        final ScrollController customController = ScrollController();
        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: SizedBox(
                height: 150,
                child: ReorderableListView(
                  scrollController: customController,
                  onReorder: (int oldIndex, int newIndex) { },
                  children: const <Widget>[
                    SizedBox(width: 100.0, height: 100.0, key: firstBox, child: Text('C')),
                    SizedBox(width: 100.0, height: 100.0, key: secondBox, child: Text('B')),
                    SizedBox(width: 100.0, height: 100.0, key: thirdBox, child: Text('A')),
                  ],
                ),
              ),
            ),
          ),
        );

        // Check initial scroll offset of first list item relative to
        // the offset of the list view.
        customController.animateTo(
          40.0,
          duration: const Duration(milliseconds: 200),
          curve: Curves.linear,
        );
        await tester.pumpAndSettle();
        Offset listViewTopLeft = tester.getTopLeft(
          find.byType(ReorderableListView),
        );
        Offset firstBoxTopLeft = tester.getTopLeft(
          find.byKey(firstBox),
        );
        expect(firstBoxTopLeft.dy, listViewTopLeft.dy - 40.0);

        // Drag the UI to see if the scroll controller updates accordingly
        await tester.drag(
          find.text('B'),
          const Offset(0.0, -100.0),
        );
        listViewTopLeft = tester.getTopLeft(
          find.byType(ReorderableListView),
        );
        firstBoxTopLeft = tester.getTopLeft(
          find.byKey(firstBox),
        );
        // Initial scroll controller offset: 40.0
        // Drag UI by 100.0 upwards vertically
        // First 20.0 px always ignored, so scroll offset is only
        // shifted by 80.0.
        // Final offset: 40.0 + 80.0 = 120.0
        // The total distance available to scroll is 300.0 - 150.0 = 150.0, or
        // height of the ReorderableListView minus height of the SizedBox. Since
        // The final offset is less than this, it's not limited.
        expect(customController.offset, 120.0);
      });

      testWidgets('Still builds when no PrimaryScrollController is available', (WidgetTester tester) async {
        final Widget reorderableList = ReorderableListView(
          children: const <Widget>[
            SizedBox(width: 100.0, height: 100.0, key: Key('C'), child: Text('C')),
            SizedBox(width: 100.0, height: 100.0, key: Key('B'), child: Text('B')),
            SizedBox(width: 100.0, height: 100.0, key: Key('A'), child: Text('A')),
          ],
          onReorder: (int oldIndex, int newIndex) { },
        );
        final Widget overlay = Overlay(
          initialEntries: <OverlayEntry>[
            OverlayEntry(builder: (BuildContext context) => reorderableList),
          ],
        );
        final Widget boilerplate = Localizations(
          locale: const Locale('en'),
          delegates: const <LocalizationsDelegate<dynamic>>[
            DefaultMaterialLocalizations.delegate,
            DefaultWidgetsLocalizations.delegate,
          ],
          child:SizedBox(
            width: 100.0,
            height: 100.0,
            child: Directionality(
              textDirection: TextDirection.ltr,
              child: overlay,
            ),
          ),
        );
        await expectLater(
          () => tester.pumpWidget(boilerplate),
          returnsNormally,
        );
      });

      group('Accessibility (a11y/Semantics)', () {
        Map<CustomSemanticsAction, VoidCallback> getSemanticsActions(int index) {
          final Semantics semantics = find.ancestor(
            of: find.byKey(Key(listItems[index])),
            matching: find.byType(Semantics),
          ).evaluate().first.widget as Semantics;
          return semantics.properties.customSemanticsActions!;
        }

        const CustomSemanticsAction moveToStart = CustomSemanticsAction(label: 'Move to the start');
        const CustomSemanticsAction moveToEnd = CustomSemanticsAction(label: 'Move to the end');
        const CustomSemanticsAction moveUp = CustomSemanticsAction(label: 'Move up');
        const CustomSemanticsAction moveDown = CustomSemanticsAction(label: 'Move down');

        testWidgets('Provides the correct accessibility actions in LTR and RTL modes', (WidgetTester tester) async {
          // The a11y actions for a vertical list are the same in LTR and RTL modes.
          final SemanticsHandle handle = tester.ensureSemantics();
          for (final TextDirection direction in TextDirection.values) {
            await tester.pumpWidget(build());

            // The first item can be moved down or to the end.
            final Map<CustomSemanticsAction, VoidCallback> firstSemanticsActions = getSemanticsActions(0);
            expect(firstSemanticsActions.length, 2, reason: 'The first list item should have 2 custom actions with $direction.');
            expect(firstSemanticsActions.containsKey(moveToStart), false, reason: 'The first item cannot `Move to the start` with $direction.');
            expect(firstSemanticsActions.containsKey(moveUp), false, reason: 'The first item cannot `Move up` with $direction.');
            expect(firstSemanticsActions.containsKey(moveDown), true, reason: 'The first item should be able to `Move down` with $direction.');
            expect(firstSemanticsActions.containsKey(moveToEnd), true, reason: 'The first item should be able to `Move to the end` with $direction.');

            // Items in the middle can be moved to the start, end, up or down.
            for (int i = 1; i < listItems.length - 1; i += 1) {
              final Map<CustomSemanticsAction, VoidCallback> ithSemanticsActions = getSemanticsActions(i);
              expect(ithSemanticsActions.length, 4, reason: 'List item $i should have 4 custom actions with $direction.');
              expect(ithSemanticsActions.containsKey(moveToStart), true, reason: 'List item $i should be able to `Move to the start` with $direction.');
              expect(ithSemanticsActions.containsKey(moveUp), true, reason: 'List item $i should be able to `Move up` with $direction.');
              expect(ithSemanticsActions.containsKey(moveDown), true, reason: 'List item $i should be able to `Move down` with $direction.');
              expect(ithSemanticsActions.containsKey(moveToEnd), true, reason: 'List item $i should be able to `Move to the end` with $direction.');
            }

            // The last item can be moved up or to the start.
            final Map<CustomSemanticsAction, VoidCallback> lastSemanticsActions = getSemanticsActions(listItems.length - 1);
            expect(lastSemanticsActions.length, 2, reason: 'The last list item should have 2 custom actions with $direction.');
            expect(lastSemanticsActions.containsKey(moveToStart), true, reason: 'The last item should be able to `Move to the start` with $direction.');
            expect(lastSemanticsActions.containsKey(moveUp), true, reason: 'The last item should be able to `Move up` with $direction.');
            expect(lastSemanticsActions.containsKey(moveDown), false, reason: 'The last item cannot `Move down` with $direction.');
            expect(lastSemanticsActions.containsKey(moveToEnd), false, reason: 'The last item cannot `Move to the end` with $direction.');
          }
          handle.dispose();
        });

        testWidgets('First item accessibility (a11y) actions work', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to end: move Item 1 to the end of the list.
          await tester.pumpWidget(build());
          Map<CustomSemanticsAction, VoidCallback> firstSemanticsActions = getSemanticsActions(0);
          firstSemanticsActions[moveToEnd]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));

          // Test out move after: move Item 2 (the current first item) one space down.
          await tester.pumpWidget(build());
          firstSemanticsActions = getSemanticsActions(0);
          firstSemanticsActions[moveDown]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 3', 'Item 2', 'Item 4', 'Item 1']));

          handle.dispose();
        });

        testWidgets('Middle item accessibility (a11y) actions work', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to end: move Item 2 to the end of the list.
          await tester.pumpWidget(build());
          Map<CustomSemanticsAction, VoidCallback> middleSemanticsActions = getSemanticsActions(1);
          middleSemanticsActions[moveToEnd]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 4', 'Item 2']));

          // Test out move after: move Item 3 (the current second item) one space down.
          await tester.pumpWidget(build());
          middleSemanticsActions = getSemanticsActions(1);
          middleSemanticsActions[moveDown]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 4', 'Item 3', 'Item 2']));

          // Test out move after: move Item 3 (the current third item) one space up.
          await tester.pumpWidget(build());
          middleSemanticsActions = getSemanticsActions(2);
          middleSemanticsActions[moveUp]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 4', 'Item 2']));

          // Test out move to start: move Item 4 (the current third item) to the start of the list.
          await tester.pumpWidget(build());
          middleSemanticsActions = getSemanticsActions(2);
          middleSemanticsActions[moveToStart]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 3', 'Item 2']));

          handle.dispose();
        });

        testWidgets('Last item accessibility (a11y) actions work', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to start: move Item 4 to the start of the list.
          await tester.pumpWidget(build());
          Map<CustomSemanticsAction, VoidCallback> lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          lastSemanticsActions[moveToStart]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 2', 'Item 3']));

          // Test out move up: move Item 3 (the current last item) one space up.
          await tester.pumpWidget(build());
          lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          lastSemanticsActions[moveUp]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 3', 'Item 2']));

          handle.dispose();
        });

        testWidgets("Doesn't hide accessibility when a child declares its own semantics", (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          final Widget reorderableListView = ReorderableListView(
            onReorder: (int oldIndex, int newIndex) { },
            children: <Widget>[
              const SizedBox(
                key: Key('List tile 1'),
                height: itemHeight,
                child: Text('List tile 1'),
              ),
              SizedBox(
                key: const Key('Switch tile'),
                height: itemHeight,
                child: Material(
                  child: SwitchListTile(
                    title: const Text('Switch tile'),
                    value: true,
                    onChanged: (bool? newValue) { },
                  ),
                ),
              ),
              const SizedBox(
                key: Key('List tile 2'),
                height: itemHeight,
                child: Text('List tile 2'),
              ),
            ],
          );
          await tester.pumpWidget(MaterialApp(
            home: SizedBox(
              height: itemHeight * 10,
              child: reorderableListView,
            ),
          ));

          // Get the switch tile's semantics:
          final SemanticsNode semanticsNode = tester.getSemantics(find.byKey(const Key('Switch tile')));

          // Check for properties of both SwitchTile semantics and the ReorderableListView custom semantics actions.
          expect(semanticsNode, matchesSemantics(
            hasToggledState: true,
            isToggled: true,
            isEnabled: true,
            isFocusable: true,
            hasEnabledState: true,
            label: 'Switch tile',
            hasTapAction: true,
            customActions: const <CustomSemanticsAction>[
              CustomSemanticsAction(label: 'Move up'),
              CustomSemanticsAction(label: 'Move down'),
              CustomSemanticsAction(label: 'Move to the end'),
              CustomSemanticsAction(label: 'Move to the start'),
            ],
          ));
          handle.dispose();
        });
      });
    });

    group('in horizontal mode', () {
      testWidgets('reorder is not triggered when children length is less or equals to 1', (WidgetTester tester) async {
        bool onReorderWasCalled = false;
        final List<String> currentListItems = listItems.take(1).toList();
        final ReorderableListView reorderableListView = ReorderableListView(
          header: const Text('Header'),
          scrollDirection: Axis.horizontal,
          onReorder: (_, __) => onReorderWasCalled = true,
          children: currentListItems.map<Widget>(listItemToWidget).toList(),
        );
        final List<String> currentOriginalListItems = originalListItems.take(1).toList();
        await tester.pumpWidget(MaterialApp(
          home: SizedBox(
            height: itemHeight * 10,
            child: reorderableListView,
          ),
        ));
        expect(currentListItems, orderedEquals(currentOriginalListItems));
        final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('Item 1')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        expect(currentListItems, orderedEquals(currentOriginalListItems));
        await drag.moveTo(tester.getBottomLeft(find.text('Item 1')) * 2);
        expect(currentListItems, orderedEquals(currentOriginalListItems));
        await drag.up();
        expect(onReorderWasCalled, false);
        expect(currentListItems, orderedEquals(<String>['Item 1']));
      });

      testWidgets('allows reordering from the very top to the very bottom', (WidgetTester tester) async {
        await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 1')),
          tester.getCenter(find.text('Item 4')) + const Offset(itemHeight * 2, 0.0),
        );
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));
      });

      testWidgets('allows reordering from the very bottom to the very top', (WidgetTester tester) async {
        await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 4')),
          tester.getCenter(find.text('Item 1')),
        );
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 2', 'Item 3']));
      });

      testWidgets('allows reordering inside the middle of the widget', (WidgetTester tester) async {
        await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 3')),
          tester.getCenter(find.text('Item 2')),
        );
        await tester.pumpAndSettle();
        expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 2', 'Item 4']));
      });

      testWidgets('properly reorders with a header', (WidgetTester tester) async {
        await tester.pumpWidget(build(header: const Text('Header Text'), scrollDirection: Axis.horizontal));
        expect(find.text('Header Text'), findsOneWidget);
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 1')),
          tester.getCenter(find.text('Item 4')) + const Offset(itemHeight * 2, 0.0),
        );
        await tester.pumpAndSettle();
        expect(find.text('Header Text'), findsOneWidget);
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));
        await tester.pumpWidget(build(header: const Text('Header Text'), scrollDirection: Axis.horizontal));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 4')),
          tester.getCenter(find.text('Item 3')),
        );
        await tester.pumpAndSettle();
        expect(find.text('Header Text'), findsOneWidget);
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 4', 'Item 3', 'Item 1']));
      });

      testWidgets('properly reorders with a footer', (WidgetTester tester) async {
        await tester.pumpWidget(build(footer: const Text('Footer Text'), scrollDirection: Axis.horizontal));
        expect(find.text('Footer Text'), findsOneWidget);
        expect(listItems, orderedEquals(originalListItems));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 1')),
          tester.getCenter(find.text('Item 4')) + const Offset(itemHeight * 2, 0.0),
        );
        await tester.pumpAndSettle();
        expect(find.text('Footer Text'), findsOneWidget);
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));
        await tester.pumpWidget(build(footer: const Text('Footer Text'), scrollDirection: Axis.horizontal));
        await longPressDrag(
          tester,
          tester.getCenter(find.text('Item 4')),
          tester.getCenter(find.text('Item 3')),
        );
        await tester.pumpAndSettle();
        expect(find.text('Footer Text'), findsOneWidget);
        expect(listItems, orderedEquals(<String>['Item 2', 'Item 4', 'Item 3', 'Item 1']));
      });

      testWidgets('properly determines the horizontal drop area extents', (WidgetTester tester) async {
        final Widget reorderableListView = ReorderableListView(
          scrollDirection: Axis.horizontal,
          onReorder: (int oldIndex, int newIndex) { },
          children: const <Widget>[
            SizedBox(
              key: Key('Normal item'),
              width: itemHeight,
              child: Text('Normal item'),
            ),
            SizedBox(
              key: Key('Tall item'),
              width: itemHeight * 2,
              child: Text('Tall item'),
            ),
            SizedBox(
              key: Key('Last item'),
              width: itemHeight,
              child: Text('Last item'),
            ),
          ],
        );
        await tester.pumpWidget(MaterialApp(
          home: SizedBox(
            width: itemHeight * 10,
            child: reorderableListView,
          ),
        ));

        double getListWidth() {
          final RenderSliverList listScrollView = tester.renderObject(find.byType(SliverList));
          return listScrollView.geometry!.maxPaintExtent;
        }

        const double kDraggingListWidth = 4 * itemHeight;
        // Drag a normal text item
        expect(getListWidth(), kDraggingListWidth);
        TestGesture drag = await tester.startGesture(tester.getCenter(find.text('Normal item')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        await tester.pumpAndSettle();
        expect(getListWidth(), kDraggingListWidth);

        // Move it
        await drag.moveTo(tester.getCenter(find.text('Last item')));
        await tester.pumpAndSettle();
        expect(getListWidth(), kDraggingListWidth);

        // Drop it
        await drag.up();
        await tester.pumpAndSettle();
        expect(getListWidth(), kDraggingListWidth);

        // Drag a tall item
        drag = await tester.startGesture(tester.getCenter(find.text('Tall item')));
        await tester.pump(kLongPressTimeout + kPressTimeout);
        await tester.pumpAndSettle();
        expect(getListWidth(), kDraggingListWidth);
        // Move it
        await drag.moveTo(tester.getCenter(find.text('Last item')));
        await tester.pumpAndSettle();
        expect(getListWidth(), kDraggingListWidth);

        // Drop it
        await drag.up();
        await tester.pumpAndSettle();
        expect(getListWidth(), kDraggingListWidth);
      });

      testWidgets('Horizontal drag in progress golden image', (WidgetTester tester) async {
        debugDisableShadows = false;
        final Widget reorderableListView = ReorderableListView(
          scrollDirection: Axis.horizontal,
          onReorder: (int oldIndex, int newIndex) { },
          children: <Widget>[
            Container(
              key: const Key('pink'),
              height: double.infinity,
              width: itemHeight,
              color: Colors.pink,
            ),
            Container(
              key: const Key('blue'),
              height: double.infinity,
              width: itemHeight,
              color: Colors.blue,
            ),
            Container(
              key: const Key('green'),
              height: double.infinity,
              width: itemHeight,
              color: Colors.green,
            ),
          ],
        );
        await tester.pumpWidget(MaterialApp(
          home: Container(
            color: Colors.white,
            width: itemHeight * 3,
            // Wrap in an overlay so that the golden image includes the dragged item.
            child: Overlay(
              initialEntries: <OverlayEntry>[
                OverlayEntry(builder: (BuildContext context) {
                  // Wrap the list in padding to test that the positioning
                  // is correct when the origin of the overlay is different
                  // from the list.
                  return Padding(
                    padding: const EdgeInsets.all(24),
                    child: reorderableListView,
                  );
                }),
              ],
            ),
          ),
        ));

        // Start dragging the second item.
        final TestGesture drag = await tester.startGesture(tester.getCenter(find.byKey(const Key('blue'))));
        await tester.pump(kLongPressTimeout + kPressTimeout);

        // Drag it left to be partially over the first item.
        await drag.moveBy(const Offset(-itemHeight / 3, 0));
        await tester.pumpAndSettle();

        // Should be an image of the second item overlapping the right of the
        // first with a gap between the first and third and a drop shadow on
        // the dragged item.
        await expectLater(
          find.byType(Overlay).last,
          matchesGoldenFile('reorderable_list_test.horizontal.drop_area.png'),
        );
        debugDisableShadows = true;
      });

      testWidgets('Preserves children states when the list parent changes the order', (WidgetTester tester) async {
        _StatefulState findState(Key key) {
          return find.byElementPredicate((Element element) => element.findAncestorWidgetOfExactType<_Stateful>()?.key == key)
              .evaluate()
              .first
              .findAncestorStateOfType<_StatefulState>()!;
        }
        await tester.pumpWidget(MaterialApp(
          home: ReorderableListView(
            onReorder: (int oldIndex, int newIndex) { },
            scrollDirection: Axis.horizontal,
            children: <Widget>[
              _Stateful(key: const Key('A')),
              _Stateful(key: const Key('B')),
              _Stateful(key: const Key('C')),
            ],
          ),
        ));
        await tester.tap(find.byKey(const Key('A')));
        await tester.pumpAndSettle();
        // Only the 'A' widget should be checked.
        expect(findState(const Key('A')).checked, true);
        expect(findState(const Key('B')).checked, false);
        expect(findState(const Key('C')).checked, false);

        await tester.pumpWidget(MaterialApp(
          home: ReorderableListView(
            onReorder: (int oldIndex, int newIndex) { },
            scrollDirection: Axis.horizontal,
            children: <Widget>[
              _Stateful(key: const Key('B')),
              _Stateful(key: const Key('C')),
              _Stateful(key: const Key('A')),
            ],
          ),
        ));
        // Only the 'A' widget should be checked.
        expect(findState(const Key('B')).checked, false);
        expect(findState(const Key('C')).checked, false);
        expect(findState(const Key('A')).checked, true);
      });

      testWidgets('Preserves children states when rebuilt', (WidgetTester tester) async {
        const Key firstBox = Key('key');
        Widget build() {
          return MaterialApp(
            home: Directionality(
              textDirection: TextDirection.ltr,
              child: SizedBox(
                width: 100,
                height: 100,
                child: ReorderableListView(
                  scrollDirection: Axis.horizontal,
                  children: const <Widget>[
                    SizedBox(key: firstBox, width: 10, height: 10),
                  ],
                  onReorder: (_, __) {},
                ),
              ),
            ),
          );
        }

        // When the widget is rebuilt, the state of child should be consistent.
        await tester.pumpWidget(build());
        final Element e0 = tester.element(find.byKey(firstBox));
        await tester.pumpWidget(build());
        final Element e1 = tester.element(find.byKey(firstBox));
        expect(e0, equals(e1));
      });

      group('Accessibility (a11y/Semantics)', () {
        Map<CustomSemanticsAction, VoidCallback> getSemanticsActions(int index) {
          final Semantics semantics = find.ancestor(
            of: find.byKey(Key(listItems[index])),
            matching: find.byType(Semantics),
          ).evaluate().first.widget as Semantics;
          return semantics.properties.customSemanticsActions!;
        }

        const CustomSemanticsAction moveToStart = CustomSemanticsAction(label: 'Move to the start');
        const CustomSemanticsAction moveToEnd = CustomSemanticsAction(label: 'Move to the end');
        const CustomSemanticsAction moveLeft = CustomSemanticsAction(label: 'Move left');
        const CustomSemanticsAction moveRight = CustomSemanticsAction(label: 'Move right');

        testWidgets('Provides the correct accessibility actions in LTR mode', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();

          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));

          // The first item can be moved right or to the end.
          final Map<CustomSemanticsAction, VoidCallback> firstSemanticsActions = getSemanticsActions(0);
          expect(firstSemanticsActions.length, 2, reason: 'The first list item should have 2 custom actions.');
          expect(firstSemanticsActions.containsKey(moveToStart), false, reason: 'The first item cannot `Move to the start`.');
          expect(firstSemanticsActions.containsKey(moveLeft), false, reason: 'The first item cannot `Move left`.');
          expect(firstSemanticsActions.containsKey(moveRight), true, reason: 'The first item should be able to `Move right`.');
          expect(firstSemanticsActions.containsKey(moveToEnd), true, reason: 'The first item should be able to `Move to the end`.');

          // Items in the middle can be moved to the start, end, left or right.
          for (int i = 1; i < listItems.length - 1; i += 1) {
            final Map<CustomSemanticsAction, VoidCallback> ithSemanticsActions = getSemanticsActions(i);
            expect(ithSemanticsActions.length, 4, reason: 'List item $i should have 4 custom actions.');
            expect(ithSemanticsActions.containsKey(moveToStart), true, reason: 'List item $i should be able to `Move to the start`.');
            expect(ithSemanticsActions.containsKey(moveLeft), true, reason: 'List item $i should be able to `Move left`.');
            expect(ithSemanticsActions.containsKey(moveRight), true, reason: 'List item $i should be able to `Move right`.');
            expect(ithSemanticsActions.containsKey(moveToEnd), true, reason: 'List item $i should be able to `Move to the end`.');
          }

          // The last item can be moved left or to the start.
          final Map<CustomSemanticsAction, VoidCallback> lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          expect(lastSemanticsActions.length, 2, reason: 'The last list item should have 2 custom actions.');
          expect(lastSemanticsActions.containsKey(moveToStart), true, reason: 'The last item should be able to `Move to the start`.');
          expect(lastSemanticsActions.containsKey(moveLeft), true, reason: 'The last item should be able to `Move left`.');
          expect(lastSemanticsActions.containsKey(moveRight), false, reason: 'The last item cannot `Move right`.');
          expect(lastSemanticsActions.containsKey(moveToEnd), false, reason: 'The last item cannot `Move to the end`.');
          handle.dispose();
        });

        testWidgets('Provides the correct accessibility actions in Right-To-Left directionality', (WidgetTester tester) async {
          // In RTL mode, the right is the start and the left is the end.
          // The array representation is unchanged (LTR), but the direction of the motion actions is reversed.
          final SemanticsHandle handle = tester.ensureSemantics();

          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));

          // The first item can be moved right or to the end.
          final Map<CustomSemanticsAction, VoidCallback> firstSemanticsActions = getSemanticsActions(0);
          expect(firstSemanticsActions.length, 2, reason: 'The first list item should have 2 custom actions.');
          expect(firstSemanticsActions.containsKey(moveToStart), false, reason: 'The first item cannot `Move to the start`.');
          expect(firstSemanticsActions.containsKey(moveRight), false, reason: 'The first item cannot `Move right`.');
          expect(firstSemanticsActions.containsKey(moveLeft), true, reason: 'The first item should be able to `Move left`.');
          expect(firstSemanticsActions.containsKey(moveToEnd), true, reason: 'The first item should be able to `Move to the end`.');

          // Items in the middle can be moved to the start, end, left or right.
          for (int i = 1; i < listItems.length - 1; i += 1) {
            final Map<CustomSemanticsAction, VoidCallback> ithSemanticsActions = getSemanticsActions(i);
            expect(ithSemanticsActions.length, 4, reason: 'List item $i should have 4 custom actions.');
            expect(ithSemanticsActions.containsKey(moveToStart), true, reason: 'List item $i should be able to `Move to the start`.');
            expect(ithSemanticsActions.containsKey(moveRight), true, reason: 'List item $i should be able to `Move right`.');
            expect(ithSemanticsActions.containsKey(moveLeft), true, reason: 'List item $i should be able to `Move left`.');
            expect(ithSemanticsActions.containsKey(moveToEnd), true, reason: 'List item $i should be able to `Move to the end`.');
          }

          // The last item can be moved left or to the start.
          final Map<CustomSemanticsAction, VoidCallback> lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          expect(lastSemanticsActions.length, 2, reason: 'The last list item should have 2 custom actions.');
          expect(lastSemanticsActions.containsKey(moveToStart), true, reason: 'The last item should be able to `Move to the start`.');
          expect(lastSemanticsActions.containsKey(moveRight), true, reason: 'The last item should be able to `Move right`.');
          expect(lastSemanticsActions.containsKey(moveLeft), false, reason: 'The last item cannot `Move left`.');
          expect(lastSemanticsActions.containsKey(moveToEnd), false, reason: 'The last item cannot `Move to the end`.');
          handle.dispose();
        });

        testWidgets('First item accessibility (a11y) actions work in LTR mode', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to end: move Item 1 to the end of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          Map<CustomSemanticsAction, VoidCallback> firstSemanticsActions = getSemanticsActions(0);
          firstSemanticsActions[moveToEnd]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));

          // Test out move after: move Item 2 (the current first item) one space to the right.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          firstSemanticsActions = getSemanticsActions(0);
          firstSemanticsActions[moveRight]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 3', 'Item 2', 'Item 4', 'Item 1']));

          handle.dispose();
        });

        testWidgets('First item accessibility (a11y) actions work in Right-To-Left directionality', (WidgetTester tester) async {
          // In RTL mode, the right is the start and the left is the end.
          // The array representation is unchanged (LTR), but the direction of the motion actions is reversed.
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to end: move Item 1 to the end of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          Map<CustomSemanticsAction, VoidCallback> firstSemanticsActions = getSemanticsActions(0);
          firstSemanticsActions[moveToEnd]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 2', 'Item 3', 'Item 4', 'Item 1']));

          // Test out move after: move Item 2 (the current first item) one space to the left.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          firstSemanticsActions = getSemanticsActions(0);
          firstSemanticsActions[moveLeft]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 3', 'Item 2', 'Item 4', 'Item 1']));

          handle.dispose();
        });

        testWidgets('Middle item accessibility (a11y) actions work in LTR mode', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to end: move Item 2 to the end of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          Map<CustomSemanticsAction, VoidCallback> middleSemanticsActions = getSemanticsActions(1);
          middleSemanticsActions[moveToEnd]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 4', 'Item 2']));

          // Test out move after: move Item 3 (the current second item) one space to the right.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          middleSemanticsActions = getSemanticsActions(1);
          middleSemanticsActions[moveRight]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 4', 'Item 3', 'Item 2']));

          // Test out move after: move Item 3 (the current third item) one space to the left.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          middleSemanticsActions = getSemanticsActions(2);
          middleSemanticsActions[moveLeft]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 4', 'Item 2']));

          // Test out move to start: move Item 4 (the current third item) to the start of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          middleSemanticsActions = getSemanticsActions(2);
          middleSemanticsActions[moveToStart]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 3', 'Item 2']));

          handle.dispose();
        });

        testWidgets('Middle item accessibility (a11y) actions work in Right-To-Left directionality', (WidgetTester tester) async {
          // In RTL mode, the right is the start and the left is the end.
          // The array representation is unchanged (LTR), but the direction of the motion actions is reversed.
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to end: move Item 2 to the end of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          Map<CustomSemanticsAction, VoidCallback> middleSemanticsActions = getSemanticsActions(1);
          middleSemanticsActions[moveToEnd]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 4', 'Item 2']));

          // Test out move after: move Item 3 (the current second item) one space to the left.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          middleSemanticsActions = getSemanticsActions(1);
          middleSemanticsActions[moveLeft]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 4', 'Item 3', 'Item 2']));

          // Test out move after: move Item 3 (the current third item) one space to the right.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          middleSemanticsActions = getSemanticsActions(2);
          middleSemanticsActions[moveRight]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 1', 'Item 3', 'Item 4', 'Item 2']));

          // Test out move to start: move Item 4 (the current third item) to the start of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          middleSemanticsActions = getSemanticsActions(2);
          middleSemanticsActions[moveToStart]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 3', 'Item 2']));

          handle.dispose();
        });

        testWidgets('Last item accessibility (a11y) actions work in LTR mode', (WidgetTester tester) async {
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to start: move Item 4 to the start of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          Map<CustomSemanticsAction, VoidCallback> lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          lastSemanticsActions[moveToStart]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 2', 'Item 3']));

          // Test out move before: move Item 3 (the current last item) one space to the left.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal));
          lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          lastSemanticsActions[moveLeft]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 3', 'Item 2']));

          handle.dispose();
        });

        testWidgets('Last item accessibility (a11y) actions work in Right-To-Left directionality', (WidgetTester tester) async {
          // In RTL mode, the right is the start and the left is the end.
          // The array representation is unchanged (LTR), but the direction of the motion actions is reversed.
          final SemanticsHandle handle = tester.ensureSemantics();
          expect(listItems, orderedEquals(originalListItems));

          // Test out move to start: move Item 4 to the start of the list.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          Map<CustomSemanticsAction, VoidCallback> lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          lastSemanticsActions[moveToStart]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 2', 'Item 3']));

          // Test out move before: move Item 3 (the current last item) one space to the right.
          await tester.pumpWidget(build(scrollDirection: Axis.horizontal, textDirection: TextDirection.rtl));
          lastSemanticsActions = getSemanticsActions(listItems.length - 1);
          lastSemanticsActions[moveRight]!();
          await tester.pumpAndSettle();
          expect(listItems, orderedEquals(<String>['Item 4', 'Item 1', 'Item 3', 'Item 2']));

          handle.dispose();
        });
      });

    });


    testWidgets('ReorderableListView.builder asserts on negative childCount', (WidgetTester tester) async {
      expect(() => ReorderableListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return const SizedBox();
        },
        itemCount: -1,
        onReorder: (int from, int to) {},
      ), throwsAssertionError);
    });

    testWidgets('ReorderableListView.builder only creates the children it needs', (WidgetTester tester) async {
      final Set<int> itemsCreated = <int>{};
      await tester.pumpWidget(MaterialApp(
        home: ReorderableListView.builder(
          itemBuilder: (BuildContext context, int index) {
            itemsCreated.add(index);
            return Text(index.toString(), key: ValueKey<int>(index));
          },
          itemCount: 1000,
          onReorder: (int from, int to) {},
        ),
      ));

      // Should have only created the first 18 items.
      expect(itemsCreated, <int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17});
    });

    group('Padding', () {
      testWidgets('Padding with no header & footer', (WidgetTester tester) async {
        const EdgeInsets padding = EdgeInsets.fromLTRB(10, 20, 30, 40);

        // Vertical
        await tester.pumpWidget(build(padding: padding));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 20, 770, 68));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(10, 164, 770, 212));

        // Horizontal
        await tester.pumpWidget(build(padding: padding, scrollDirection: Axis.horizontal));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 20, 58, 560));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(154, 20, 202, 560));
      });

      testWidgets('Padding with header or footer', (WidgetTester tester) async {
        const EdgeInsets padding = EdgeInsets.fromLTRB(10, 20, 30, 40);
        const Key headerKey = Key('Header');
        const Key footerKey = Key('Footer');
        const Widget verticalHeader = SizedBox(key: headerKey, height: 10);
        const Widget horizontalHeader = SizedBox(key: headerKey, width: 10);
        const Widget verticalFooter = SizedBox(key: footerKey, height: 10);
        const Widget horizontalFooter = SizedBox(key: footerKey, width: 10);

        // Vertical Header
        await tester.pumpWidget(build(padding: padding, header: verticalHeader));
        expect(tester.getRect(find.byKey(headerKey)), const Rect.fromLTRB(10, 20, 770, 30));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 30, 770, 78));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(10, 174, 770, 222));

        // Vertical Footer
        await tester.pumpWidget(build(padding: padding, footer: verticalFooter));
        expect(tester.getRect(find.byKey(footerKey)), const Rect.fromLTRB(10, 212, 770, 222));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 20, 770, 68));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(10, 164, 770, 212));

        // Vertical Header, reversed
        await tester.pumpWidget(build(padding: padding, header: verticalHeader, reverse: true));
        expect(tester.getRect(find.byKey(headerKey)), const Rect.fromLTRB(10, 550, 770, 560));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 502, 770, 550));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(10, 358, 770, 406));

        // Vertical Footer, reversed
        await tester.pumpWidget(build(padding: padding, footer: verticalFooter, reverse: true));
        expect(tester.getRect(find.byKey(footerKey)), const Rect.fromLTRB(10, 358, 770, 368));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 512, 770, 560));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(10, 368, 770, 416));

        // Horizontal Header
        await tester.pumpWidget(build(padding: padding, header: horizontalHeader, scrollDirection: Axis.horizontal));
        expect(tester.getRect(find.byKey(headerKey)), const Rect.fromLTRB(10, 20, 20, 560));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(20, 20, 68, 560));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(164, 20, 212, 560));

        // // Horizontal Footer
        await tester.pumpWidget(build(padding: padding, footer: horizontalFooter, scrollDirection: Axis.horizontal));
        expect(tester.getRect(find.byKey(footerKey)), const Rect.fromLTRB(202, 20, 212, 560));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(10, 20, 58, 560));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(154, 20, 202, 560));

        // Horizontal Header, reversed
        await tester.pumpWidget(build(padding: padding, header: horizontalHeader, scrollDirection: Axis.horizontal, reverse: true));
        expect(tester.getRect(find.byKey(headerKey)), const Rect.fromLTRB(760, 20, 770, 560));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(712, 20, 760, 560));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(568, 20, 616, 560));

        // // Horizontal Footer, reversed
        await tester.pumpWidget(build(padding: padding, footer: horizontalFooter, scrollDirection: Axis.horizontal, reverse: true));
        expect(tester.getRect(find.byKey(footerKey)), const Rect.fromLTRB(568, 20, 578, 560));
        expect(tester.getRect(find.byKey(const Key('Item 1'))), const Rect.fromLTRB(722, 20, 770, 560));
        expect(tester.getRect(find.byKey(const Key('Item 4'))), const Rect.fromLTRB(578, 20, 626, 560));
      });
    });

    testWidgets('ReorderableListView can be reversed', (WidgetTester tester) async {
      final Widget reorderableListView = ReorderableListView(
        reverse: true,
        onReorder: (int oldIndex, int newIndex) { },
        children: const <Widget>[
          SizedBox(
            key: Key('A'),
            child: Text('A'),
          ),
          SizedBox(
            key: Key('B'),
            child: Text('B'),
          ),
          SizedBox(
            key: Key('C'),
            child: Text('C'),
          ),
        ],
      );
      await tester.pumpWidget(MaterialApp(
        home: reorderableListView,
      ));
      expect(tester.getCenter(find.text('A')).dy, greaterThan(tester.getCenter(find.text('B')).dy));
    });

    testWidgets('Animation test when placing an item in place', (WidgetTester tester) async {
      const Key testItemKey = Key('Test item');
      final Widget reorderableListView = ReorderableListView(
        onReorder: (int oldIndex, int newIndex) { },
        children: const <Widget>[
          SizedBox(
            key: Key('First item'),
            height: itemHeight,
            child: Text('First item'),
          ),
          SizedBox(
            key: testItemKey,
            height: itemHeight,
            child: Text('Test item'),
          ),
          SizedBox(
            key: Key('Last item'),
            height: itemHeight,
            child: Text('Last item'),
          ),
        ],
      );
      await tester.pumpWidget(MaterialApp(
        home: SizedBox(
          height: itemHeight * 10,
          child: reorderableListView,
        ),
      ));

      Offset getTestItemPosition() {
        final RenderBox testItem = tester.renderObject<RenderBox>(find.byKey(testItemKey));
        return testItem.localToGlobal(Offset.zero);
      }
      // Before pick it up.
      final Offset startPosition = getTestItemPosition();

      // Pick it up.
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(testItemKey)));
      await tester.pump(kLongPressTimeout + kPressTimeout);
      expect(getTestItemPosition(), startPosition);

      // Put it down.
      await gesture.up();
      await tester.pump();
      expect(getTestItemPosition(), startPosition);

      // After put it down.
      await tester.pumpAndSettle();
      expect(getTestItemPosition(), startPosition);
    });
    // TODO(djshuckerow): figure out how to write a test for scrolling the list.

    testWidgets('ReorderableListView on desktop platforms should have drag handles', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      // All four items should have drag handles and not delayed listeners.
      expect(find.byIcon(Icons.drag_handle), findsNWidgets(4));
      expect(find.byType(ReorderableDelayedDragStartListener), findsNothing);
    }, variant: TargetPlatformVariant.desktop());

    testWidgets('ReorderableListView on mobile platforms should not have drag handles', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      // All four items should have delayed listeners and not drag handles.
      expect(find.byType(ReorderableDelayedDragStartListener), findsNWidgets(4));
      expect(find.byIcon(Icons.drag_handle), findsNothing);
    }, variant: TargetPlatformVariant.mobile());

    testWidgets('Vertical list renders drag handle in correct position', (WidgetTester tester) async {
      await tester.pumpWidget(build(platform: TargetPlatform.macOS));
      final Finder listView = find.byType(ReorderableListView);
      final Finder item1 = find.byKey(const Key('Item 1'));
      final Finder dragHandle = find.byIcon(Icons.drag_handle).first;

      // Should be centered vertically within the item and 8 pixels from the right edge of the list.
      expect(tester.getCenter(dragHandle).dy, tester.getCenter(item1).dy);
      expect(tester.getTopRight(dragHandle).dx, tester.getSize(listView).width - 8);
    });

    testWidgets('Horizontal list renders drag handle in correct position', (WidgetTester tester) async {
      await tester.pumpWidget(build(scrollDirection: Axis.horizontal, platform: TargetPlatform.macOS));
      final Finder listView = find.byType(ReorderableListView);
      final Finder item1 = find.byKey(const Key('Item 1'));
      final Finder dragHandle = find.byIcon(Icons.drag_handle).first;

      // Should be centered horizontally within the item and 8 pixels from the bottom of the list.
      expect(tester.getCenter(dragHandle).dx, tester.getCenter(item1).dx);
      expect(tester.getBottomRight(dragHandle).dy, tester.getSize(listView).height - 8);
    });
  });

  testWidgets('ReorderableListView, can deal with the dragged item getting unmounted and rebuilt during drag', (WidgetTester tester) async {
    // See https://github.com/flutter/flutter/issues/74840 for more details.
    final List<int> items = List<int>.generate(100, (int index) => index);

    void handleReorder(int fromIndex, int toIndex) {
      if (toIndex > fromIndex) {
        toIndex -= 1;
      }
      items.insert(toIndex, items.removeAt(fromIndex));
    }

    // The list is 800x600, 8 items, each item is 800x100 with
    // an "item $index" text widget at the item's origin.  Drags are initiated by
    // a simple press on the text widget.
    await tester.pumpWidget(MaterialApp(
      home: ReorderableListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return SizedBox(
            key: ValueKey<int>(items[index]),
            height: 100,
            child: ReorderableDragStartListener(
              index: index,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text('item ${items[index]}'),
                ],
              ),
            ),
          );
        },
        itemCount: items.length,
        onReorder: handleReorder,
      ),
    ));

    // Drag item 0 downwards and force an auto scroll off the end of the list
    // far enough that item zeros original entry in the list is unmounted.
    final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('item 0')));
    await tester.pump(kPressTimeout);
    // Off the bottom of the screen, which should autoscroll until we hit the
    // end of the list
    await drag.moveBy(const Offset(0, 700));
    await tester.pump(const Duration(seconds: 30));
    await tester.pumpAndSettle();
    // Ensure we made it to the bottom (only 4 should be showing as there should
    // be a gap at the end for the drop area of the dragged item.
    for (final int i in <int>[95, 96, 97, 98, 99]) {
      expect(find.text('item $i'), findsOneWidget);
    }

    // Drag back to off the top of the list, which should autoscroll until
    // we hit the beginning of the list. This should cause the first item's
    // entry to be rebuilt. However, the contents should not be in both places.
    await drag.moveBy(const Offset(0, -1400));
    await tester.pump(const Duration(seconds: 30));
    await tester.pumpAndSettle();
    // Release back at the top so item 0 should drop where it was
    await drag.up();
    await tester.pumpAndSettle();

    // Should not have changed anything
    for (final int i in <int>[0, 1, 2, 3, 4, 5]) {
      expect(find.text('item $i'), findsOneWidget);
    }
    expect(items.take(8), orderedEquals(<int>[0, 1, 2, 3, 4, 5, 6, 7]));
  });

  testWidgets('ReorderableListView calls onReorderStart and onReorderEnd correctly', (WidgetTester tester) async {
    final List<int> items = List<int>.generate(8, (int index) => index);
    int? startIndex, endIndex;
    final Finder item0 = find.textContaining('item 0');

    void handleReorder(int fromIndex, int toIndex) {
      if (toIndex > fromIndex) {
        toIndex -= 1;
      }
      items.insert(toIndex, items.removeAt(fromIndex));
    }

    await tester.pumpWidget(MaterialApp(
      home: ReorderableListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return SizedBox(
            key: ValueKey<int>(items[index]),
            height: 100,
            child: ReorderableDragStartListener(
              index: index,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text('item ${items[index]}'),
                ],
              ),
            ),
          );
        },
        itemCount: items.length,
        onReorder: handleReorder,
        onReorderStart: (int index) {
          startIndex = index;
        },
        onReorderEnd: (int index) {
          endIndex = index;
        },
      ),
    ));

    TestGesture drag = await tester.startGesture(tester.getCenter(item0));
    await tester.pump(kPressTimeout);
    // Drag enough for move to start.
    await drag.moveBy(const Offset(0, 20));

    expect(startIndex, equals(0));
    expect(endIndex, isNull);

    // Move item0 from index 0 to index 3
    await drag.moveBy(const Offset(0, 300));
    await tester.pumpAndSettle();
    await drag.up();
    await tester.pumpAndSettle();

    expect(endIndex, equals(3));

    startIndex = null;
    endIndex = null;

    drag = await tester.startGesture(tester.getCenter(item0));
    await tester.pump(kPressTimeout);
    // Drag enough for move to start.
    await drag.moveBy(const Offset(0, 20));

    expect(startIndex, equals(2));
    expect(endIndex, isNull);

    // Move item0 from index 2 to index 0
    await drag.moveBy(const Offset(0, -200));
    await tester.pumpAndSettle();
    await drag.up();
    await tester.pumpAndSettle();

    expect(endIndex, equals(0));
  });

  testWidgets('ReorderableListView throws an error when key is not passed to its children', (WidgetTester tester) async {
    final Widget reorderableListView = ReorderableListView.builder(
      itemBuilder: (BuildContext context, int index) {
        return SizedBox(child: Text('Item $index'));
      },
      itemCount: 3,
      onReorder: (int oldIndex, int newIndex) { },
    );
    await tester.pumpWidget(MaterialApp(
      home: reorderableListView,
    ));
    final dynamic exception = tester.takeException();
    expect(exception, isFlutterError);
    expect(exception.toString(), contains('Every item of ReorderableListView must have a key.'));
  });

  testWidgets('Throws an error if no overlay present', (WidgetTester tester) async {
    final Widget reorderableList = ReorderableListView(
      children: const <Widget>[
        SizedBox(width: 100.0, height: 100.0, key: Key('C'), child: Text('C')),
        SizedBox(width: 100.0, height: 100.0, key: Key('B'), child: Text('B')),
        SizedBox(width: 100.0, height: 100.0, key: Key('A'), child: Text('A')),
      ],
      onReorder: (int oldIndex, int newIndex) { },
    );
    final Widget boilerplate = Localizations(
      locale: const Locale('en'),
      delegates: const <LocalizationsDelegate<dynamic>>[
        DefaultMaterialLocalizations.delegate,
        DefaultWidgetsLocalizations.delegate,
      ],
      child:SizedBox(
        width: 100.0,
        height: 100.0,
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: reorderableList,
        ),
      ),
    );
    await tester.pumpWidget(boilerplate);

    final dynamic exception = tester.takeException();
    expect(exception, isFlutterError);
    expect(exception.toString(), contains('No Overlay widget found'));
    expect(exception.toString(), contains('ReorderableListView widgets require an Overlay widget ancestor'));
  });

  testWidgets('ReorderableListView asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
    expect(() => ReorderableListView(
      itemExtent: 30,
      prototypeItem: const SizedBox(),
      onReorder: (int fromIndex, int toIndex) { },
      children: const <Widget>[],
    ), throwsAssertionError);
  });

  testWidgets('ReorderableListView.builder asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
    final List<int> numbers = <int>[0,1,2];
    expect(() => ReorderableListView.builder(
      itemBuilder: (BuildContext context, int index) {
        return SizedBox(
            key: ValueKey<int>(numbers[index]),
            height: 20 + numbers[index] * 10,
            child: ReorderableDragStartListener(
              index: index,
              child: Text(numbers[index].toString()),
            )
        );
      },
      itemCount: numbers.length,
      itemExtent: 30,
      prototypeItem: const SizedBox(),
      onReorder: (int fromIndex, int toIndex) { },
    ), throwsAssertionError);
  });

  testWidgets('if itemExtent is non-null, children have same extent in the scroll direction', (WidgetTester tester) async {
    final List<int> numbers = <int>[0,1,2];

    await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return ReorderableListView.builder(
                  itemBuilder: (BuildContext context, int index) {
                    return SizedBox(
                        key: ValueKey<int>(numbers[index]),
                        // children with different heights
                        height: 20 + numbers[index] * 10,
                        child: ReorderableDragStartListener(
                          index: index,
                          child: Text(numbers[index].toString()),
                        )
                    );
                  },
                  itemCount: numbers.length,
                  itemExtent: 30,
                  onReorder: (int fromIndex, int toIndex) { },
                );
              },
            ),
          ),
        )
    );

    final double item0Height = tester.getSize(find.text('0').hitTestable()).height;
    final double item1Height = tester.getSize(find.text('1').hitTestable()).height;
    final double item2Height = tester.getSize(find.text('2').hitTestable()).height;

    expect(item0Height, 30.0);
    expect(item1Height, 30.0);
    expect(item2Height, 30.0);
  });

  testWidgets('if prototypeItem is non-null, children have same extent in the scroll direction', (WidgetTester tester) async {
    final List<int> numbers = <int>[0,1,2];

    await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return ReorderableListView.builder(
                  itemBuilder: (BuildContext context, int index) {
                    return SizedBox(
                        key: ValueKey<int>(numbers[index]),
                        // children with different heights
                        height: 20 + numbers[index] * 10,
                        child: ReorderableDragStartListener(
                          index: index,
                          child: Text(numbers[index].toString()),
                        )
                    );
                  },
                  itemCount: numbers.length,
                  prototypeItem: const SizedBox(
                    height: 30,
                    child: Text('3'),
                  ),
                  onReorder: (int oldIndex, int newIndex) {  },
                );
              },
            ),
          ),
        )
    );

    final double item0Height = tester.getSize(find.text('0').hitTestable()).height;
    final double item1Height = tester.getSize(find.text('1').hitTestable()).height;
    final double item2Height = tester.getSize(find.text('2').hitTestable()).height;

    expect(item0Height, 30.0);
    expect(item1Height, 30.0);
    expect(item2Height, 30.0);
  });
}

Future<void> longPressDrag(WidgetTester tester, Offset start, Offset end) async {
  final TestGesture drag = await tester.startGesture(start);
  await tester.pump(kLongPressTimeout + kPressTimeout);
  await drag.moveTo(end);
  await tester.pump(kPressTimeout);
  await drag.up();
}

class _Stateful extends StatefulWidget {
  // Ignoring the preference for const constructors because we want to test with regular non-const instances.
  // ignore:prefer_const_constructors_in_immutables
  _Stateful({super.key});

  @override
  State<StatefulWidget> createState() => _StatefulState();
}

class _StatefulState extends State<_Stateful> {
  bool? checked = false;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 48.0,
      height: 48.0,
      child: Material(
        child: Checkbox(
          value: checked,
          onChanged: (bool? newValue) => checked = newValue,
        ),
      ),
    );
  }
}
