diff options
-rw-r--r-- | include/m_popup.h | 11 | ||||
-rw-r--r-- | plugins/Popup/src/config.h | 1 | ||||
-rw-r--r-- | plugins/Popup/src/main.cpp | 7 | ||||
-rw-r--r-- | plugins/Popup/src/services.cpp | 148 | ||||
-rw-r--r-- | plugins/YAPP/src/services.cpp | 61 | ||||
-rw-r--r-- | protocols/GTalkExt/src/handlers.cpp | 14 |
6 files changed, 144 insertions, 98 deletions
diff --git a/include/m_popup.h b/include/m_popup.h index 84bc5de878..3edf9addb9 100644 --- a/include/m_popup.h +++ b/include/m_popup.h @@ -300,6 +300,17 @@ static int __inline PUShowMessageW(wchar_t *lpwzText, DWORD kind) { #define PUShowMessageT PUShowMessage
#endif
+/* Popup/Filter
+Filters popups out
+
+wParam = (HANDLE)hContact
+lParam = (void*)pWindowProc;
+
+returns: 0 = popup allowed, 1 = popup filtered out
+*/
+
+#define ME_POPUP_FILTER "Popup/Filter"
+
//------------- Class API ----------------//
typedef struct {
diff --git a/plugins/Popup/src/config.h b/plugins/Popup/src/config.h index f6a0635b18..dcfcf7b0dd 100644 --- a/plugins/Popup/src/config.h +++ b/plugins/Popup/src/config.h @@ -127,6 +127,7 @@ void LoadOptions(); //===== General Plugin =====
extern HINSTANCE hInst;
extern HANDLE hMainThread;
+extern HANDLE hEventNotify;
extern HANDLE hSemaphore;
extern BOOL closing;
extern HANDLE folderId;
diff --git a/plugins/Popup/src/main.cpp b/plugins/Popup/src/main.cpp index 58d9c1ba94..6761a28fae 100644 --- a/plugins/Popup/src/main.cpp +++ b/plugins/Popup/src/main.cpp @@ -27,6 +27,7 @@ WORD SETTING_MAXIMUMWIDTH_MAX = GetSystemMetrics(SM_CXSCREEN); #define MENUCOMMAND_HISTORY "Popup/ShowHistory"
#define MENUCOMMAND_SVC "Popup/EnableDisableMenuCommand"
+HANDLE hEventNotify;
//===== MessageBoxes =====
//void MB(char*); //This one is for Debug purposes
@@ -379,6 +380,8 @@ MIRAPI int Load(void) LoadOptions();
//Service Functions
+ hEventNotify = CreateHookableEvent(ME_POPUP_FILTER);
+
CreateServiceFunction(MS_POPUP_ADDPOPUP, Popup_AddPopup);
CreateServiceFunction(MS_POPUP_ADDPOPUPW, Popup_AddPopupW);
CreateServiceFunction(MS_POPUP_ADDPOPUP2, Popup_AddPopup2);
@@ -435,7 +438,9 @@ MIRAPI int Unload(void) FreeLibrary(hMsimgDll);
FreeLibrary(hGdiDll);
- if (PopupOptions.SkinPack) mir_free(PopupOptions.SkinPack);
+ DestroyHookableEvent(hEventNotify);
+
+ mir_free(PopupOptions.SkinPack);
mir_free(PopupOptions.Effect);
OptAdv_UnregisterVfx();
diff --git a/plugins/Popup/src/services.cpp b/plugins/Popup/src/services.cpp index 932943f698..0e7895b09c 100644 --- a/plugins/Popup/src/services.cpp +++ b/plugins/Popup/src/services.cpp @@ -58,12 +58,10 @@ static bool isFullScreen() // check foregroundwindow
HWND hWnd = GetForegroundWindow();
- if (hWnd && hWnd != hWndDesktop && hWnd != hWndShell)
- {
+ if (hWnd && hWnd != hWndDesktop && hWnd != hWndShell) {
TCHAR tszClassName[128] = _T("");
GetClassName(hWnd, tszClassName, SIZEOF(tszClassName));
- if (_tcscmp(tszClassName, _T("WorkerW")))
- {
+ if (_tcscmp(tszClassName, _T("WorkerW"))) {
RECT rect, rectw, recti;
GetWindowRect(hWnd, &rectw);
@@ -83,10 +81,12 @@ static bool isFullScreen() //===== Popup/AddPopup
INT_PTR Popup_AddPopup(WPARAM wParam, LPARAM lParam)
{
- if (!gbPopupLoaded) return -1;
+ if (!gbPopupLoaded)
+ return -1;
POPUPDATA *ppd = (POPUPDATA*)wParam;
- if (!ppd) return -1;
+ if (!ppd)
+ return -1;
POPUPDATA2 ppd2 = { sizeof(ppd2) };
ppd2.flags = PU2_ANSI;
@@ -105,10 +105,12 @@ INT_PTR Popup_AddPopup(WPARAM wParam, LPARAM lParam) //===== Popup/AddPopupW
INT_PTR Popup_AddPopupW(WPARAM wParam, LPARAM lParam)
{
- if (!gbPopupLoaded) return -1;
+ if (!gbPopupLoaded)
+ return -1;
POPUPDATAW_V2 *ppd = (POPUPDATAW_V2*)wParam;
- if (!ppd) return -1;
+ if (!ppd)
+ return -1;
POPUPDATA2 ppd2 = {0};
ppd2.cbSize = sizeof(ppd2);
@@ -144,10 +146,15 @@ INT_PTR Popup_AddPopup2(WPARAM wParam, LPARAM lParam) {
/* NOTE: we will return 0 instead of -1 since tabSRMM stops using popup after first failure :/ */
- if (!gbPopupLoaded) return -1;
+ if (!gbPopupLoaded)
+ return -1;
+
+ POPUPDATA2 *ppdIn = (POPUPDATA2*)wParam;
+ if (!ppdIn)
+ return -1;
- POPUPDATA2 *ppdIn = (POPUPDATA2 *)wParam;
- if (!ppdIn) return -1;
+ if ( NotifyEventHooks(hEventNotify, (WPARAM)ppdIn->lchContact, (LPARAM)ppdIn->PluginWindowProc))
+ return 0;
POPUPDATA2 ppdFixed = {0};
POPUPDATA2 *ppd = &ppdFixed;
@@ -156,7 +163,7 @@ INT_PTR Popup_AddPopup2(WPARAM wParam, LPARAM lParam) DWORD disableWhen;
FillNotificationData(ppd, &disableWhen);
- if (!(lParam&APF_NO_HISTORY))
+ if ( !(lParam & APF_NO_HISTORY))
PopupHistoryAdd(ppd);
if (PopupThreadIsFull())
@@ -164,9 +171,9 @@ INT_PTR Popup_AddPopup2(WPARAM wParam, LPARAM lParam) #ifdef _DEBUG
char temp[128];
- OutputDebugStringA("isWorkstationLocked: \t");
- OutputDebugStringA(isWorkstationLocked() ? "true":"false");
- OutputDebugStringA("\n");
+ OutputDebugStringA("isWorkstationLocked: \t");
+ OutputDebugStringA(isWorkstationLocked() ? "true":"false");
+ OutputDebugStringA("\n");
#endif
if (isWorkstationLocked())
@@ -182,8 +189,7 @@ INT_PTR Popup_AddPopup2(WPARAM wParam, LPARAM lParam) if (bShowMode == PU_SHOWMODE_BLOCK)
return -1;
- if (bShowMode != PU_SHOWMODE_FAVORITE)
- {
+ if (bShowMode != PU_SHOWMODE_FAVORITE) {
if (!PopupOptions.ModuleIsEnabled)
return -1;
#ifdef _DEBUG
@@ -210,8 +216,7 @@ INT_PTR Popup_AddPopup2(WPARAM wParam, LPARAM lParam) if ((disableWhen & 0x0000FFFF) & Proto_Status2Flag_My(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)))
return -1;
- if (proto)
- {
+ if (proto) {
char prefix[128];
mir_snprintf(prefix, sizeof(prefix), LPGEN("Protocol Status") "/%s", GetContactProto(ppd->lchContact));
if (db_get_dw(NULL, MODULNAME, prefix, 0) &
@@ -222,12 +227,11 @@ INT_PTR Popup_AddPopup2(WPARAM wParam, LPARAM lParam) }
}
- if (lParam&APF_CUSTOM_POPUP)
+ if (lParam & APF_CUSTOM_POPUP)
ppd->flags |= PU2_CUSTOM_POPUP;
+
PopupWnd2 *wnd = new PopupWnd2(ppd, NULL, false);
-
- if (lParam & APF_RETURN_HWND)
- {
+ if (lParam & APF_RETURN_HWND) {
while (!wnd->m_bWindowCreated) Sleep(1);
return (INT_PTR)wnd->getHwnd();
}
@@ -313,32 +317,32 @@ INT_PTR Popup_ShowMessage(WPARAM wParam, LPARAM lParam) { ppd2.cbSize = sizeof(ppd2);
ppd2.flags = PU2_ANSI;
ppd2.lpzText = (char*)wParam;
- switch (lParam&0x7fffffff) {
- case SM_ERROR:
- ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_ERROR,0);
- ppd2.colorBack = RGB(191,0,0);
- ppd2.colorText = RGB(255,245,225);
- ppd2.lchNotification = g_hntfError;
- ppd2.lpzTitle = Translate("Error");
- break;
- case SM_WARNING:
- ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_WARNING,0);
- ppd2.colorBack = RGB(210,210,150);
- ppd2.colorText = RGB(0,0,0);
- ppd2.lchNotification = g_hntfWarning;
- ppd2.lpzTitle = Translate("Warning");
- break;
- case SM_NOTIFY:
- ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_NOTIFY,0);
- ppd2.colorBack = RGB(230,230,230);
- ppd2.colorText = RGB(0,0,0);
- ppd2.lchNotification = g_hntfNotification;
- ppd2.lpzTitle = Translate("Notify");
- break;
- default: //No no no... you must give me a good value.
- return -1;
+ switch (lParam & 0x7fffffff) {
+ case SM_ERROR:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_ERROR,0);
+ ppd2.colorBack = RGB(191,0,0);
+ ppd2.colorText = RGB(255,245,225);
+ ppd2.lchNotification = g_hntfError;
+ ppd2.lpzTitle = Translate("Error");
+ break;
+ case SM_WARNING:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_WARNING,0);
+ ppd2.colorBack = RGB(210,210,150);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfWarning;
+ ppd2.lpzTitle = Translate("Warning");
+ break;
+ case SM_NOTIFY:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_NOTIFY,0);
+ ppd2.colorBack = RGB(230,230,230);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfNotification;
+ ppd2.lpzTitle = Translate("Notify");
+ break;
+ default: //No no no... you must give me a good value.
+ return -1;
}
- return Popup_AddPopup2((WPARAM)&ppd2, (LPARAM)((lParam&0x80000000)?APF_NO_HISTORY:0));
+ return Popup_AddPopup2((WPARAM)&ppd2, (LPARAM)((lParam & 0x80000000)?APF_NO_HISTORY:0));
}
INT_PTR Popup_ShowMessageW(WPARAM wParam, LPARAM lParam) {
@@ -350,31 +354,31 @@ INT_PTR Popup_ShowMessageW(WPARAM wParam, LPARAM lParam) { ppd2.flags = PU2_UNICODE;
ppd2.lpwzText = (WCHAR*)wParam;
switch (lParam&0x7fffffff) {
- case SM_ERROR:
- ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_ERROR,0);
- ppd2.colorBack = RGB(191,0,0);
- ppd2.colorText = RGB(255,245,225);
- ppd2.lchNotification = g_hntfError;
- ppd2.lpwzTitle = TranslateW(L"Error");
- break;
- case SM_WARNING:
- ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_WARNING,0);
- ppd2.colorBack = RGB(210,210,150);
- ppd2.colorText = RGB(0,0,0);
- ppd2.lchNotification = g_hntfWarning;
- ppd2.lpwzTitle = TranslateW(L"Warning");
- break;
- case SM_NOTIFY:
- ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_NOTIFY,0);
- ppd2.colorBack = RGB(230,230,230);
- ppd2.colorText = RGB(0,0,0);
- ppd2.lchNotification = g_hntfNotification;
- ppd2.lpwzTitle = TranslateW(L"Notify");
- break;
- default: //No no no... you must give me a good value.
- return -1;
+ case SM_ERROR:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_ERROR,0);
+ ppd2.colorBack = RGB(191,0,0);
+ ppd2.colorText = RGB(255,245,225);
+ ppd2.lchNotification = g_hntfError;
+ ppd2.lpwzTitle = TranslateW(L"Error");
+ break;
+ case SM_WARNING:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_WARNING,0);
+ ppd2.colorBack = RGB(210,210,150);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfWarning;
+ ppd2.lpwzTitle = TranslateW(L"Warning");
+ break;
+ case SM_NOTIFY:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_NOTIFY,0);
+ ppd2.colorBack = RGB(230,230,230);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfNotification;
+ ppd2.lpwzTitle = TranslateW(L"Notify");
+ break;
+ default: //No no no... you must give me a good value.
+ return -1;
}
- return Popup_AddPopup2((WPARAM)&ppd2, (LPARAM)((lParam&0x80000000)?APF_NO_HISTORY:0));
+ return Popup_AddPopup2((WPARAM)&ppd2, (LPARAM)((lParam & 0x80000000)?APF_NO_HISTORY:0));
}
//===== Popup/Query
diff --git a/plugins/YAPP/src/services.cpp b/plugins/YAPP/src/services.cpp index 25e3093a04..7d374a7dde 100644 --- a/plugins/YAPP/src/services.cpp +++ b/plugins/YAPP/src/services.cpp @@ -2,6 +2,7 @@ extern HANDLE hTTButton;
extern HGENMENU hMenuRoot, hMenuItem, hMenuItemHistory;
+static HANDLE hEventNotify;
void StripBBCodesInPlace(wchar_t *text)
{
@@ -42,8 +43,10 @@ void StripBBCodesInPlace(wchar_t *text) static INT_PTR CreatePopup(WPARAM wParam, LPARAM lParam)
{
POPUPDATA *pd_in = (POPUPDATA *)wParam;
- PopupData *pd_out = (PopupData *)mir_calloc(sizeof(PopupData));
+ if ( NotifyEventHooks(hEventNotify, (WPARAM)pd_in->lchContact, (LPARAM)pd_in->PluginWindowProc))
+ return 0;
+ PopupData *pd_out = (PopupData *)mir_calloc(sizeof(PopupData));
pd_out->cbSize = sizeof(PopupData);
pd_out->flags = PDF_UNICODE;
pd_out->pwzTitle = mir_a2u(pd_in->lpzContactName);
@@ -78,8 +81,10 @@ static INT_PTR CreatePopup(WPARAM wParam, LPARAM lParam) static INT_PTR CreatePopupW(WPARAM wParam, LPARAM lParam)
{
POPUPDATAW *pd_in = (POPUPDATAW *)wParam;
- PopupData *pd_out = (PopupData *)mir_calloc(sizeof(PopupData));
+ if ( NotifyEventHooks(hEventNotify, (WPARAM)pd_in->lchContact, (LPARAM)pd_in->PluginWindowProc))
+ return 0;
+ PopupData *pd_out = (PopupData *)mir_calloc(sizeof(PopupData));
pd_out->cbSize = sizeof(PopupData);
pd_out->flags = PDF_UNICODE;
pd_out->pwzTitle = mir_wstrdup(pd_in->lpwzContactName);
@@ -129,7 +134,8 @@ void ShowPopup(PopupData &pd_in) if (pd_in.flags & PDF_UNICODE) {
pd_out->pwzTitle = mir_wstrdup(pd_in.pwzTitle);
pd_out->pwzText = mir_wstrdup(pd_in.pwzText);
- } else {
+ }
+ else {
pd_out->flags |= PDF_UNICODE;
pd_out->pwzTitle = mir_a2u(pd_in.pszTitle);
pd_out->pwzText = mir_a2u(pd_in.pszText);
@@ -139,23 +145,21 @@ void ShowPopup(PopupData &pd_in) lstPopupHistory.Add(pd_out->pwzTitle, pd_out->pwzText, time(0));
- if (!db_get_b(0, MODULE, "Enabled", 1))
- {
+ if (!db_get_b(0, MODULE, "Enabled", 1)) {
mir_free(pd_out->pwzTitle);
mir_free(pd_out->pwzText);
mir_free(pd_out);
}
- else
- PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)pd_out);
+ else PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)pd_out);
}
static INT_PTR GetContact(WPARAM wParam, LPARAM lParam)
{
HWND hwndPop = (HWND)wParam;
HANDLE hContact;
- if (GetCurrentThreadId() == message_pump_thread_id) {
+ if (GetCurrentThreadId() == message_pump_thread_id)
SendMessage(hwndPop, PUM_GETCONTACT, (WPARAM)&hContact, 0);
- } else {
+ else {
HANDLE hEvent = CreateEvent(0, 0, 0, 0);
PostMessage(hwndPop, PUM_GETCONTACT, (WPARAM)&hContact, (LPARAM)hEvent);
MsgWaitForMultipleObjectsEx(1, &hEvent, INFINITE, 0, 0);
@@ -169,9 +173,9 @@ static INT_PTR GetOpaque(WPARAM wParam, LPARAM lParam) {
HWND hwndPop = (HWND)wParam;
void *data = 0;
- if (GetCurrentThreadId() == message_pump_thread_id) {
+ if (GetCurrentThreadId() == message_pump_thread_id)
SendMessage(hwndPop, PUM_GETOPAQUE, (WPARAM)&data, 0);
- } else {
+ else {
HANDLE hEvent = CreateEvent(0, 0, 0, 0);
PostMessage(hwndPop, PUM_GETOPAQUE, (WPARAM)&data, (LPARAM)hEvent);
MsgWaitForMultipleObjectsEx(1, &hEvent, INFINITE, 0, 0);
@@ -276,25 +280,25 @@ static INT_PTR PopupChangeW(WPARAM wParam, LPARAM lParam) static INT_PTR ShowMessage(WPARAM wParam, LPARAM lParam)
{
- if ( !db_get_b(0, MODULE, "Enabled", 1)) return 0;
-
- POPUPDATAT pd = {0};
- _tcscpy(pd.lptzContactName, lParam == SM_WARNING ? _T("Warning") : _T("Notification"));
- pd.lchIcon = LoadIcon(0, lParam == SM_WARNING ? IDI_WARNING : IDI_INFORMATION);
- _tcsncpy(pd.lptzText, _A2T((char *)wParam), MAX_SECONDLINE); pd.lptzText[MAX_SECONDLINE-1] = 0;
- CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pd, 0);
+ if ( db_get_b(0, MODULE, "Enabled", 1)) {
+ POPUPDATAT pd = {0};
+ _tcscpy(pd.lptzContactName, lParam == SM_WARNING ? _T("Warning") : _T("Notification"));
+ pd.lchIcon = LoadIcon(0, lParam == SM_WARNING ? IDI_WARNING : IDI_INFORMATION);
+ _tcsncpy(pd.lptzText, _A2T((char *)wParam), MAX_SECONDLINE); pd.lptzText[MAX_SECONDLINE-1] = 0;
+ CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pd, 0);
+ }
return 0;
}
static INT_PTR ShowMessageW(WPARAM wParam, LPARAM lParam)
{
- if ( !db_get_b(0, MODULE, "Enabled", 1)) return 0;
-
- POPUPDATAW pd = {0};
- wcscpy(pd.lpwzContactName, lParam == SM_WARNING ? L"Warning" : L"Notification");
- pd.lchIcon = LoadIcon(0, lParam == SM_WARNING ? IDI_WARNING : IDI_INFORMATION);
- wcsncpy(pd.lpwzText, (wchar_t *)wParam, MAX_SECONDLINE);
- CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&pd, 0);
+ if ( db_get_b(0, MODULE, "Enabled", 1)) {
+ POPUPDATAW pd = {0};
+ wcscpy(pd.lpwzContactName, lParam == SM_WARNING ? L"Warning" : L"Notification");
+ pd.lchIcon = LoadIcon(0, lParam == SM_WARNING ? IDI_WARNING : IDI_INFORMATION);
+ wcsncpy(pd.lpwzText, (wchar_t *)wParam, MAX_SECONDLINE);
+ CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&pd, 0);
+ }
return 0;
}
@@ -375,6 +379,9 @@ static INT_PTR CreateClassPopup(WPARAM wParam, LPARAM lParam) }
}
if (pc) {
+ if ( NotifyEventHooks(hEventNotify, (WPARAM)pdc->hContact, (LPARAM)pc->PluginWindowProc))
+ return 0;
+
PopupData pd = {sizeof(PopupData)};
if (pc->flags & PCF_UNICODE) pd.flags |= PDF_UNICODE;
pd.colorBack = pc->colorBack;
@@ -397,6 +404,8 @@ static INT_PTR CreateClassPopup(WPARAM wParam, LPARAM lParam) void InitServices()
{
+ hEventNotify = CreateHookableEvent(ME_POPUP_FILTER);
+
CreateServiceFunction(MS_POPUP_REGISTERCLASS, RegisterPopupClass);
CreateServiceFunction(MS_POPUP_UNREGISTERCLASS, UnregisterPopupClass);
@@ -419,6 +428,8 @@ void InitServices() void DeinitServices()
{
+ DestroyHookableEvent(hEventNotify);
+
for (int i = 0; i < arClasses.getCount(); i++)
FreePopupClass(arClasses[i]);
arClasses.destroy();
diff --git a/protocols/GTalkExt/src/handlers.cpp b/protocols/GTalkExt/src/handlers.cpp index 9f8ff03aff..9004715531 100644 --- a/protocols/GTalkExt/src/handlers.cpp +++ b/protocols/GTalkExt/src/handlers.cpp @@ -73,6 +73,8 @@ static const LPCTSTR SETTING_TRUE = _T("true"); static const DWORD RESPONSE_TIMEOUT = 1000 * 60 * 60;
static const DWORD TIMER_INTERVAL = 1000 * 60 * 2;
+LRESULT CALLBACK PopupProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
XML_API xi = {0};
#include <tchar.h>
@@ -356,6 +358,17 @@ BOOL SendHandler(IJabberInterface *ji, HXML node, void *pUserData) /////////////////////////////////////////////////////////////////////////////////////////
+int OnFilterPopup(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if ( !db_get_b(hContact, SHORT_PLUGIN_NAME, PSEUDOCONTACT_FLAG, 0))
+ return 0;
+
+ return (lParam == (LPARAM)&PopupProc);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
IJabberInterface* IsGoogleAccount(LPCSTR szModuleName)
{
IJabberInterface *japi = getJabberApi(szModuleName);
@@ -393,6 +406,7 @@ int ModulesLoaded(WPARAM wParam, LPARAM lParam) ji->Net()->AddSendHandler(SendHandler);
}
+ HookEvent(ME_POPUP_FILTER, OnFilterPopup);
HookOptionsInitialization();
return 0;
}
|