Sync to Wine-0_9_1:
authorGé van Geldorp <ge@gse.nl>
Thu, 17 Nov 2005 21:58:13 +0000 (21:58 +0000)
committerGé van Geldorp <ge@gse.nl>
Thu, 17 Nov 2005 21:58:13 +0000 (21:58 +0000)
Phil Krylov <phil@newstar.rinet.ru>
- Added support for EM_REQUESTRESIZE message, EN_REQUESTRESIZE
  notification, and ENM_REQUESTRESIZE event mask.
- Cache background color brush instead of recreating it at each screen
  update.
Mike McCormack <mike@codeweavers.com>
- Convert all RTFPanic and RTFMsg calls to ERR calls.

svn path=/trunk/; revision=19315

reactos/lib/riched20/caret.c
reactos/lib/riched20/editor.c
reactos/lib/riched20/editor.h
reactos/lib/riched20/editstr.h
reactos/lib/riched20/paint.c
reactos/lib/riched20/reader.c
reactos/lib/riched20/rtf.h
reactos/lib/riched20/wrap.c

index 9c30e5c..69c6ca1 100644 (file)
@@ -1097,6 +1097,7 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
         editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */
         ME_DeleteSelection(editor);
         ME_UpdateRepaint(editor);
+        ME_SendRequestResize(editor, FALSE);
         return TRUE;
       }
       if (ME_ArrowLeft(editor, p)) {
@@ -1105,6 +1106,7 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
         ME_MoveCaret(editor);
         ME_DeleteTextAtCursor(editor, nCursor, 1);
         ME_UpdateRepaint(editor);
+        ME_SendRequestResize(editor, FALSE);
       }
       return TRUE;
     }
@@ -1117,11 +1119,13 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
         ME_DeleteSelection(editor);
         ME_ClearTempStyle(editor);
         ME_UpdateRepaint(editor);
+        ME_SendRequestResize(editor, FALSE);
         return TRUE;
       }
       ME_DeleteTextAtCursor(editor, nCursor, 1);
       ME_ClearTempStyle(editor);
       ME_UpdateRepaint(editor);
+      ME_SendRequestResize(editor, FALSE);
       return TRUE;
     }
     case VK_HOME: {
index 07a1ee0..a25a90d 100644 (file)
@@ -83,7 +83,7 @@
   - EM_PASTESPECIAL
   + EM_POSFROMCHAR
   + EM_REDO 2.0
-  - EM_REQUESTRESIZE
+  + EM_REQUESTRESIZE
   + EM_REPLACESEL (proper style?) ANSI&Unicode
   - EM_SCROLL
   - EM_SCROLLCARET
   - EN_MSGFILTER
   - EN_OLEOPFAILED
   - EN_PROTECTED
-  - EN_REQUESTRESIZE
+  + EN_REQUESTRESIZE
   - EN_SAVECLIPBOARD
   + EN_SELCHANGE 
   + EN_SETFOCUS
@@ -633,6 +633,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
   }
   ME_MoveCaret(editor);
   ME_SendSelChange(editor);
+  ME_SendRequestResize(editor, FALSE);
 
   return 0;
 }
@@ -820,6 +821,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
   ed->nUDArrowX = -1;
   ed->nSequence = 0;
   ed->rgbBackColor = -1;
+  ed->hbrBackground = GetSysColorBrush(COLOR_WINDOW);
   ed->bCaretAtEnd = FALSE;
   ed->nEventMask = 0;
   ed->nModifyStep = 0;
@@ -925,7 +927,8 @@ void ME_DestroyEditor(ME_TextEditor *editor)
     if (editor->pFontCache[i].hFont)
       DeleteObject(editor->pFontCache[i].hFont);
   }
-    
+  DeleteObject(editor->hbrBackground);
+
   FREE_OBJ(editor);
 }
 
@@ -1134,7 +1137,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
   UNSUPPORTED_MSG(EM_HIDESELECTION)
   UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */
   UNSUPPORTED_MSG(EM_PASTESPECIAL)
-  UNSUPPORTED_MSG(EM_REQUESTRESIZE)
   UNSUPPORTED_MSG(EM_SCROLL)
   UNSUPPORTED_MSG(EM_SCROLLCARET)
   UNSUPPORTED_MSG(EM_SELECTIONTYPE)
@@ -1265,10 +1267,18 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
   case EM_SETBKGNDCOLOR:
   {
     LRESULT lColor = ME_GetBackColor(editor);
+    if (editor->rgbBackColor != -1)
+      DeleteObject(editor->hbrBackground);
     if (wParam)
+    {
       editor->rgbBackColor = -1;
+      editor->hbrBackground = GetSysColorBrush(COLOR_WINDOW);
+    }
     else
+    {
       editor->rgbBackColor = lParam;
+      editor->hbrBackground = CreateSolidBrush(editor->rgbBackColor);
+    }
     if (editor->bRedraw)
     {
       InvalidateRect(hWnd, NULL, TRUE);
@@ -1792,12 +1802,9 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
     {
       HDC hDC = (HDC)wParam;
       RECT rc;
-      COLORREF rgbBG = ME_GetBackColor(editor);
       if (GetUpdateRect(hWnd,&rc,TRUE))
       {
-        HBRUSH hbr = CreateSolidBrush(rgbBG);
-        FillRect(hDC, &rc, hbr);
-        DeleteObject(hbr);
+        FillRect(hDC, &rc, editor->hbrBackground);
       }
     }
     return 1;
@@ -1974,6 +1981,9 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
       ME_RewrapRepaint(editor);
     return 0;
   }
+  case EM_REQUESTRESIZE:
+    ME_SendRequestResize(editor, TRUE);
+    return 0;
   case WM_SETREDRAW:
     editor->bRedraw = wParam;
     return 0;
index 7229aaf..420435f 100644 (file)
@@ -173,6 +173,7 @@ ME_DisplayItem *ME_MakeRow(int height, int baseline, int width);
 void ME_InsertRowStart(ME_WrapContext *wc, ME_DisplayItem *pEnd);
 void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp);
 BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor);
+void ME_SendRequestResize(ME_TextEditor *editor, BOOL force);
 
 /* para.c */
 ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run); 
index 2e8f175..7a7398f 100644 (file)
@@ -270,6 +270,7 @@ typedef struct tagME_TextEditor
   int nSequence;
   int nOldSelFrom, nOldSelTo;
   COLORREF rgbBackColor;
+  HBRUSH hbrBackground;
   BOOL bCaretAtEnd;
   int nEventMask;
   int nModifyStep;
index c60b50d..e1c56b4 100644 (file)
@@ -78,18 +78,17 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpda
     }
 
     if (ye>ys) {
-      HBRUSH hbr;
-      hbr = CreateSolidBrush(ME_GetBackColor(c.editor));
       rc.left = xs;
       rc.top = ys;
       rc.right = xe;
       rc.bottom = ye;
-      FillRect(hDC, &rc, hbr);
-      DeleteObject(hbr);
+      FillRect(hDC, &rc, c.editor->hbrBackground);
     }
     if (ys == c.pt.y) /* don't overwrite the top bar */
       ys++;
   }
+  if (editor->nTotalLength != editor->nLastTotalLength)
+    ME_SendRequestResize(editor, FALSE);
   editor->nLastTotalLength = editor->nTotalLength;
   ME_DestroyContext(&c);
 }
index c169115..83cfb76 100644 (file)
@@ -219,7 +219,7 @@ void RTFInit(RTF_Info *info)
                info->rtfTextBuf = RTFAlloc (rtfBufSiz);
                info->pushedTextBuf = RTFAlloc (rtfBufSiz);
                if (info->rtfTextBuf == NULL || info->pushedTextBuf == NULL)
-                       RTFPanic (info,"Cannot allocate text buffers.");
+                       ERR ("Cannot allocate text buffers.");
                info->rtfTextBuf[0] = info->pushedTextBuf[0] = '\0';
        }
 
@@ -283,7 +283,7 @@ void RTFSetInputName(RTF_Info *info, char *name)
 
        info->inputName = RTFStrSave (name);
        if (info->inputName == NULL)
-               RTFPanic (info,"RTFSetInputName: out of memory");
+               ERR ("RTFSetInputName: out of memory");
 }
 
 
@@ -299,7 +299,7 @@ void RTFSetOutputName(RTF_Info *info, char *name)
 
        info->outputName = RTFStrSave (name);
        if (info->outputName == NULL)
-               RTFPanic (info, "RTFSetOutputName: out of memory");
+               ERR ("RTFSetOutputName: out of memory");
 }
 
 
@@ -388,7 +388,7 @@ void RTFRouteToken(RTF_Info *info)
 
        if (info->rtfClass < 0 || info->rtfClass >= rtfMaxClass)        /* watchdog */
        {
-               RTFPanic (info,"Unknown class %d: %s (reader malfunction)",
+               ERR( "Unknown class %d: %s (reader malfunction)",
                                                        info->rtfClass, info->rtfTextBuf);
        }
        if (RTFCheckCM (info, rtfControl, rtfDestination))
@@ -490,9 +490,9 @@ void RTFUngetToken(RTF_Info *info)
        TRACE("\n");
 
        if (info->pushedClass >= 0)     /* there's already an ungotten token */
-               RTFPanic (info,"cannot unget two tokens");
+               ERR ("cannot unget two tokens");
        if (info->rtfClass < 0)
-               RTFPanic (info,"no token to unget");
+               ERR ("no token to unget");
        info->pushedClass = info->rtfClass;
        info->pushedMajor = info->rtfMajor;
        info->pushedMinor = info->rtfMinor;
@@ -600,7 +600,7 @@ RTFCharSetToCodePage(RTF_Info *info, int charset)
                         /* FIXME: TranslateCharsetInfo does not work as good as it
                          * should, so let's use it only when all else fails */
                         if (!TranslateCharsetInfo(&n, &csi, TCI_SRCCHARSET))
-                               RTFMsg(info, "%s: unknown charset %u\n", __FUNCTION__, charset);
+                               ERR("%s: unknown charset %u\n", __FUNCTION__, charset);
                        else
                                 return csi.ciACP;
                }
@@ -893,19 +893,19 @@ static void ReadFontTbl(RTF_Info *info)
                        else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup))
                                old = 0;        /* brace */
                        else                    /* can't tell! */
-                               RTFPanic (info, "%s: Cannot determine format", fn);
+                               ERR ( "%s: Cannot determine format", fn);
                }
                if (old == 0)           /* need to find "{" here */
                {
                        if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
-                               RTFPanic (info, "%s: missing \"{\"", fn);
+                               ERR ( "%s: missing \"{\"", fn);
                        RTFGetToken (info);     /* yes, skip to next token */
                        if (info->rtfClass == rtfEOF)
                                break;
                }
                fp = New (RTFFont);
                if (fp == NULL)
-                       RTFPanic (info, "%s: cannot allocate font entry", fn);
+                       ERR ( "%s: cannot allocate font entry", fn);
 
                fp->rtfNextFont = info->fontList;
                info->fontList = fp;
@@ -929,8 +929,8 @@ static void ReadFontTbl(RTF_Info *info)
                                {
                                default:
                                        /* ignore token but announce it */
-                                       RTFMsg (info,"%s: unknown token \"%s\"\n",
-                                                       fn, info->rtfTextBuf);
+                                       ERR ("%s: unknown token \"%s\"\n",
+                                               fn, info->rtfTextBuf);
                                         break;
                                case rtfFontFamily:
                                        fp->rtfFFamily = info->rtfMinor;
@@ -991,7 +991,7 @@ static void ReadFontTbl(RTF_Info *info)
                                *bp = '\0';
                                fp->rtfFName = RTFStrSave (buf);
                                if (fp->rtfFName == NULL)
-                                       RTFPanic (info, "%s: cannot allocate font name", fn);
+                                       ERR ( "%s: cannot allocate font name", fn);
                                /* already have next token; don't read one */
                                /* at bottom of loop */
                                continue;
@@ -999,7 +999,7 @@ static void ReadFontTbl(RTF_Info *info)
                        else
                        {
                                /* ignore token but announce it */
-                               RTFMsg (info, "%s: unknown token \"%s\"\n",
+                               ERR ( "%s: unknown token \"%s\"\n",
                                                        fn,info->rtfTextBuf);
                        }
                        RTFGetToken (info);
@@ -1012,7 +1012,7 @@ static void ReadFontTbl(RTF_Info *info)
                {
                        RTFGetToken (info);
                        if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
-                               RTFPanic (info, "%s: missing \"}\"", fn);
+                               ERR ( "%s: missing \"}\"", fn);
                        if (info->rtfClass == rtfEOF)
                                break;
                }
@@ -1026,7 +1026,7 @@ static void ReadFontTbl(RTF_Info *info)
                 }
        }
        if (fp->rtfFNum == -1)
-               RTFPanic (info,"%s: missing font number", fn);
+               ERR( "%s: missing font number", fn);
 /*
  * Could check other pieces of structure here, too, I suppose.
  */
@@ -1068,7 +1068,7 @@ static void ReadColorTbl(RTF_Info *info)
                        break;
                cp = New (RTFColor);
                if (cp == NULL)
-                       RTFPanic (info,"%s: cannot allocate color entry", fn);
+                       ERR ( "%s: cannot allocate color entry", fn);
                cp->rtfCNum = cnum++;
                cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1;
                cp->rtfNextColor = info->colorList;
@@ -1086,7 +1086,7 @@ static void ReadColorTbl(RTF_Info *info)
                if (info->rtfClass == rtfEOF)
                        break;
                if (!RTFCheckCM (info, rtfText, ';'))
-                       RTFPanic (info,"%s: malformed entry", fn);
+                       ERR ("%s: malformed entry", fn);
        }
        RTFRouteToken (info);   /* feed "}" back to router */
 }
@@ -1116,7 +1116,7 @@ static void ReadStyleSheet(RTF_Info *info)
                        break;
                sp = New (RTFStyle);
                if (sp == NULL)
-                       RTFPanic (info,"%s: cannot allocate stylesheet entry", fn);
+                       ERR ( "%s: cannot allocate stylesheet entry", fn);
                sp->rtfSName = NULL;
                sp->rtfSNum = -1;
                sp->rtfSType = rtfParStyle;
@@ -1128,7 +1128,7 @@ static void ReadStyleSheet(RTF_Info *info)
                sp->rtfExpanding = 0;
                info->styleList = sp;
                if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
-                       RTFPanic (info,"%s: missing \"{\"", fn);
+                       ERR ( "%s: missing \"{\"", fn);
                real_style = TRUE;
                for (;;)
                {
@@ -1140,7 +1140,7 @@ static void ReadStyleSheet(RTF_Info *info)
                        {
                                if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest)) {
                                        RTFGetToken(info);
-                                       RTFPanic(info, "%s: skipping optional destination", fn);
+                                       ERR( "%s: skipping optional destination", fn);
                                        RTFSkipGroup(info);
                                        info->rtfClass = rtfGroup;
                                        info->rtfMajor = rtfEndGroup;
@@ -1182,14 +1182,14 @@ static void ReadStyleSheet(RTF_Info *info)
                                }
                                sep = New (RTFStyleElt);
                                if (sep == NULL)
-                                       RTFPanic (info,"%s: cannot allocate style element", fn);
+                                       ERR ( "%s: cannot allocate style element", fn);
                                sep->rtfSEClass = info->rtfClass;
                                sep->rtfSEMajor = info->rtfMajor;
                                sep->rtfSEMinor = info->rtfMinor;
                                sep->rtfSEParam = info->rtfParam;
                                sep->rtfSEText = RTFStrSave (info->rtfTextBuf);
                                if (sep->rtfSEText == NULL)
-                                       RTFPanic (info,"%s: cannot allocate style element text", fn);
+                                       ERR ( "%s: cannot allocate style element text", fn);
                                if (sepLast == NULL)
                                        sp->rtfSSEList = sep;   /* first element */
                                else                            /* add to end */
@@ -1203,7 +1203,7 @@ static void ReadStyleSheet(RTF_Info *info)
                                 * This passes over "{\*\keycode ... }, among
                                 * other things. A temporary (perhaps) hack.
                                 */
-                                RTFPanic(info, "%s: skipping begin", fn);
+                                ERR( "%s: skipping begin", fn);
                                RTFSkipGroup (info);
                                continue;
                        }
@@ -1224,19 +1224,19 @@ static void ReadStyleSheet(RTF_Info *info)
                                *bp = '\0';
                                sp->rtfSName = RTFStrSave (buf);
                                if (sp->rtfSName == NULL)
-                                       RTFPanic (info, "%s: cannot allocate style name", fn);
+                                       ERR ( "%s: cannot allocate style name", fn);
                        }
                        else            /* unrecognized */
                        {
                                /* ignore token but announce it */
-                               RTFMsg (info, "%s: unknown token \"%s\"\n",
+                               ERR ( "%s: unknown token \"%s\"\n",
                                                        fn, info->rtfTextBuf);
                        }
                }
                if (real_style) {
                        RTFGetToken (info);
                        if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
-                               RTFPanic (info, "%s: missing \"}\"", fn);
+                               ERR ( "%s: missing \"}\"", fn);
                        /*
                         * Check over the style structure.  A name is a must.
                         * If no style number was specified, check whether it's the
@@ -1248,12 +1248,12 @@ static void ReadStyleSheet(RTF_Info *info)
                         * Some German RTF writers use "Standard" instead of "Normal".
                         */
                        if (sp->rtfSName == NULL)
-                               RTFPanic (info,"%s: missing style name", fn);
+                               ERR ( "%s: missing style name", fn);
                        if (sp->rtfSNum < 0)
                        {
                                if (strncmp (buf, "Normal", 6) != 0
                                        && strncmp (buf, "Standard", 8) != 0)
-                                       RTFPanic (info,"%s: missing style number", fn);
+                                       ERR ( "%s: missing style number", fn);
                                sp->rtfSNum = rtfNormalStyleNum;
                        }
                        if (sp->rtfSNextPar == -1)      /* if \snext not given, */
@@ -1359,7 +1359,7 @@ void RTFExpandStyle(RTF_Info *info, int n)
        if (s == NULL)
                return;
        if (s->rtfExpanding != 0)
-               RTFPanic (info,"Style expansion loop, style %d", n);
+               ERR ("Style expansion loop, style %d", n);
        s->rtfExpanding = 1;    /* set expansion flag for loop detection */
        /*
         * Expand "based-on" style (unless it's the same as the current
@@ -2443,63 +2443,6 @@ int RTFHexToChar(int i)
 }
 
 
-/* ---------------------------------------------------------------------- */
-
-/*
- * Print message.
- *
- * Message should include linefeeds as necessary.
- */
-
-
-void RTFMsg (RTF_Info *info, const char *fmt, ...)
-{
-       char    buf[rtfBufSiz];
-
-       va_list args;
-       va_start (args,fmt);
-       vsprintf (buf, fmt, args);
-       va_end (args);
-       MESSAGE( "%s", buf);
-}
-
-
-/* ---------------------------------------------------------------------- */
-
-
-/*
- * Process termination.  Print error message and exit.  Also prints
- * current token, and current input line number and position within
- * line if any input has been read from the current file.  (No input
- * has been read if prevChar is EOF).
- */
-
-static void DefaultPanicProc(RTF_Info *info, char *s)
-{
-       MESSAGE( "%s", s);
-       /*exit (1);*/
-}
-
-
-
-void RTFPanic(RTF_Info *info, const char *fmt, ...)
-{
-       char    buf[rtfBufSiz];
-
-       va_list args;
-       va_start (args,fmt);
-       vsprintf (buf, fmt, args);
-       va_end (args);
-       lstrcatA (buf, "\n");
-       if (info->prevChar != EOF && info->rtfTextBuf != NULL)
-       {
-               sprintf (buf + lstrlenA (buf),
-                       "Last token read was \"%s\" near line %ld, position %d.\n",
-                       info->rtfTextBuf, info->rtfLineNum, info->rtfLinePos);
-       }
-       DefaultPanicProc(info, buf);
-}
-
 /* ---------------------------------------------------------------------- */
 
 /*
@@ -2594,7 +2537,7 @@ CharAttr(RTF_Info *info)
                         TRACE("font %d codepage %d\n", info->rtfParam, info->codePage);
                 }
                 else
-                        RTFMsg(info, "unknown font %d\n", info->rtfParam);
+                        ERR( "unknown font %d\n", info->rtfParam);
                 break;
         case rtfUnicodeLength:
                 info->unicodeLength = info->rtfParam;
index d3720be..611ce9a 100644 (file)
@@ -1093,8 +1093,6 @@ struct _RTF_Info {
 
     RTFFuncPtr       readHook;
 
-    RTFFuncPtr       panicProc;
-
     DWORD    dwOutputCount;
     WCHAR    OutputBuffer[0x1000];
 
@@ -1140,18 +1138,6 @@ RTFColor *RTFGetColor (RTF_Info *, int);
 RTFStyle       *RTFGetStyle (RTF_Info *, int);
 int            RTFCharToHex ( char);
 int            RTFHexToChar ( int );
-void           RTFSetMsgProc ( RTFFuncPtr );
-void           RTFSetPanicProc ( RTF_Info *, RTFFuncPtr);
-
-/*
- * The following messing around is used to allow RTFMsg() and RTFPanic()
- * to be variable-argument functions that are declared publicly but
- * without generating prototype-mismatch errors on systems that have
- * stdarg.h.
- */
-
-void   RTFMsg (RTF_Info *, const char *fmt, ...);
-void   RTFPanic (RTF_Info *, const char *fmt, ...);
 
 void   RTFFlushOutputBuffer( RTF_Info *info );
 void   RTFSetEditStream(RTF_Info *info, ME_InStream *stream);
index 2da74a1..4ea9ac4 100644 (file)
@@ -448,9 +448,36 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
   }
   editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
   editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
+  
   editor->nTotalLength = c.pt.y;
 
   ME_DestroyContext(&c);
   ReleaseDC(hWnd, hDC);
   return bModified;
 }
+
+
+void
+ME_SendRequestResize(ME_TextEditor *editor, BOOL force)
+{
+  if (editor->nEventMask & ENM_REQUESTRESIZE)
+  {
+    RECT rc;
+
+    GetClientRect(editor->hWnd, &rc);
+
+    if (force || rc.bottom != editor->nTotalLength)
+    {
+      REQRESIZE info;
+
+      info.nmhdr.hwndFrom = editor->hWnd;
+      info.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
+      info.nmhdr.code = EN_REQUESTRESIZE;
+      info.rc = rc;
+      info.rc.bottom = editor->nTotalLength;
+    
+      SendMessageW(GetParent(editor->hWnd), WM_NOTIFY,
+                   info.nmhdr.idFrom, (LPARAM)&info);
+    }
+  }
+}