Replace Long by Timestamp

This commit is contained in:
2017-07-22 11:01:35 -04:00
parent 882ddba324
commit a8aa6f192c
80 changed files with 672 additions and 526 deletions

View File

@@ -96,7 +96,7 @@ public class CommandParserTest extends BaseUnitTest
public void testDecodeCreateRepCommand() throws JSONException
{
CreateRepetitionCommand original, decoded;
original = new CreateRepetitionCommand(habit, 1000, 5);
original = new CreateRepetitionCommand(habit, Timestamp.ZERO.plus(100), 5);
decoded = (CreateRepetitionCommand) parser.parse(original.toJson());
MatcherAssert.assertThat(decoded.getId(), equalTo(original.getId()));
@@ -140,7 +140,8 @@ public class CommandParserTest extends BaseUnitTest
public void testDecodeToggleCommand() throws JSONException
{
ToggleRepetitionCommand original, decoded;
original = new ToggleRepetitionCommand(habitList, habit, 1000);
original = new ToggleRepetitionCommand(habitList, habit,
Timestamp.ZERO.plus(100));
decoded = (ToggleRepetitionCommand) parser.parse(original.toJson());
MatcherAssert.assertThat(decoded.getId(), equalTo(original.getId()));

View File

@@ -35,7 +35,7 @@ public class CreateRepetitionCommandTest extends BaseUnitTest
private Habit habit;
private long today;
private Timestamp today;
@Override
@Before
@@ -46,7 +46,7 @@ public class CreateRepetitionCommandTest extends BaseUnitTest
habit = fixtures.createShortHabit();
habitList.add(habit);
today = DateUtils.getStartOfToday();
today = DateUtils.getToday();
command = new CreateRepetitionCommand(habit, today, 100);
}

View File

@@ -33,7 +33,7 @@ public class ToggleRepetitionCommandTest extends BaseUnitTest
private ToggleRepetitionCommand command;
private Habit habit;
private long today;
private Timestamp today;
@Override
@Before
@@ -44,7 +44,7 @@ public class ToggleRepetitionCommandTest extends BaseUnitTest
habit = fixtures.createShortHabit();
habitList.add(habit);
today = DateUtils.getStartOfToday();
today = DateUtils.getToday();
command = new ToggleRepetitionCommand(habitList, habit, today);
}

View File

@@ -121,7 +121,7 @@ public class ImportTest extends BaseUnitTest
{
GregorianCalendar date = DateUtils.getStartOfTodayCalendar();
date.set(year, month - 1, day);
return h.getRepetitions().containsTimestamp(date.getTimeInMillis());
return h.getRepetitions().containsTimestamp(new Timestamp(date));
}
private void importFromFile(String assetFilename) throws IOException

View File

@@ -28,9 +28,7 @@ import java.util.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.IsEqual.*;
import static org.isoron.uhabits.core.models.Checkmark.CHECKED_EXPLICITLY;
import static org.isoron.uhabits.core.models.Checkmark.CHECKED_IMPLICITLY;
import static org.isoron.uhabits.core.models.Checkmark.UNCHECKED;
import static org.isoron.uhabits.core.models.Checkmark.*;
public class CheckmarkListTest extends BaseUnitTest
{
@@ -49,9 +47,6 @@ public class CheckmarkListTest extends BaseUnitTest
{
super.setUp();
dayLength = DateUtils.millisecondsInOneDay;
today = DateUtils.getStartOfToday();
nonDailyHabit = fixtures.createShortHabit();
habitList.add(nonDailyHabit);
@@ -281,7 +276,9 @@ public class CheckmarkListTest extends BaseUnitTest
@Test
public void test_getValues_withInvalidInterval()
{
int values[] = nonDailyHabit.getCheckmarks().getValues(100L, -100L);
int values[] = nonDailyHabit
.getCheckmarks()
.getValues(new Timestamp(0L).plus(100), new Timestamp(0L));
assertThat(values, equalTo(new int[0]));
}
@@ -305,7 +302,9 @@ public class CheckmarkListTest extends BaseUnitTest
UNCHECKED
};
int[] actualValues = nonDailyHabit.getCheckmarks().getValues(from, to);
int[] actualValues = nonDailyHabit
.getCheckmarks()
.getValues(new Timestamp(from), new Timestamp(to));
assertThat(actualValues, equalTo(expectedValues));
}
@@ -344,15 +343,14 @@ public class CheckmarkListTest extends BaseUnitTest
assertThat(writer.toString(), equalTo(expectedCSV));
}
private long day(int offset)
private Timestamp day(int offset)
{
return DateUtils.getStartOfToday() -
offset * DateUtils.millisecondsInOneDay;
return DateUtils.getToday().minus(offset);
}
private void travelInTime(int days)
{
DateUtils.setFixedLocalTime(
FIXED_LOCAL_TIME + days * DateUtils.millisecondsInOneDay);
FIXED_LOCAL_TIME + days * Timestamp.DAY_LENGTH);
}
}

View File

@@ -87,7 +87,7 @@ public class HabitTest extends BaseUnitTest
{
Habit h = modelFactory.buildHabit();
assertFalse(h.isCompletedToday());
h.getRepetitions().toggle(getStartOfToday());
h.getRepetitions().toggle(getToday());
assertTrue(h.isCompletedToday());
}
@@ -100,19 +100,19 @@ public class HabitTest extends BaseUnitTest
h.setTargetValue(100.0);
assertFalse(h.isCompletedToday());
h.getRepetitions().toggle(getStartOfToday(), 200);
h.getRepetitions().toggle(getToday(), 200);
assertTrue(h.isCompletedToday());
h.getRepetitions().toggle(getStartOfToday(), 100);
h.getRepetitions().toggle(getToday(), 100);
assertTrue(h.isCompletedToday());
h.getRepetitions().toggle(getStartOfToday(), 50);
h.getRepetitions().toggle(getToday(), 50);
assertFalse(h.isCompletedToday());
h.setTargetType(Habit.AT_MOST);
h.getRepetitions().toggle(getStartOfToday(), 200);
h.getRepetitions().toggle(getToday(), 200);
assertFalse(h.isCompletedToday());
h.getRepetitions().toggle(getStartOfToday(), 100);
h.getRepetitions().toggle(getToday(), 100);
assertTrue(h.isCompletedToday());
h.getRepetitions().toggle(getStartOfToday(), 50);
h.getRepetitions().toggle(getToday(), 50);
assertTrue(h.isCompletedToday());
}

View File

@@ -29,7 +29,6 @@ import java.util.*;
import static junit.framework.TestCase.assertFalse;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.*;
import static org.hamcrest.core.IsEqual.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -43,7 +42,7 @@ public class RepetitionListTest extends BaseUnitTest
@NonNull
private Habit habit;
private long today;
private Timestamp today;
private long day;
@@ -58,14 +57,13 @@ public class RepetitionListTest extends BaseUnitTest
habit = fixtures.createEmptyHabit();
reps = habit.getRepetitions();
today = DateUtils.getStartOfToday();
day = DateUtils.millisecondsInOneDay;
today = DateUtils.getToday();
reps.toggle(today - 3 * day);
reps.toggle(today - 2 * day);
reps.toggle(today.minus(3));
reps.toggle(today.minus(2));
reps.toggle(today);
reps.toggle(today - 7 * day);
reps.toggle(today - 5 * day);
reps.toggle(today.minus(7));
reps.toggle(today.minus(5));
listener = mock(ModelObservable.Listener.class);
reps.getObservable().addListener(listener);
@@ -82,19 +80,19 @@ public class RepetitionListTest extends BaseUnitTest
@Test
public void test_contains()
{
assertThat(reps.containsTimestamp(today), is(true));
assertThat(reps.containsTimestamp(today - 2 * day), is(true));
assertThat(reps.containsTimestamp(today - 3 * day), is(true));
assertTrue(reps.containsTimestamp(today));
assertTrue(reps.containsTimestamp(today.minus(2)));
assertTrue(reps.containsTimestamp(today.minus(3)));
assertThat(reps.containsTimestamp(today - day), is(false));
assertThat(reps.containsTimestamp(today - 4 * day), is(false));
assertFalse(reps.containsTimestamp(today.minus(1)));
assertFalse(reps.containsTimestamp(today.minus(4)));
}
@Test
public void test_getOldest()
{
Repetition rep = reps.getOldest();
assertThat(rep.getTimestamp(), is(equalTo(today - 7 * day)));
assertThat(rep.getTimestamp(), equalTo(today.minus(7)));
}
@Test
@@ -134,28 +132,28 @@ public class RepetitionListTest extends BaseUnitTest
weekdayCount[month][week]++;
monthCount[month]++;
}
reps.toggle(day.getTimeInMillis());
reps.toggle(new Timestamp(day));
}
}
day.add(Calendar.DAY_OF_YEAR, 1);
}
HashMap<Long, Integer[]> freq =
HashMap<Timestamp, Integer[]> freq =
reps.getWeekdayFrequency();
// Repetitions until November should be counted correctly
for (int month = 0; month < 11; month++)
{
day.set(2015, month, 1);
Integer actualCount[] = freq.get(day.getTimeInMillis());
Integer actualCount[] = freq.get(new Timestamp(day));
if (monthCount[month] == 0) assertThat(actualCount, equalTo(null));
else assertThat(actualCount, equalTo(weekdayCount[month]));
}
// Repetitions in December should be discarded
day.set(2015, 11, 1);
assertThat(freq.get(day.getTimeInMillis()), equalTo(null));
assertThat(freq.get(new Timestamp(day)), equalTo(null));
}
@Test
@@ -167,9 +165,9 @@ public class RepetitionListTest extends BaseUnitTest
verify(listener).onModelChange();
reset(listener);
assertFalse(reps.containsTimestamp(today - day));
reps.toggle(today - day);
assertTrue(reps.containsTimestamp(today - day));
assertFalse(reps.containsTimestamp(today.minus(1)));
reps.toggle(today.minus(1));
assertTrue(reps.containsTimestamp(today.minus(1)));
verify(listener).onModelChange();
reset(listener);

View File

@@ -117,11 +117,11 @@ public class ScoreListTest extends BaseUnitTest
};
ScoreList scores = habit.getScores();
long current = DateUtils.getStartOfToday();
Timestamp current = DateUtils.getToday();
for (double expectedValue : expectedValues)
{
assertThat(scores.getValue(current), closeTo(expectedValue, E));
current -= DateUtils.millisecondsInOneDay;
current = current.minus(1);
}
}
@@ -130,11 +130,9 @@ public class ScoreListTest extends BaseUnitTest
{
toggleRepetitions(0, 20);
long today = DateUtils.getStartOfToday();
long day = DateUtils.millisecondsInOneDay;
long from = today - 4 * day;
long to = today - 2 * day;
Timestamp today = DateUtils.getToday();
Timestamp from = today.minus(4);
Timestamp to = today.minus(2);
double[] expected = {
0.617008, 0.596033, 0.573909,
@@ -169,7 +167,7 @@ public class ScoreListTest extends BaseUnitTest
assertThat(habit.getScores().getTodayValue(), closeTo(0.101149, E));
habit.setFrequency(new Frequency(1, 2));
habit.getScores().invalidateNewerThan(0);
habit.getScores().invalidateNewerThan(new Timestamp(0));
assertThat(habit.getScores().getTodayValue(), closeTo(0.051922, E));
}
@@ -194,10 +192,9 @@ public class ScoreListTest extends BaseUnitTest
private void toggleRepetitions(final int from, final int to)
{
RepetitionList reps = habit.getRepetitions();
long today = DateUtils.getStartOfToday();
long day = DateUtils.millisecondsInOneDay;
Timestamp today = DateUtils.getToday();
for (int i = from; i < to; i++)
reps.toggle(today - i * day);
reps.toggle(today.minus(i));
}
}

View File

@@ -38,7 +38,7 @@ public class StreakListTest extends BaseUnitTest
private long day;
private long today;
private Timestamp today;
private ModelObservable.Listener listener;
@@ -54,25 +54,23 @@ public class StreakListTest extends BaseUnitTest
listener = mock(ModelObservable.Listener.class);
streaks.getObservable().addListener(listener);
today = DateUtils.getStartOfToday();
day = DateUtils.millisecondsInOneDay;
today = DateUtils.getToday();
}
@Test
public void testFindBeginning_withEmptyHistory()
{
Habit habit2 = fixtures.createEmptyHabit();
Long beginning = habit2.getStreaks().findBeginning();
assertThat(beginning, is(nullValue()));
Timestamp beginning = habit2.getStreaks().findBeginning();
assertNull(beginning);
}
@Test
public void testFindBeginning_withLongHistory()
{
streaks.rebuild();
streaks.invalidateNewerThan(0);
assertThat(streaks.findBeginning(), equalTo(today - 120 * day));
streaks.invalidateNewerThan(new Timestamp(0));
assertThat(streaks.findBeginning(), equalTo(today.minus(120)));
}
@Test
@@ -82,11 +80,11 @@ public class StreakListTest extends BaseUnitTest
assertThat(all.size(), equalTo(22));
assertThat(all.get(3).getEnd(), equalTo(today - 7 * day));
assertThat(all.get(3).getStart(), equalTo(today - 10 * day));
assertThat(all.get(3).getEnd(), equalTo(today.minus(7)));
assertThat(all.get(3).getStart(), equalTo(today.minus(10)));
assertThat(all.get(17).getEnd(), equalTo(today - 89 * day));
assertThat(all.get(17).getStart(), equalTo(today - 91 * day));
assertThat(all.get(17).getEnd(), equalTo(today.minus(89)));
assertThat(all.get(17).getStart(), equalTo(today.minus(91)));
}
@Test
@@ -95,16 +93,16 @@ public class StreakListTest extends BaseUnitTest
List<Streak> best = streaks.getBest(4);
assertThat(best.size(), equalTo(4));
assertThat(best.get(0).getLength(), equalTo(4L));
assertThat(best.get(1).getLength(), equalTo(3L));
assertThat(best.get(2).getLength(), equalTo(5L));
assertThat(best.get(3).getLength(), equalTo(6L));
assertThat(best.get(0).getLength(), equalTo(4));
assertThat(best.get(1).getLength(), equalTo(3));
assertThat(best.get(2).getLength(), equalTo(5));
assertThat(best.get(3).getLength(), equalTo(6));
best = streaks.getBest(2);
assertThat(best.size(), equalTo(2));
assertThat(best.get(0).getLength(), equalTo(5L));
assertThat(best.get(1).getLength(), equalTo(6L));
assertThat(best.get(0).getLength(), equalTo(5));
assertThat(best.get(1).getLength(), equalTo(6));
}
@Test
@@ -113,7 +111,7 @@ public class StreakListTest extends BaseUnitTest
Streak s = streaks.getNewestComputed();
assertThat(s.getEnd(), equalTo(today));
streaks.invalidateNewerThan(today - 8 * day);
streaks.invalidateNewerThan(today.minus(8));
verify(listener).onModelChange();
s = streaks.getNewestComputed();

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2015-2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.models;
import org.isoron.uhabits.core.*;
import org.isoron.uhabits.core.utils.*;
import org.junit.*;
import static junit.framework.TestCase.assertFalse;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertTrue;
public class TimestampTest extends BaseUnitTest
{
@Test
public void testCompare() throws Exception
{
Timestamp t1 = DateUtils.getToday();
Timestamp t2 = t1.minus(1);
Timestamp t3 = t1.plus(3);
assertThat(t1.compare(t2), greaterThan(0));
assertThat(t1.compare(t1), equalTo(0));
assertThat(t1.compare(t3), lessThan(0));
assertTrue(t1.isNewerThan(t2));
assertFalse(t1.isNewerThan(t1));
assertFalse(t2.isNewerThan(t1));
assertTrue(t2.isOlderThan(t1));
assertFalse(t1.isOlderThan(t2));
}
@Test
public void testDaysUntil() throws Exception
{
Timestamp t = DateUtils.getToday();
assertThat(t.daysUntil(t), equalTo(0));
assertThat(t.daysUntil(t.plus(1)), equalTo(1));
assertThat(t.daysUntil(t.plus(3)), equalTo(3));
assertThat(t.daysUntil(t.plus(300)), equalTo(300));
assertThat(t.daysUntil(t.minus(1)), equalTo(-1));
assertThat(t.daysUntil(t.minus(3)), equalTo(-3));
assertThat(t.daysUntil(t.minus(300)), equalTo(-300));
}
}

View File

@@ -31,17 +31,16 @@ import org.junit.*;
import java.util.*;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.IsEqual.*;
import static org.isoron.uhabits.core.models.Checkmark.CHECKED_EXPLICITLY;
import static org.isoron.uhabits.core.models.Checkmark.*;
public class SQLiteRepetitionListTest extends BaseUnitTest
{
private Habit habit;
private long today;
private Timestamp today;
private RepetitionList repetitions;
@@ -62,20 +61,19 @@ public class SQLiteRepetitionListTest extends BaseUnitTest
habit = fixtures.createLongHabit();
repetitions = habit.getRepetitions();
today = DateUtils.getStartOfToday();
day = DateUtils.millisecondsInOneDay;
today = DateUtils.getToday();
}
@Test
public void testAdd()
{
RepetitionRecord record = getByTimestamp(today + day);
RepetitionRecord record = getByTimestamp(today.plus(1));
assertNull(record);
Repetition rep = new Repetition(today + day, CHECKED_EXPLICITLY);
Repetition rep = new Repetition(today.plus(1), CHECKED_EXPLICITLY);
habit.getRepetitions().add(rep);
record = getByTimestamp(today + day);
record = getByTimestamp(today.plus(1));
assertNotNull(record);
assertThat(record.value, equalTo(CHECKED_EXPLICITLY));
}
@@ -84,12 +82,12 @@ public class SQLiteRepetitionListTest extends BaseUnitTest
public void testGetByInterval()
{
List<Repetition> reps =
repetitions.getByInterval(today - 10 * day, today);
repetitions.getByInterval(today.minus(10), today);
assertThat(reps.size(), equalTo(8));
assertThat(reps.get(0).getTimestamp(), equalTo(today - 10 * day));
assertThat(reps.get(4).getTimestamp(), equalTo(today - 5 * day));
assertThat(reps.get(5).getTimestamp(), equalTo(today - 3 * day));
assertThat(reps.get(0).getTimestamp(), equalTo(today.minus(10)));
assertThat(reps.get(4).getTimestamp(), equalTo(today.minus(5)));
assertThat(reps.get(5).getTimestamp(), equalTo(today.minus(3)));
}
@Test
@@ -99,7 +97,7 @@ public class SQLiteRepetitionListTest extends BaseUnitTest
assertNotNull(rep);
assertThat(rep.getTimestamp(), equalTo(today));
rep = repetitions.getByTimestamp(today - 2 * day);
rep = repetitions.getByTimestamp(today.minus(2));
assertNull(rep);
}
@@ -108,7 +106,7 @@ public class SQLiteRepetitionListTest extends BaseUnitTest
{
Repetition rep = repetitions.getOldest();
assertNotNull(rep);
assertThat(rep.getTimestamp(), equalTo(today - 120 * day));
assertThat(rep.getTimestamp(), equalTo(today.minus(120)));
}
@Test
@@ -133,11 +131,11 @@ public class SQLiteRepetitionListTest extends BaseUnitTest
}
@Nullable
private RepetitionRecord getByTimestamp(long timestamp)
private RepetitionRecord getByTimestamp(Timestamp timestamp)
{
String query = "where habit = ? and timestamp = ?";
String params[] = {
Long.toString(habit.getId()), Long.toString(timestamp)
Long.toString(habit.getId()), Long.toString(timestamp.getUnixTime())
};
return repository.findFirst(query, params);

View File

@@ -33,7 +33,7 @@ public class RepetitionRecordTest extends BaseUnitTest
@Test
public void testRecord() throws Exception
{
Repetition rep = new Repetition(2000L, 50);
Repetition rep = new Repetition(Timestamp.ZERO.plus(100), 50);
RepetitionRecord record = new RepetitionRecord();
record.copyFrom(rep);
assertThat(rep, equalTo(record.toRepetition()));

View File

@@ -85,7 +85,7 @@ public class HabitCardListCacheTest extends BaseUnitTest
public void testCommandListener_single()
{
Habit h2 = habitList.getByPosition(2);
long today = DateUtils.getStartOfToday();
Timestamp today = DateUtils.getToday();
commandRunner.execute(new ToggleRepetitionCommand(habitList, h2, today),
h2.getId());
@@ -106,12 +106,10 @@ public class HabitCardListCacheTest extends BaseUnitTest
assertThat(cache.getHabitByPosition(3), equalTo(h));
assertThat(cache.getScore(h.getId()), equalTo(score));
long today = DateUtils.getStartOfToday();
long day = DateUtils.millisecondsInOneDay;
Timestamp today = DateUtils.getToday();
int[] actualCheckmarks = cache.getCheckmarks(h.getId());
int[] expectedCheckmarks =
h.getCheckmarks().getValues(today - 9 * day, today);
h.getCheckmarks().getValues(today.minus(9), today);
assertThat(actualCheckmarks, equalTo(expectedCheckmarks));
}

View File

@@ -20,6 +20,7 @@
package org.isoron.uhabits.core.ui.screens.habits.list;
import org.isoron.uhabits.core.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.utils.*;
import org.junit.*;
@@ -41,16 +42,16 @@ public class HintListTest extends BaseUnitTest
@Mock
private Preferences prefs;
private long today;
private Timestamp today;
private long yesterday;
private Timestamp yesterday;
@Override
public void setUp() throws Exception
{
super.setUp();
today = DateUtils.getStartOfToday();
yesterday = today - DateUtils.millisecondsInOneDay;
today = DateUtils.getToday();
yesterday = today.minus(1);
hints = new String[]{ "hint1", "hint2", "hint3" };
hintList = new HintList(prefs, hints);

View File

@@ -83,7 +83,7 @@ public class ListHabitsBehaviorTest extends BaseUnitTest
@Test
public void testOnEdit()
{
behavior.onEdit(habit2, DateUtils.getStartOfToday());
behavior.onEdit(habit2, DateUtils.getToday());
verify(screen).showNumberPicker(eq(0.1), eq("miles"), picker.capture());
picker.getValue().onNumberPicked(100);
assertThat(habit2.getCheckmarks().getTodayValue(), equalTo(100000));
@@ -173,7 +173,7 @@ public class ListHabitsBehaviorTest extends BaseUnitTest
public void testOnToggle()
{
assertTrue(habit1.isCompletedToday());
behavior.onToggle(habit1, DateUtils.getStartOfToday());
behavior.onToggle(habit1, DateUtils.getToday());
assertFalse(habit1.isCompletedToday());
}

View File

@@ -134,17 +134,4 @@ public class DateUtilsTest extends BaseUnitTest
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
}
@Test
public void test_getDaysBetween()
{
long t1 = timestamp(2016, JANUARY, 1);
long t2 = timestamp(2016, JANUARY, 10);
long t3 = timestamp(2016, DECEMBER, 31);
assertThat(DateUtils.getDaysBetween(t1, t1), equalTo(0));
assertThat(DateUtils.getDaysBetween(t1, t2), equalTo(9));
assertThat(DateUtils.getDaysBetween(t1, t3), equalTo(365));
assertThat(DateUtils.getDaysBetween(t3, t1), equalTo(365));
}
}