<?php | |||||
namespace Lc\SovBundle\Controller; | |||||
use App\Container\Delivery\DeliveryAvailabilityPointSaleContainer; | |||||
use App\Container\Delivery\DeliveryAvailabilityZoneContainer; | |||||
use App\Container\Delivery\DeliveryPriceContainer; | |||||
use App\Container\Delivery\DeliverySlotContainer; | |||||
use App\Container\Delivery\DeliveryZoneContainer; | |||||
use App\Container\Notification\NotificationContainer; | |||||
use App\Container\Notification\NotificationLogContainer; | |||||
use App\Container\Notification\NotificationUserContainer; | |||||
use App\Container\Order\PurchaseOrderContainer; | |||||
use App\Container\Product\SupplierContainer; | |||||
use App\Container\Sponsor\SponsorContainer; | |||||
use App\Payment\SystemPay; | |||||
use App\Solver\Price\PriceSolver; | |||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use Knp\Component\Pager\PaginatorInterface; | |||||
use Lc\CaracoleBundle\Container\Address\AddressContainer; | |||||
use Lc\CaracoleBundle\Container\Config\TaxRateContainer; | |||||
use Lc\CaracoleBundle\Container\Config\UnitContainer; | |||||
use Lc\CaracoleBundle\Container\Credit\CreditHistoryContainer; | |||||
use Lc\CaracoleBundle\Container\File\DocumentContainer; | |||||
use Lc\CaracoleBundle\Container\Merchant\MerchantContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderPaymentContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderProductContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderProductReductionCatalogContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderProductRefundContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderReductionCartContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderReductionCreditContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderRefundContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderShopContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderStatusContainer; | |||||
use Lc\CaracoleBundle\Container\Order\OrderStatusHistoryContainer; | |||||
use Lc\CaracoleBundle\Container\PointSale\PointSaleContainer; | |||||
use Lc\CaracoleBundle\Container\Product\ProductCategoryContainer; | |||||
use Lc\CaracoleBundle\Container\Product\ProductContainer; | |||||
use Lc\CaracoleBundle\Container\Product\ProductFamilyContainer; | |||||
use Lc\CaracoleBundle\Container\Reduction\ReductionCartContainer; | |||||
use Lc\CaracoleBundle\Container\Reduction\ReductionCatalogContainer; | |||||
use Lc\CaracoleBundle\Container\Reduction\ReductionCreditContainer; | |||||
use Lc\CaracoleBundle\Container\Section\OpeningContainer; | |||||
use Lc\CaracoleBundle\Container\Section\SectionContainer; | |||||
use Lc\CaracoleBundle\Container\Setting\MerchantSettingContainer; | |||||
use Lc\CaracoleBundle\Container\Setting\SectionSettingContainer; | |||||
use Lc\CaracoleBundle\Container\User\UserMerchantContainer; | |||||
use Lc\CaracoleBundle\Container\User\UserPointSaleContainer; | |||||
use Lc\CaracoleBundle\Container\User\VisitorContainer; | |||||
use Lc\SovBundle\Container\ComponentContainer; | |||||
use Lc\SovBundle\Container\File\FileContainer; | |||||
use Lc\SovBundle\Container\Newsletter\NewsletterContainer; | |||||
use Lc\SovBundle\Container\Reminder\ReminderContainer; | |||||
use Lc\SovBundle\Container\Setting\SiteSettingContainer; | |||||
use Lc\SovBundle\Container\Site\NewsContainer; | |||||
use Lc\SovBundle\Container\Site\PageContainer; | |||||
use Lc\SovBundle\Container\Site\SiteContainer; | |||||
use Lc\SovBundle\Container\Ticket\TicketContainer; | |||||
use Lc\SovBundle\Container\Ticket\TicketMessageContainer; | |||||
use Lc\SovBundle\Container\User\GroupUserContainer; | |||||
use Lc\SovBundle\Container\User\UserContainer; | |||||
use Lc\SovBundle\Solver\Setting\SettingSolver; | |||||
use Psr\Log\LoggerInterface; | |||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SfAbstractController; | |||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||||
use Symfony\Component\HttpFoundation\Request; | |||||
use Symfony\Component\HttpFoundation\RequestStack; | |||||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |||||
use Symfony\Component\Security\Core\Security; | |||||
use Symfony\Contracts\Translation\TranslatorInterface; | |||||
class AbstractController extends SfAbstractController | |||||
{ | |||||
public static function getSubscribedServices() | |||||
{ | |||||
return array_merge( | |||||
parent::getSubscribedServices(), | |||||
[ | |||||
Security::class => Security::class, | |||||
EntityManagerInterface::class => EntityManagerInterface::class, | |||||
UrlGeneratorInterface::class => UrlGeneratorInterface::class, | |||||
SessionInterface::class => SessionInterface::class, | |||||
PaginatorInterface::class => PaginatorInterface::class, | |||||
RequestStack::class => RequestStack::class, | |||||
EventDispatcherInterface::class => EventDispatcherInterface::class, | |||||
TranslatorInterface::class => TranslatorInterface::class, | |||||
LoggerInterface::class => LoggerInterface::class, | |||||
SettingSolver::class => SettingSolver::class, | |||||
ComponentContainer::class => ComponentContainer::class, | |||||
FileContainer::class => FileContainer::class, | |||||
NewsletterContainer::class => NewsletterContainer::class, | |||||
ReminderContainer::class => ReminderContainer::class, | |||||
NewsContainer::class => NewsContainer::class, | |||||
PageContainer::class => PageContainer::class, | |||||
SiteContainer::class => SiteContainer::class, | |||||
TicketContainer::class => TicketContainer::class, | |||||
TicketMessageContainer::class => TicketMessageContainer::class, | |||||
GroupUserContainer::class => GroupUserContainer::class, | |||||
UserContainer::class => UserContainer::class, | |||||
SiteSettingContainer::class => SiteSettingContainer::class, | |||||
] | |||||
); | |||||
} | |||||
public function getReferer(Request $request): ?string | |||||
{ | |||||
return $request->headers->get('referer'); | |||||
} | |||||
public function getEntityManager(): EntityManagerInterface | |||||
{ | |||||
return $this->get(EntityManagerInterface::class); | |||||
} | |||||
public function getRouter(): UrlGeneratorInterface | |||||
{ | |||||
return $this->get(UrlGeneratorInterface::class); | |||||
} | |||||
public function getSession(): SessionInterface | |||||
{ | |||||
return $this->get(SessionInterface::class); | |||||
} | |||||
public function getSecurity(): Security | |||||
{ | |||||
return $this->get(Security::class); | |||||
} | |||||
public function getPaginator(): PaginatorInterface | |||||
{ | |||||
return $this->get(PaginatorInterface::class); | |||||
} | |||||
public function getRequestStack(): RequestStack | |||||
{ | |||||
return $this->get(RequestStack::class); | |||||
} | |||||
public function getEventDispatcher(): EventDispatcherInterface | |||||
{ | |||||
return $this->get(EventDispatcherInterface::class); | |||||
} | |||||
public function getTranslator(): TranslatorInterface | |||||
{ | |||||
return $this->get(TranslatorInterface::class); | |||||
} | |||||
public function getLogger(): LoggerInterface | |||||
{ | |||||
return $this->get(LoggerInterface::class); | |||||
} | |||||
public function getSettingSolver(): SettingSolver | |||||
{ | |||||
return $this->get(SettingSolver::class); | |||||
} | |||||
public function getSettingValue($entity, $settingName) | |||||
{ | |||||
return $this->getSettingSolver()->getSettingValue($entity, $settingName); | |||||
} | |||||
public function getComponentContainer(): ComponentContainer | |||||
{ | |||||
return $this->get(ComponentContainer::class); | |||||
} | |||||
public function getFileContainer(): FileContainer | |||||
{ | |||||
return $this->get(FileContainer::class); | |||||
} | |||||
public function getNewsletterContainer(): NewsletterContainer | |||||
{ | |||||
return $this->get(NewsletterContainer::class); | |||||
} | |||||
public function getReminderContainer(): ReminderContainer | |||||
{ | |||||
return $this->get(ReminderContainer::class); | |||||
} | |||||
public function getNewsContainer(): NewsContainer | |||||
{ | |||||
return $this->get(NewsContainer::class); | |||||
} | |||||
public function getPageContainer(): PageContainer | |||||
{ | |||||
return $this->get(PageContainer::class); | |||||
} | |||||
public function getSiteContainer(): SiteContainer | |||||
{ | |||||
return $this->get(SiteContainer::class); | |||||
} | |||||
public function getTicketContainer(): TicketContainer | |||||
{ | |||||
return $this->get(TicketContainer::class); | |||||
} | |||||
public function getTicketMessageContainer(): TicketMessageContainer | |||||
{ | |||||
return $this->get(TicketMessageContainer::class); | |||||
} | |||||
public function getGroupUserContainer(): GroupUserContainer | |||||
{ | |||||
return $this->get(GroupUserContainer::class); | |||||
} | |||||
public function getUserContainer(): UserContainer | |||||
{ | |||||
return $this->get(UserContainer::class); | |||||
} | |||||
public function getSiteSettingContainer(): SiteSettingContainer | |||||
{ | |||||
return $this->get(SiteSettingContainer::class); | |||||
} | |||||
} |
use Lc\SovBundle\Model\Ticket\TicketInterface; | use Lc\SovBundle\Model\Ticket\TicketInterface; | ||||
use Lc\SovBundle\Model\Ticket\TicketModel; | use Lc\SovBundle\Model\Ticket\TicketModel; | ||||
use Lc\SovBundle\Model\User\UserInterface; | use Lc\SovBundle\Model\User\UserInterface; | ||||
use Lc\SovBundle\Solver\Ticket\TicketSolver; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
use Symfony\Component\Form\AbstractType; | use Symfony\Component\Form\AbstractType; | ||||
class TicketFormType extends AbstractType | class TicketFormType extends AbstractType | ||||
{ | { | ||||
protected $em; | |||||
protected $translatorAdmin; | |||||
protected EntityManager $entityManager; | |||||
protected TranslatorAdmin $translatorAdmin; | |||||
protected TicketSolver $ticketSolver; | |||||
public function __construct(EntityManager $em, TranslatorAdmin $translatorAdmin) | |||||
{ | |||||
$this->em = $em; | |||||
public function __construct( | |||||
EntityManager $entityManager, | |||||
TranslatorAdmin $translatorAdmin, | |||||
TicketSolver $ticketSolver | |||||
) { | |||||
$this->entityManager = $entityManager; | |||||
$this->translatorAdmin = $translatorAdmin; | $this->translatorAdmin = $translatorAdmin; | ||||
$this->ticketSolver = $ticketSolver; | |||||
} | } | ||||
public function buildForm(FormBuilderInterface $builder, array $options) | public function buildForm(FormBuilderInterface $builder, array $options) | ||||
{ | { | ||||
$entityName = $this->em->getEntityName(TicketInterface::class); | |||||
$entityName = $this->entityManager->getEntityName(TicketInterface::class); | |||||
$builder->add( | $builder->add( | ||||
'user', | |||||
EntityType::class, | |||||
[ | |||||
'class' => $this->em->getEntityName(UserInterface::class), | |||||
] | |||||
'user', | |||||
EntityType::class, | |||||
[ | |||||
'class' => $this->entityManager->getEntityName(UserInterface::class), | |||||
] | |||||
); | ); | ||||
$builder->add( | $builder->add( | ||||
'subject', | |||||
TextType::class | |||||
'subject', | |||||
TextType::class | |||||
); | ); | ||||
$builder->add( | $builder->add( | ||||
'type', | |||||
ChoiceType::class, | |||||
[ | |||||
'label' => 'Type', | |||||
'choices' => $this->translatorAdmin->transChoices($entityName::getTypeChoices(),'Ticket', 'type'), | |||||
] | |||||
'type', | |||||
ChoiceType::class, | |||||
[ | |||||
'label' => 'Type', | |||||
'choices' => $this->translatorAdmin->transChoices( | |||||
$this->ticketSolver->getTypeChoices(), | |||||
'Ticket', | |||||
'type' | |||||
), | |||||
] | |||||
); | ); | ||||
$builder->add( | $builder->add( | ||||
'ticketMessages', | |||||
CollectionType::class, | |||||
[ | |||||
'entry_type' => TicketMessageType::class, | |||||
'allow_add' => false, | |||||
'label_attr' => ['class' => 'label-ticket'], | |||||
] | |||||
'ticketMessages', | |||||
CollectionType::class, | |||||
[ | |||||
'entry_type' => TicketMessageType::class, | |||||
'allow_add' => false, | |||||
'label_attr' => ['class' => 'label-ticket'], | |||||
] | |||||
); | ); | ||||
$builder->add( | $builder->add( | ||||
'submit', | |||||
SubmitType::class, | |||||
[ | |||||
'label' => $this->translatorAdmin->transAction('save') | |||||
] | |||||
'submit', | |||||
SubmitType::class, | |||||
[ | |||||
'label' => $this->translatorAdmin->transAction('save') | |||||
] | |||||
); | ); | ||||
} | } | ||||
public function configureOptions(OptionsResolver $resolver) | public function configureOptions(OptionsResolver $resolver) | ||||
{ | { | ||||
$resolver->setDefaults( | $resolver->setDefaults( | ||||
[ | |||||
'data_class' => $this->em->getEntityName(TicketInterface::class), | |||||
] | |||||
[ | |||||
'data_class' => $this->entityManager->getEntityName(TicketInterface::class), | |||||
] | |||||
); | ); | ||||
} | } | ||||
} | } |
public function __toString(){ | public function __toString(){ | ||||
return $this->getLegend(); | |||||
return ''.$this->getLegend(); | |||||
} | } | ||||
public function getPath(): ?string | public function getPath(): ?string |
return $this->andWhere('.'.$field.' = :'.$field)->setParameter($field, $value); | return $this->andWhere('.'.$field.' = :'.$field)->setParameter($field, $value); | ||||
} | } | ||||
public function filterByOldUrl(string $oldUrl): self | |||||
{ | |||||
return $this->andWhere(':oldUrl IN .oldUrls')->setParameter('oldUrl', $oldUrl); | |||||
} | |||||
/* | /* | ||||
* DEVALIAS | * DEVALIAS | ||||
*/ | */ |
public function getOneBySlug(string $slug, bool $isOnline = true, $query = null) | public function getOneBySlug(string $slug, bool $isOnline = true, $query = null) | ||||
{ | { | ||||
$query = $this->createDefaultQuery($query); | |||||
$query = $this->createQuery($query); | |||||
$query->filterBySlug($slug); | $query->filterBySlug($slug); | ||||
if ($isOnline) { | if ($isOnline) { | ||||
public function getOneByDevAlias(string $devAlias, $query = null) | public function getOneByDevAlias(string $devAlias, $query = null) | ||||
{ | { | ||||
$query = $this->createDefaultQuery($query); | |||||
$query = $this->createQuery($query); | |||||
$query->filterByDevAlias($devAlias); | $query->filterByDevAlias($devAlias); | ||||
return $query->findOne(); | return $query->findOne(); | ||||
} | } | ||||
public function getOneOnlineByDevAlias(string $devAlias, $query = null) | public function getOneOnlineByDevAlias(string $devAlias, $query = null) | ||||
{ | { | ||||
$query = $this->createDefaultQuery($query); | |||||
$query = $this->createQuery($query); | |||||
$query | $query | ||||
->filterByDevAlias($devAlias) | ->filterByDevAlias($devAlias) | ||||
->filterIsOnline(); | ->filterIsOnline(); | ||||
return $query->findOne(); | return $query->findOne(); | ||||
} | } | ||||
public function getOneByOldUrl(string $oldUrl, $query = null) | |||||
{ | |||||
$query = $this->createQuery($query); | |||||
$query | |||||
->filterByOldUrl($oldUrl) | |||||
->filterIsOnline(); | |||||
return $query->findOne(); | |||||
} | |||||
public function get($query = null) | public function get($query = null) | ||||
{ | { | ||||
$query = $this->createDefaultQuery($query); | $query = $this->createDefaultQuery($query); |
{ | { | ||||
return $query; | return $query; | ||||
} | } | ||||
public function getOneDefault() | |||||
{ | |||||
return $this->getOneByDevAlias('default'); | |||||
} | |||||
} | } |
<?php | |||||
namespace Lc\SovBundle\Twig; | |||||
use Lc\SovBundle\Component\MetaComponent; | |||||
use Twig\Extension\AbstractExtension; | |||||
use Twig\TwigFunction; | |||||
class MetaTwigExtension extends AbstractExtension | |||||
{ | |||||
protected MetaComponent $metaComponent; | |||||
public function __construct(MetaComponent $metaComponent) | |||||
{ | |||||
$this->metaComponent = $metaComponent; | |||||
} | |||||
public function getFunctions() | |||||
{ | |||||
return [ | |||||
new TwigFunction('sov_meta_title', [$this, 'getMetaTitle']), | |||||
new TwigFunction('sov_meta_description', [$this, 'getMetaDescription']), | |||||
new TwigFunction('sov_opengraph_title', [$this, 'getOpengraphTitle']), | |||||
new TwigFunction('sov_opengraph_description', [$this, 'getOpengraphDescription']), | |||||
new TwigFunction('sov_opengraph_image', [$this, 'getOpengraphImage']), | |||||
]; | |||||
} | |||||
public function getFilters() | |||||
{ | |||||
return []; | |||||
} | |||||
public function getMetaTitle($entity): ?string | |||||
{ | |||||
return $this->metaComponent->getMetaTitle($entity); | |||||
} | |||||
public function getMetaDescription($entity): ?string | |||||
{ | |||||
return $this->metaComponent->getMetaDescription($entity); | |||||
} | |||||
public function getOpenGraphTitle($entity): ?string | |||||
{ | |||||
return $this->metaComponent->getOpenGraphTitle($entity); | |||||
} | |||||
public function getOpenGraphDescription($entity): ?string | |||||
{ | |||||
return $this->metaComponent->getOpenGraphDescription($entity); | |||||
} | |||||
public function getOpenGraphImage($entity): ?string | |||||
{ | |||||
return $this->metaComponent->getOpenGraphImage($entity); | |||||
} | |||||
} |
use App\Repository\ReminderRepository; | use App\Repository\ReminderRepository; | ||||
use Doctrine\ORM\EntityManagerInterface; | use Doctrine\ORM\EntityManagerInterface; | ||||
use Lc\SovBundle\Component\MetaComponent; | |||||
use Lc\SovBundle\Component\StringComponent; | |||||
use Lc\SovBundle\Form\Newsletter\NewsletterType; | use Lc\SovBundle\Form\Newsletter\NewsletterType; | ||||
use Lc\SovBundle\Model\File\FileInterface; | |||||
use Lc\SovBundle\Repository\Reminder\ReminderStore; | use Lc\SovBundle\Repository\Reminder\ReminderStore; | ||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Liip\ImagineBundle\Imagine\Cache\CacheManager; | use Liip\ImagineBundle\Imagine\Cache\CacheManager; | ||||
class TwigExtension extends AbstractExtension | class TwigExtension extends AbstractExtension | ||||
{ | { | ||||
protected $em; | |||||
protected $kernel; | |||||
protected $parameterBag; | |||||
protected $cacheManager; | |||||
protected $requestStack; | |||||
protected $router; | |||||
protected $translator; | |||||
protected $translatorAdmin; | |||||
protected $reminderStore; | |||||
protected $security; | |||||
protected EntityManagerInterface $em; | |||||
protected KernelInterface $kernel; | |||||
protected ParameterBagInterface $parameterBag; | |||||
protected CacheManager $cacheManager; | |||||
protected RequestStack $requestStack; | |||||
protected UrlGeneratorInterface $router; | |||||
protected TranslatorInterface $translator; | |||||
protected TranslatorAdmin $translatorAdmin; | |||||
protected ReminderStore $reminderStore; | |||||
protected Security $security; | |||||
protected FormFactoryInterface $formFactory; | protected FormFactoryInterface $formFactory; | ||||
protected StringComponent $stringComponent; | |||||
protected MetaComponent $metaComponent; | |||||
public function __construct( | public function __construct( | ||||
KernelInterface $kernel, | KernelInterface $kernel, | ||||
TranslatorAdmin $translatorAdmin, | TranslatorAdmin $translatorAdmin, | ||||
ReminderStore $reminderStore, | ReminderStore $reminderStore, | ||||
Security $security, | Security $security, | ||||
FormFactoryInterface $formFactory | |||||
FormFactoryInterface $formFactory, | |||||
StringComponent $stringComponent, | |||||
MetaComponent $metaComponent | |||||
) { | ) { | ||||
$this->kernel = $kernel; | $this->kernel = $kernel; | ||||
$this->parameterBag = $parameterBag; | $this->parameterBag = $parameterBag; | ||||
$this->reminderStore = $reminderStore; | $this->reminderStore = $reminderStore; | ||||
$this->security = $security; | $this->security = $security; | ||||
$this->formFactory = $formFactory; | $this->formFactory = $formFactory; | ||||
$this->stringComponent = $stringComponent; | |||||
$this->metaComponent = $metaComponent; | |||||
} | } | ||||
public function getFunctions() | public function getFunctions() | ||||
{ | { | ||||
return [ | return [ | ||||
new TwigFunction('sov_liip', [$this, 'liip']), | new TwigFunction('sov_liip', [$this, 'liip']), | ||||
new TwigFunction('liip', [$this, 'liip']), | |||||
new TwigFunction('sov_get_by_devalias', [$this, 'getByDevAlias']), | new TwigFunction('sov_get_by_devalias', [$this, 'getByDevAlias']), | ||||
new TwigFunction('sov_parameter', [$this, 'getParameter']), | new TwigFunction('sov_parameter', [$this, 'getParameter']), | ||||
new TwigFunction('sov_homepage_route', [$this, 'getHomepageRoute']), | new TwigFunction('sov_homepage_route', [$this, 'getHomepageRoute']), | ||||
new TwigFunction('lc_format_price', [$this, 'formatPrice']), | new TwigFunction('lc_format_price', [$this, 'formatPrice']), | ||||
new TwigFunction('die', [$this, 'die']), | new TwigFunction('die', [$this, 'die']), | ||||
new TwigFunction('get_form_newsletter', [$this, 'getFormNewsletter']), | new TwigFunction('get_form_newsletter', [$this, 'getFormNewsletter']), | ||||
new TwigFunction('sov_limit_text', [$this, 'limitText']), | |||||
]; | ]; | ||||
} | } | ||||
$fileManagerFolder = substr($this->getFileManagerFolder(), 1); | $fileManagerFolder = substr($this->getFileManagerFolder(), 1); | ||||
if (strpos($path, $fileManagerFolder) === false) { | if (strpos($path, $fileManagerFolder) === false) { | ||||
$path = $fileManagerFolder.'/'.$path; | |||||
$path = $fileManagerFolder . '/' . $path; | |||||
} | } | ||||
if (file_exists($path)) { | if (file_exists($path)) { | ||||
} | } | ||||
} | } | ||||
return $this->cacheManager->getBrowserPath($this->getFileManagerFolder().'/'.$default, $thumb); | |||||
return $this->cacheManager->getBrowserPath($this->getFileManagerFolder() . '/' . $default, $thumb); | |||||
} | } | ||||
public function getFileManagerFolder() | public function getFileManagerFolder() | ||||
return $form->createView(); | return $form->createView(); | ||||
} | } | ||||
public function limitText(string $text, int $limit) | |||||
{ | |||||
return $this->stringComponent->limitText($text, $limit); | |||||
} | |||||
} | } |