PersonAddressMove: fix tests, address history on household, and household::getMembersOnRange

This commit is contained in:
Julien Fastré 2022-02-21 00:12:57 +01:00
parent caa63ea97a
commit 4f4b1bfbaa
9 changed files with 288 additions and 210 deletions

View File

@ -304,7 +304,6 @@ class Address
/**
* Get postcode.
*
*/
public function getPostcode(): ?PostalCode
{

View File

@ -15,13 +15,14 @@ use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Notification;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Templating\EngineInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class PersonMoveEventSubscriber implements EventSubscriberInterface
class PersonAddressMoveEventSubscriber implements EventSubscriberInterface
{
private EngineInterface $engine;
@ -62,17 +63,11 @@ class PersonMoveEventSubscriber implements EventSubscriberInterface
continue;
}
$now = new \DateTimeImmutable('now');
if (
$period->getPersonLocation() === $person
&&
(
&& (
$event->getMoveDate() >= $period->getLastLocationHistory()->getStartDate()
|| (
$event->getNextAddress()->getValidFrom() < $now
&& (null === $event->getNextAddress()->getValidTo() || $event->getNextAddress()->getValidTo() > $now)
)
|| $event->willChangeBeActiveAt(new DateTimeImmutable('now'))
)
&& null !== $period->getUser()
&& $period->getUser() !== $this->security->getUser()

View File

@ -22,25 +22,25 @@ use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
use Chill\PersonBundle\Repository\Household\HouseholdACLAwareRepositoryInterface;
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
use DateTimeImmutable;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use function array_filter;
use function array_values;
class HouseholdApiController extends ApiController
{
private EventDispatcherInterface $eventDispatcher;
private HouseholdACLAwareRepositoryInterface $householdACLAwareRepository;
private HouseholdRepository $householdRepository;
private EventDispatcherInterface $eventDispatcher;
public function __construct(
EventDispatcherInterface $eventDispatcher,
HouseholdRepository $householdRepository,
@ -76,10 +76,10 @@ class HouseholdApiController extends ApiController
}
/**
* Add an address to a household
* Add an address to a household.
*
* @Route("/api/1.0/person/household/{id}/address.{_format}", name="chill_api_single_household_address",
* methods={"POST"}, requirements={"_format": "json"})
* methods={"POST"}, requirements={"_format": "json"})
*/
public function householdAddressApi(Household $household, Request $request, string $_format): Response
{
@ -87,22 +87,22 @@ class HouseholdApiController extends ApiController
/** @var Address $address */
$address = $this->getSerializer()->deserialize($request->getContent(), Address::class, $_format, [
AbstractNormalizer::GROUPS => ['write']
AbstractNormalizer::GROUPS => ['write'],
]);
$household->addAddress($address);
foreach ($household->getMembersOnRange(
\DateTimeImmutable::createFromMutable($address->getValidFrom()),
DateTimeImmutable::createFromMutable($address->getValidFrom()),
null === $address->getValidTo() ? null :
\DateTimeImmutable::createFromMutable($address->getValidTo())
DateTimeImmutable::createFromMutable($address->getValidTo())
) as $member) {
/** @var HouseholdMember $member */
$event = new PersonAddressMoveEvent($member->getPerson());
$event
->setPreviousAddress($household->getPreviousAddressOf($address))
->setNextAddress($address)
;
->setNextAddress($address);
dump($event);
$this->eventDispatcher->dispatch($event);
}
@ -118,7 +118,7 @@ class HouseholdApiController extends ApiController
$address,
Response::HTTP_OK,
[],
[AbstractNormalizer::GROUPS => ["read"]]
[AbstractNormalizer::GROUPS => ['read']]
);
}

View File

@ -28,12 +28,12 @@ class AccompanyingPeriodLocationHistory implements TrackCreationInterface
use TrackCreationTrait;
/**
* @ORM\ManyToOne(targetEntity=Address::class)
* @ORM\ManyToOne(targetEntity=Address::class, cascade={"persist"})
*/
private ?Address $addressLocation = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default":null})
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
*/
private ?DateTimeImmutable $endDate = null;

View File

@ -116,66 +116,6 @@ class Household
return $this;
}
public function getAddressesOrdered(): array
{
$addresses = $this->getAddresses()->toArray();
usort($addresses, function (Address $a, Address $b) {
$validFromA = $a->getValidFrom()->format('Y-m-d');
$validFromB = $b->getValidFrom()->format('Y-m-d');
if ($a === $b) {
if (null === $a->getId()) {
return 1;
}
if (null === $b->getId()) {
return -1;
}
return $a->getId() <=> $b->getId();
}
return $validFromA <=> $validFromB;
});
return $addresses;
}
public function getPreviousAddressOf(Address $address): ?Address
{
$iterator = new ArrayIterator($this->getAddressesOrdered());
$iterator->rewind();
while ($iterator->valid()) {
$current = $iterator->current();
$iterator->next();
if ($iterator->valid()) {
if ($address === $iterator->current()) {
return $current;
}
}
}
return null;
}
public function makeAddressConsistent(): void
{
$iterator = new ArrayIterator($this->getAddressesOrdered());
$iterator->rewind();
while ($iterator->valid()) {
$current = $iterator->current();
$iterator->next();
if ($iterator->valid()) {
$current->setValidTo($iterator->current()->getValidFrom());
}
}
}
public function addComposition(HouseholdComposition $composition): self
{
if (!$this->compositions->contains($composition)) {
@ -211,6 +151,31 @@ class Household
return $this->addresses;
}
public function getAddressesOrdered(): array
{
$addresses = $this->getAddresses()->toArray();
usort($addresses, static function (Address $a, Address $b) {
$validFromA = $a->getValidFrom()->format('Y-m-d');
$validFromB = $b->getValidFrom()->format('Y-m-d');
if ($a === $b) {
if (null === $a->getId()) {
return 1;
}
if (null === $b->getId()) {
return -1;
}
return $a->getId() <=> $b->getId();
}
return $validFromA <=> $validFromB;
});
return $addresses;
}
public function getCommentMembers(): CommentEmbeddable
{
return $this->commentMembers;
@ -412,24 +377,25 @@ class Household
public function getMembersOnRange(DateTimeImmutable $from, ?DateTimeImmutable $to): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
return $this->getMembers()->filter(static function (HouseholdMember $m) use ($from, $to) {
if (null === $m->getEndDate() && null !== $to) {
return $m->getStartDate() <= $to;
}
$criteria->where(
$expr->gte('startDate', $from)
);
if (null === $to) {
return $m->getStartDate() >= $from || null === $m->getEndDate();
}
if (null !== $to) {
$criteria->andWhere(
$expr->orX(
$expr->lte('endDate', $to),
$expr->eq('endDate', null)
),
);
}
if (null !== $m->getEndDate() && $m->getEndDate() < $from) {
return false;
}
return $this->getMembers()
->matching($criteria);
if ($m->getStartDate() <= $to) {
return true;
}
return false;
});
}
public function getNonCurrentMembers(?DateTimeImmutable $now = null): Collection
@ -472,6 +438,25 @@ class Household
return $this->getNonCurrentMembers($now)->matching($criteria);
}
public function getPreviousAddressOf(Address $address): ?Address
{
$iterator = new ArrayIterator($this->getAddressesOrdered());
$iterator->rewind();
while ($iterator->valid()) {
$current = $iterator->current();
$iterator->next();
if ($iterator->valid()) {
if ($iterator->current() === $address) {
return $current;
}
}
}
return null;
}
public function getWaitingForBirth(): bool
{
return $this->waitingForBirth;
@ -516,6 +501,23 @@ class Household
} while ($iterator->valid());
}
public function makeAddressConsistent(): void
{
$iterator = new ArrayIterator($this->getAddressesOrdered());
$iterator->rewind();
while ($iterator->valid()) {
$current = $iterator->current();
$iterator->next();
if ($iterator->valid()) {
$current->setValidTo($iterator->current()->getValidFrom());
}
}
}
public function removeAddress(Address $address)
{
$this->addresses->removeElement($address);

View File

@ -168,4 +168,42 @@ class PersonAddressMoveEvent extends Event
return $this;
}
/**
* Will the change affect this date ?
*/
public function willChangeBeActiveAt(DateTimeImmutable $date): bool
{
if ($this->getMoveDate() < $date && $this->personLeaveWithoutHousehold()) {
return true;
}
if ($this->personChangeHousehold()) {
if ($this->getMoveDate() > $date) {
return false;
}
if (null === $this->getNextMembership()->getEndDate()) {
return true;
}
if ($this->getNextMembership()->getEndDate() > $date) {
return true;
}
} else {
if ($this->getNextAddress()->getValidFrom() > $date) {
return false;
}
if (null === $this->getNextAddress()->getValidTo()) {
return true;
}
if ($this->getNextAddress()->getValidTo() > $date) {
return true;
}
}
return false;
}
}

View File

@ -14,7 +14,7 @@ namespace AccompanyingPeriod\Events;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\AccompanyingPeriod\Events\PersonMoveEventSubscriber;
use Chill\PersonBundle\AccompanyingPeriod\Events\PersonAddressMoveEventSubscriber;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
@ -80,51 +80,6 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
$eventSubscriber->resetPeriodLocation($event);
}
public function testEventChangeHouseholdNotificationForPeriodChangeLocationOfPersonAnteriorToCurrentLocationHistory()
{
$person = new Person();
$period = new AccompanyingPeriod();
$period
->setStep(AccompanyingPeriod::STEP_CONFIRMED)
->setPersonLocation($person)
->setUser(new User())
->addPerson($person);
$this->forceIdToPeriod($period);
$previousHousehold = (new Household())->addAddress(
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
);
$previousMembership = new HouseholdMember();
$previousMembership
->setPerson($person)
->setHousehold($previousHousehold)
->setStartDate(new DateTimeImmutable('1 year ago'))
->setEndDate(new DateTimeImmutable('tomorrow'));
$nextHousehold = (new Household())->addAddress(
(new Address())->setValidFrom(new DateTime('1 month ago'))
);
$nextMembership = new HouseholdMember();
$nextMembership
->setPerson($person)
->setHousehold($nextHousehold)
->setStartDate(new DateTimeImmutable('1 month ago'));
$event = new PersonAddressMoveEvent($person);
$event
->setPreviousMembership($previousMembership)
->setNextMembership($nextMembership);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalled(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
$this->assertNotNull($period->getAddressLocation());
$this->assertNull($period->getPersonLocation());
}
public function testEventChangeHouseholdNotification()
{
$person = new Person();
@ -170,40 +125,43 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
$this->assertNull($period->getPersonLocation());
}
public function testEventPersonChangeAddressInThePast()
public function testEventChangeHouseholdNotificationForPeriodChangeLocationOfPersonAnteriorToCurrentLocationHistory()
{
$person = new Person();
$period = new AccompanyingPeriod();
$period
->setStep(AccompanyingPeriod::STEP_CONFIRMED)
->setPersonLocation($person)
->addPerson($person)
->setUser(new User());
->setUser(new User())
->addPerson($person);
$this->forceIdToPeriod($period);
$membership = new HouseholdMember();
$membership
$previousHousehold = (new Household())->addAddress(
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
);
$previousMembership = new HouseholdMember();
$previousMembership
->setPerson($person)
->setHousehold($household = new Household())
->setHousehold($previousHousehold)
->setStartDate(new DateTimeImmutable('1 year ago'))
;
->setEndDate(new DateTimeImmutable('tomorrow'));
$previousAddress = new Address();
$previousAddress->setValidFrom(new DateTime('6 months ago'));
$household->addAddress($previousAddress);
$newAddress = new Address();
$newAddress->setValidFrom(new DateTime('tomorrow'));
$household->addAddress($newAddress);
$nextHousehold = (new Household())->addAddress(
(new Address())->setValidFrom(new DateTime('1 month ago'))
);
$nextMembership = new HouseholdMember();
$nextMembership
->setPerson($person)
->setHousehold($nextHousehold)
->setStartDate(new DateTimeImmutable('1 month ago'));
$event = new PersonAddressMoveEvent($person);
$event
->setPreviousAddress($household->getPreviousAddressOf($newAddress))
->setNextAddress($newAddress)
;
->setPreviousMembership($previousMembership)
->setNextMembership($nextMembership);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$em->persist(Argument::type(Notification::class))->shouldBeCalled(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
@ -247,12 +205,52 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
$this->assertNull($period->getPersonLocation());
}
public function testEventPersonChangeAddressInThePast()
{
$person = new Person();
$period = new AccompanyingPeriod();
$period
->setStep(AccompanyingPeriod::STEP_CONFIRMED)
->setPersonLocation($person)
->addPerson($person)
->setUser(new User());
$this->forceIdToPeriod($period);
$membership = new HouseholdMember();
$membership
->setPerson($person)
->setHousehold($household = new Household())
->setStartDate(new DateTimeImmutable('1 year ago'));
$previousAddress = new Address();
$previousAddress->setValidFrom(new DateTime('6 months ago'));
$household->addAddress($previousAddress);
$newAddress = new Address();
$newAddress->setValidFrom(new DateTime('tomorrow'));
$household->addAddress($newAddress);
$event = new PersonAddressMoveEvent($person);
$event
->setPreviousAddress($household->getPreviousAddressOf($newAddress))
->setNextAddress($newAddress);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
$this->assertNotNull($period->getAddressLocation());
$this->assertNull($period->getPersonLocation());
}
private function buildSubscriber(
?EngineInterface $engine = null,
?EntityManagerInterface $entityManager = null,
?Security $security = null,
?TranslatorInterface $translator = null
): PersonMoveEventSubscriber {
): PersonAddressMoveEventSubscriber {
if (null === $translator) {
$double = $this->prophesize(TranslatorInterface::class);
$translator = $double->reveal();
@ -274,7 +272,7 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
$entityManager = $double->reveal();
}
return new PersonMoveEventSubscriber(
return new PersonAddressMoveEventSubscriber(
$engine,
$entityManager,
$security,

View File

@ -14,8 +14,10 @@ namespace Entity\Household;
use Chill\MainBundle\Entity\Address;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdComposition;
use DateTimeImmutable;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
/**
@ -24,27 +26,47 @@ use PHPUnit\Framework\TestCase;
*/
final class HouseholdTest extends TestCase
{
public function testHouseholdComposition()
public function testGetMembersOnRange()
{
$household = new Household();
$household->addComposition(($first = new HouseholdComposition())
->setStartDate(new DateTimeImmutable('2021-12-01')));
$household->addMember($householdMemberA = (new HouseholdMember())
->setStartDate(new DateTimeImmutable('2020-01-01'))
->setEndDate(new DateTimeImmutable('2020-12-31'))
->setPerson(new Person()));
$household->addMember($householdMemberB = (new HouseholdMember())
->setStartDate(new DateTimeImmutable('2020-06-01'))
->setEndDate(new DateTimeImmutable('2021-06-31'))
->setPerson(new Person()));
$household->addMember($householdMemberC = (new HouseholdMember())
->setStartDate(new DateTimeImmutable('2021-01-01'))
->setEndDate(null)
->setPerson(new Person()));
$this->assertNull($first->getEndDate());
$members = $household->getMembersOnRange(new DateTimeImmutable('2019-01-01'), null);
$household->addComposition(($second = new HouseholdComposition())
->setStartDate(new DateTimeImmutable('2021-12-31')));
$this->assertCount(3, $members);
$this->assertContains($householdMemberA, $members);
$this->assertContains($householdMemberB, $members);
$this->assertContains($householdMemberC, $members);
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $first->getEndDate());
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $second->getStartDate());
$members = $household->getMembersOnRange(new DateTimeImmutable('2020-01-01'), new DateTimeImmutable('2020-07-01'));
$this->assertCount(2, $members);
$this->assertContains($householdMemberA, $members);
$this->assertContains($householdMemberB, $members);
$this->assertNotContains($householdMemberC, $members);
$household->addComposition(($inside = new HouseholdComposition())
->setStartDate(new DateTimeImmutable('2021-12-15')));
$members = $household->getMembersOnRange(new DateTimeImmutable('2020-01-01'), new DateTimeImmutable('2022-12-31'));
$this->assertCount(3, $members);
$this->assertContains($householdMemberA, $members);
$this->assertContains($householdMemberB, $members);
$this->assertContains($householdMemberC, $members);
$this->assertEquals(new DateTimeImmutable('2021-12-15'), $first->getEndDate());
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $second->getStartDate());
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $inside->getEndDate());
$members = $household->getMembersOnRange(new DateTimeImmutable('2021-01-01'), new DateTimeImmutable('2022-12-31'));
$this->assertCount(2, $members);
$this->assertNotContains($householdMemberA, $members);
$this->assertContains($householdMemberB, $members);
$this->assertContains($householdMemberC, $members);
}
public function testHouseholdAddressConsistent()
@ -72,7 +94,7 @@ final class HouseholdTest extends TestCase
$this->assertNull($lastAddress->getValidTo());
$futureAddress = new Address();
$futureAddress->setValidFrom(new DateTime('tomorrow'));
$futureAddress->setValidFrom($tomorrow = new DateTime('tomorrow'));
$household->addAddress($futureAddress);
$addresses = $household->getAddressesOrdered();
@ -83,6 +105,31 @@ final class HouseholdTest extends TestCase
$this->assertEquals($oneMonthAgo, $previousAddress->getValidFrom());
$this->assertEquals($yesterday, $previousAddress->getValidTo());
$this->assertEquals($yesterday, $lastAddress->getValidFrom());
$this->assertNull($lastAddress->getValidTo());
$this->assertEquals($tomorrow, $lastAddress->getValidTo());
$this->assertEquals($tomorrow, $futureAddress->getValidFrom());
$this->assertNull($futureAddress->getValidTo());
}
public function testHouseholdComposition()
{
$household = new Household();
$household->addComposition(($first = new HouseholdComposition())
->setStartDate(new DateTimeImmutable('2021-12-01')));
$this->assertNull($first->getEndDate());
$household->addComposition(($second = new HouseholdComposition())
->setStartDate(new DateTimeImmutable('2021-12-31')));
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $first->getEndDate());
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $second->getStartDate());
$household->addComposition(($inside = new HouseholdComposition())
->setStartDate(new DateTimeImmutable('2021-12-15')));
$this->assertEquals(new DateTimeImmutable('2021-12-15'), $first->getEndDate());
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $second->getStartDate());
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $inside->getEndDate());
}
}

View File

@ -12,7 +12,6 @@ declare(strict_types=1);
namespace Event\Person;
use Chill\MainBundle\Entity\Address;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Chill\PersonBundle\Entity\Person;
@ -27,6 +26,34 @@ use PHPUnit\Framework\TestCase;
*/
final class PersonAddressMoveEventTest extends TestCase
{
public function testPersonChangeAddress()
{
$person = new Person();
$household = (new Household())->addAddress(
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
);
$household->addAddress(
($nextAddress = new Address())->setValidFrom(new DateTime('1 month ago'))
);
$member = new HouseholdMember();
$member
->setPerson($person)
->setHousehold($household)
->setStartDate(new DateTimeImmutable('1 year ago'))
->setEndDate(new DateTimeImmutable('tomorrow'));
$event = new PersonAddressMoveEvent($person);
$event
->setPreviousAddress($previousAddress)
->setNextAddress($nextAddress);
$this->assertSame($previousAddress, $event->getPreviousAddress());
$this->assertSame($nextAddress, $event->getNextAddress());
$this->assertEquals(new DateTime('tomorrow'), $nextAddress->getValidFrom());
$this->assertEquals(new DateTime('tomorrow'), $event->getMoveDate());
}
public function testPersonChangeHousehold()
{
$person = new Person();
@ -88,32 +115,4 @@ final class PersonAddressMoveEventTest extends TestCase
$this->assertTrue($event->personLeaveWithoutHousehold());
$this->assertEquals(new DateTimeImmutable('tomorrow'), $event->getMoveDate());
}
public function testPersonChangeAddress()
{
$person = new Person();
$household = (new Household())->addAddress(
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
);
$household = (new Household())->addAddress(
($nextAddress = new Address())->setValidFrom(new DateTime('1 month ago'))
);
$member = new HouseholdMember();
$member
->setPerson($person)
->setHousehold($household)
->setStartDate(new DateTimeImmutable('1 year ago'))
->setEndDate(new DateTimeImmutable('tomorrow'));
$event = new PersonAddressMoveEvent($person);
$event
->setPreviousAddress($previousAddress)
->setNextAddress($nextAddress);
$this->assertSame($previousAddress, $event->getPreviousAddress());
$this->assertSame($nextAddress, $event->getNextAddress());
$this->assertEquals(new DateTime('tomorrow'), $nextAddress->getValidFrom());
$this->assertEquals(new DateTime('tomorrow'), $event->getMoveDate());
}
}