#include "datalib0.h" /* DataLib definition */ #include "curve0.h" /* CurrentCurveData definition */ #include "visual0.h" /* Callbacks for visual functions */ /* This structure is used to pass data from the kernel to window libraries */ typedef struct { WindoW Win; MenuDesc MenuDesc; /* private copy of MenuDesc and MenuItems array */ CharPtr WinTitle; /* Title of the window */ RecT Position; /* Origin of the window and dimensions of its client area */ #define Left Position.left #define Top Position.top #define Width Position.right #define Height Position.bottom Color Colors[2]; /* colors */ #define Foreground Colors[0] #define Background Colors[1] Int2 flags; /* Command and Status flags */ #define WFL_HIDDEN 0x0001 /* Window is hidden */ #define WFL_DONT_RESIZE 0x0002 /* Ignore resize event/message. Set by CreateWin to supress first call of ResizeProc after window has been created. */ #define WFL_DONT_REDRAW 0x0004 /* Set by ResizeProc to ensure only one redraw of the Slate during ResizeProc will be caused by Upadte. */ #define WFL_FUNC_EDITED 0x0008 /* Window function was edited; recompile */ #define WFL_G1 0x0010 /* First G-point on curve */ #define WFL_M1 0x0020 /* First M-point in G-point */ #define WFL_RESIZE 0x0040 /* ResizeProc is in progress */ #define WFL_GDIM1 0x0080 /* Must be set by SimpleFunctions if only vars with Gdim==1 are used by this window */ #define WFL_FROZEN 0x0100 /* Window's Status function returns FALSE */ #define WFL_NOTACTIVE 0x0200 /* was deactivated by DeactivateWindows() */ Int2 BorderHeight,BorderWidth;/* window border's height and width */ Uint1 Unique; /* unique number used to construct window function names */ VoidPtr Private; /* Window's private data. Must be allocated via MemNew */ } WinComData, PNTR WinComDataPtr; /* Some useful subroutines from the kernel. Pointer to this structure is passed to the 'Get Class Table' function. */ typedef struct _Util { /*---------*/ /* DataLib */ /* DiagramLib */ DataLibPtr DiagramLib; /* Len of last VRecord read */ size_t PNTR DataLibLastVRecLen; CharPtr (*DataLibReadVRecord)(DataLibPtr dl, CharPtr partition); Int2 (*DataLibWriteVRecord)(DataLibPtr dl, CharPtr partition, CharPtr buf, size_t len); size_t (*DataLibRead)(DataLibPtr dl, CharPtr buf, size_t len); size_t (*DataLibWrite)(DataLibPtr dl, CharPtr buf, size_t len); void (*DataLibSavePos)(DataLibPtr dl); void (*DataLibRestorePos)(DataLibPtr dl); Int2 (*DataLibSeek)(DataLibPtr dl, DataLibPosPtr pos); /*------------------*/ /* Menu item/status */ /* Compute forward */ void (*Forward)(Int2 i); /* Compute backward */ void (PNTR Backward)(Int2 i); /* Status of forward/backward */ Boolean (*FBStatus)(Int2 i); /* Extend curve */ void (*Extend)(Int2 i); /* Status of extend */ Boolean (*ExtendStatus)(Int2 i); /* Redraw diagram */ void (*RedrawDiagram)(Int2 i); /* Status of redraw diagram */ Boolean (*RedrawDStatus)(Int2 i); /* Redraw curve */ void (*RedrawCurve)(Int2 i); /* Status of redraw curve */ Boolean (*RedrawCStatus)(Int2 i); /* Clear All windows */ void (*ClearAll)(Int2 i); /* Status of Hardcopy */ Boolean (*HardcopyStatus)(Int2 i); /* Hides the window */ void (*HideWin)(Int2 index); /*---------------*/ /* Help routines */ /* Show Help topic */ void (*Help)(CharPtr key); /* Open Search Help topic window */ void (*HelpSearch)(CharPtr key); /*---------------*/ /* Visible names */ /* Abs index of visible class is its index in the list of ALL visible classes (as listed in appropriate .con file for class of dynamic system, e.g. ode_g.con). Rel index of visible class is its index in the list of visible classes used by particular starter/generator pair (as listed in appropriate .con file for point/curve combination, e.g. __ep.con. */ /* abs index of Class-th relvant visual class or -1, Class=0,... */ Int2 (*GetNthRelevantClass)(Int2 Class); /* Returns name and unique id of the class given by abs index, Class=0,... */ Boolean (*GetClassNameAndId)(Int2 Class, CharPtr PNTR name, Uint2Ptr id); /* Returns dim of visible class. If *Class==0 then 2-bytes RealId follows */ Int2Ptr (*GetClassDim)(CharPtr Class); /* Returns name and dimension of visible name from class-th relevant class, class=0,... */ void (*GetNameAndDim)(Int2 class, Int2 var, CharPtr PNTR name, Int2Ptr dim); /* Is the class with realId relevant */ Int2 (*IsClassRelevant)(Uint2 realId); /* Enumerates all relevant visible classes */ void (*EnumClasses)(LisT List, ProcClassPtr proc); /* Enumerates all variables from given class */ void (*EnumVariables)(LisT List, Int2 Class, ProcVariablesPtr proc); /* Translates RealId of class to rel index of class */ Uint1 (*ClassGlobToLoc)(Int2 RealId); /* Returns starter/generator 's vector corresponding to the class with given rel index */ FloatHiPtr (*GetLocalClassVector)(Uint1 localclass); /* Updates coord of init point in starter/generator windows */ void (*UpdateInitPoint)(void); /*-------*/ /* Color */ /* Gets the numbers of colors available */ Int2 (*ColorNumber)(void); /* Sets i-th color */ void (*ColorSet)(Color i); /* access to black and white */ ColorPtr BlackIndex,WhiteIndex; /* Color representation: external --> internal */ Color (*ColorIn)(long rgb); /* Color representation: internal --> external */ long (*ColorOut)(Color i); /* Ask the color */ Color (*ColorAsk)(Color InitColor); /*------*/ /* Draw */ /* Sets pen's attributes */ void (*SetCurrentPen)(DrawAttrPtr attr); /*----------------*/ /* Special points */ /* Checks whether the given point is not 'far' from a special point */ Boolean (*PtNearSpecial)(PoinT pt, PoinT sppt); /* Sets new initial point */ Boolean (*SetSpecialPoint)(FilePtr curvePtr, Int2 pointNum); /* Draws special point (marker,label, hardcopy included) */ void (*DrawSpecialPoint)(Int2 x, Int2 y, Int2 pointtype, Color bg, Boolean labelyes); /* Store coord of last ordinary point before a special one; used by DrawMarker when it decides where to place label */ void (*SpecialPointPrev)(Int2 idX, Int2 idY, FloatHi fdX, FloatHi fdY, FloatHi deltaX, FloatHi deltaY); /* Is there a marker associated with the given (global) type of point? */ Boolean (*IsMarker)(Int2 pointtype); /* Access to the list of special points of the current curve */ void (*ReadSPList)(Int2Ptr num, DataLibPosPtr PNTR list); void (*FreeSPList)(Int2 num, DataLibPosPtr list); /* Returns label and color of special point of the given global type */ Boolean (*GetSPAttr)(Int2 type, CharPtr PNTR Label, ColorPtr Color); /* Returns a title of special point given by local type */ CharPtr (*GetSPname)(Pointtype localtype, Boolean Full); /*------*/ /* Misc */ /* Recreates window's controls an recompile if necessary */ void (*RecreateWindow)(WinComDataPtr wcd); /* Pushes context (help environment, keys, info msg */ void (*PushContext)(CharPtr HelpCode, KeyProc KeyAction, CharPtr Text); /* Pops pushed context */ void (*PopContext)(void); /* G-dimension of expr is 1? */ Boolean (*GdimEq1)(CharPtr expr); /* G-dimension of curve is more then 1? */ Boolean (*IsDimGMore1)(void); /* Locks menus in all windows */ void (*LockMenus)(void); /* Unlocks menus in all windows */ void (*UnlockMenus)(void); /* refreshes menus in all windows */ void (*RefreshMenus)(void); /* Enables/Disables items depending on their status functions */ void (*SetStatusOfItems)(MenuDescPtr pmd); /* Creates Normal group with margins and spacing */ GrouP (*CreateNormalGroup)(GrouP parent, Int2 x, Int2 y, CharPtr title); /* Creates Hidden group with margins and spacing */ GrouP (*CreateHiddenGroup)(GrouP parent, Int2 x, Int2 y, Int2 vspace); /* Returns groups spacing/margins */ Int2 (*GetGroupSM)(CharPtr SMCode); /* Creates Ok/Cancel/Help buttons */ GrouP (*TerminalButtons)(WindoW win, GrouP samewidth, BtnActnProc Ok, BtnActnProc Cancel,BtnActnProc Help); /* Creates SingleList of visible names */ LisT (*CreateNamesList)(GrouP g, Int2 width, Int2 height, LstNotifyProc NorifyProc, LstCountSelProc CountSelProc); /* Creates MultiList of visible names */ LisT (*MultiNamesList)(GrouP g, PairPtr PNTR selection); /* Retrievs text from TexT object */ void (*GetTitleAndSave)(TexT t, CharPtr PNTR indirptr); /* Counts lines in text and removes \r's */ CharPtr (*CountLinesAndErase_r)(CharPtr p, Char c, Int2Ptr LineCount); /* Locates function Name in dyn library hLib */ void (*(*LibraryFuncAddress)(LibHandle hLib, CharPtr Name))(); /* Properties of current curve */ CurrentCurveDataPtr ccd; /* Adr of ptr to array of ptrs to vectors of values */ FloatHiPtr PNTR PNTR PNTR IndirectValues; /* number of current M-point in current G-point */ Int2Ptr curveCurNum; /* Is there current curve? */ Boolean *CurCurve; /* Compiler of expressions */ Int2 (*ComputeExpr)(CharPtr source, FloatHiPtr res); /* Gets abs index of class and offset for a name; name is simple when returns TRUE */ Boolean (*ParseName)(CharPtr func, Int2Ptr p_index, Uint2Ptr p_offset); /* Mark bifurcation data obsolete */ void (*InvalidateBifData)(void); /* Sets/resets hardcopy mode for the window */ void (*hcSetMode)(WinComDataPtr wcd, FILE PNTR Stream); /* Ptrs to list of font names and their number */ CharPtr PNTR *hcFontList; Int2 *hcFontNum; /* Access the list of visual attributes of current curve */ void (*ReadVAList)(Int2 num, ByteStorePtr PNTR PNTR list); void (*WriteVAList)(Int2 num, ByteStorePtr PNTR list); void (*FreeVAList)(Int2 num, ByteStorePtr PNTR list); /* Save/restore current visual attributes */ void (*PushVisualAttr)(Boolean freemem); void (*PopVisualAttr)(void); /* Save/restores curve's visual attributes for all windows */ void (*SaveVisualAttr)(DataLibPtr dl, ByteStorePtr from, ByteStorePtr to, Boolean freemem); void (*RestoreVisualAttr)(DataLibPtr dl, ByteStorePtr from, ByteStorePtr to); /* Duplicates window (creates exact copy of it) */ Boolean (*DuplicateWindow)(WinComDataPtr wcd, VoidPtr private); /* Rhs of current dynamical system. Must be called as described in appropriate class desc file */ /* pointer to functions that describes dynamical system */ IntFuncEntry *Rhs; /* see stagen.h */ /* Critical regions */ void (*StartCR)(jmp_buf PNTR pretenv, void (*callback)(int sig)); void (*EndCR)(void); /* Windows */ void (*DeactivateWindows)(WinComDataPtr wcd); void (*ActivateWindows)(void); /* */ void (*Dummy)(void); } Util, PNTR UtilPtr; /* Members of window class. GetClassTable function returns pointer to this table. A window function is user-specified fucntion (the user usually gives its body only) which is internally constructed, compiled and used by the class members to compute external representation of curve's points, e.g. numbers. A window of the given class may have any number of window functions (0,1, or more). */ typedef struct { /* Creates private data area and fills it with defaults */ void (* BuildDefaultDescription)(WinComDataPtr wcd); /* Creates private data area and fills it with data from archive */ void (* ReadDescription)(WinComDataPtr wcd, DataLibPtr arch); /* Writes data (if arch!=NULL) and frees memory */ void (* WriteDescription)(WinComDataPtr wcd, DataLibPtr arch); /* Creates controls */ void (* CreateControls)(WinComDataPtr wcd); /* Removes controls */ void (* RemoveControls)(WinComDataPtr wcd); /* Enable/Disable controls */ void (* ManageControls)(WinComDataPtr wcd, Boolean enable); /* Builds private copy of menu and sets window title */ void (* BuildMenu)(WinComDataPtr wcd); /* Notification routine. Called after the initial point has been changed */ void (* NewInitPoint)(WinComDataPtr wcd); /* Clears the window */ void (* ClearWindow)(WinComDataPtr wcd); /* Tests: are all window functions simple variables */ Boolean (* SimpleFunctions)(WinComDataPtr wcd); /* Outputs C text of windows functions */ void (* PutFunctions)(WinComDataPtr wcd, FILE PNTR Source, Int2Ptr LineNum); /* Locates window functions in window library */ void (* SetFunctions)(WinComDataPtr wcd, LibHandle hWinLib); /* Exports description of the window */ void (* ExportDescription)(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR out); /* Imports description of the window */ void (* ImportDescription)(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR in); /* Writes visual attribute stored with a curve */ /* from==NULL means "take current", otherwise BSRead(from) */ /* to==NULL - DataLibWrite(dgm), otherwise BSWrite(to) */ void (* SaveAttr)(WinComDataPtr wcd, DataLibPtr dgm, ByteStorePtr from, ByteStorePtr to, Boolean freemem); /* Restores visualizer's attribute stored with a curve */ /* from==NULL - DataLibRead(dgm), otherwise BSRead(from) */ /* to=NULL - restore to current, otherwise BSWrite(to) */ void (* RestoreAttr)(WinComDataPtr wcd, DataLibPtr dgm, ByteStorePtr from, ByteStorePtr to, Boolean skip); /* Exports attributes */ void (* ExportAttr)(WinComDataPtr wcd, DataLibPtr dgm, FILE PNTR out); /* Imports attributes */ void (* ImportAttr)(WinComDataPtr wcd, DataLibPtr dgm, FILE PNTR in); /* Temporary stores attributes */ void (* PushAttr)(WinComDataPtr wcd, Boolean freemem); /* Restores */ void (* PopAttr)(WinComDataPtr wcd); /* Performs special action */ void (* SpecialAction)(WinComDataPtr wcd, VisualSpecAction vsa); /* Called when a curve is about to be deleted */ void (* FreeCurveData)(WinComDataPtr wcd, FilePtr fp); /* Called before processing of G-point */ void (* GInit)(WinComDataPtr wcd); /* Called after processing of G-point */ void (* GTerm)(WinComDataPtr wcd); /* Called before processing of M-point */ void (* MInit)(WinComDataPtr wcd); /* Called after processing of M-point */ void (* MTerm)(WinComDataPtr wcd); /* Called to process M-point */ void (PNTR MProcess)(WinComDataPtr wcd); /* Hardcopy members used to draw markers */ void (PNTR hcPen)(WinComDataPtr wcd, DrawAttrPtr attr); void (PNTR hcString)(WinComDataPtr wcd, CharPtr str, float PNTR data); void (PNTR hcPaintOval)(WinComDataPtr wcd, RectPtr r); void (PNTR hcFrameOval)(WinComDataPtr wcd, RectPtr r); void (PNTR hcPaintPoly)(WinComDataPtr wcd, Int2 num, PointPtr poly); void (PNTR hcFramePoly)(WinComDataPtr wcd, Int2 num, PointPtr poly); /* The last */ void (PNTR Dummy)(void); } ClassFunc, PNTR ClassFuncPtr; #define WHM 1 /* window horizontal margin */ #define WVM 1 /* window vertical margin */ #define NOUPDATE DBL_MAX /* this value means "don't update" */ #if defined(KERNEL) #if LINKIN Entry(ClassFuncPtr) g2d_GetClassTable(UtilPtr utility); Entry(ClassFuncPtr) num_GetClassTable(UtilPtr utility); Entry(ClassFuncPtr) tab_GetClassTable(UtilPtr utility); Entry(ClassFuncPtr) s1d_GetClassTable(UtilPtr utility); Entry(ClassFuncPtr) g3d_GetClassTable(UtilPtr utility); #endif #else /* defined(KERNEL) */ #define ClassMember Local /* to distinguish member functions */ ClassMember(void) BuildDefaultDescription(WinComDataPtr wcd); ClassMember(void) ReadDescription(WinComDataPtr wcd, DataLibPtr arch); ClassMember(void) WriteDescription(WinComDataPtr wcd, DataLibPtr arch); ClassMember(void) CreateControls(WinComDataPtr wcd); ClassMember(void) RemoveControls(WinComDataPtr wcd); ClassMember(void) ManageControls(WinComDataPtr wcd, Boolean enable); ClassMember(void) BuildMenu(WinComDataPtr wcd); ClassMember(void) NewInitPoint(WinComDataPtr wcd); ClassMember(void) ClearWindow(WinComDataPtr wcd); ClassMember(Boolean) SimpleFunctions(WinComDataPtr wcd); ClassMember(void) PutFunctions(WinComDataPtr wcd, FILE PNTR Source,Int2Ptr LineNum); ClassMember(void) SetFunctions(WinComDataPtr wcd, LibHandle hWinLib); ClassMember(void) ExportDescription(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR out); ClassMember(void) ImportDescription(WinComDataPtr wcd, DataLibPtr arch, FILE PNTR in); ClassMember(void) SaveAttr(WinComDataPtr wcd, DataLibPtr dgm, ByteStorePtr from, ByteStorePtr to, Boolean freemem); ClassMember(void) RestoreAttr(WinComDataPtr wcd, DataLibPtr dgm, ByteStorePtr from, ByteStorePtr to, Boolean skip); ClassMember(void) ExportAttr(WinComDataPtr wcd, DataLibPtr dgm, FILE PNTR out); ClassMember(void) ImportAttr(WinComDataPtr wcd, DataLibPtr dgm, FILE PNTR in); ClassMember(void) PushAttr(WinComDataPtr wcd, Boolean freemem); ClassMember(void) PopAttr(WinComDataPtr wcd); ClassMember(void) SpecialAction(WinComDataPtr wcd, VisualSpecAction vsa); ClassMember(void) FreeCurveData(WinComDataPtr wcd, FilePtr fp); ClassMember(void) GInit(WinComDataPtr wcd); ClassMember(void) GTerm(WinComDataPtr wcd); ClassMember(void) MInit(WinComDataPtr wcd); ClassMember(void) MTerm(WinComDataPtr wcd); ClassMember(void) MProcess(WinComDataPtr wcd); ClassMember(void) hcPen(WinComDataPtr wcd, DrawAttrPtr attr); ClassMember(void) hcString(WinComDataPtr wcd, CharPtr str, float PNTR data); ClassMember(void) hcPaintOval(WinComDataPtr wcd, RectPtr r); ClassMember(void) hcFrameOval(WinComDataPtr wcd, RectPtr r); ClassMember(void) hcPaintPoly(WinComDataPtr wcd, Int2 num, PointPtr poly); ClassMember(void) hcFramePoly(WinComDataPtr wcd, Int2 num, PointPtr poly); Local(ClassFunc) Members={ BuildDefaultDescription, ReadDescription, WriteDescription, CreateControls, RemoveControls, ManageControls, BuildMenu, NewInitPoint, ClearWindow, SimpleFunctions, PutFunctions, SetFunctions, ExportDescription, ImportDescription, SaveAttr, RestoreAttr, ExportAttr, ImportAttr, PushAttr, PopAttr, SpecialAction, FreeCurveData, GInit, GTerm, MInit, MTerm, MProcess, hcPen, hcString, hcPaintOval, hcFrameOval, hcPaintPoly, hcFramePoly, NULL }; /* Pointer to access utilities */ Local(UtilPtr) Utility; #ifndef GET_CLASS_TABLE #error GET_CLASS_TABLE must be defined #endif /* Returns the class members table */ Entry(ClassFuncPtr) GET_CLASS_TABLE(UtilPtr utility) { Utility=utility; return &Members; } /* #defines for Utilities */ #define DiagramLib (*Utility->DiagramLib) #define DataLibLastVRecLen *Utility->DataLibLastVRecLen #define DataLibReadVRecord Utility->DataLibReadVRecord #define DataLibWriteVRecord Utility->DataLibWriteVRecord #define DataLibRead Utility->DataLibRead #define DataLibWrite Utility->DataLibWrite #define DataLibSavePos Utility->DataLibSavePos #define DataLibRestorePos Utility->DataLibRestorePos #define DataLibSeek Utility->DataLibSeek #define Forward Utility->Forward #define Backward Utility->Backward #define FBStatus Utility->FBStatus #define Extend Utility->Extend #define ExtendStatus Utility->ExtendStatus #define RedrawDiagram Utility->RedrawDiagram #define RedrawDStatus Utility->RedrawDStatus #define RedrawCurve Utility->RedrawCurve #define RedrawCStatus Utility->RedrawCStatus #define ClearAll Utility->ClearAll #define HardcopyStatus Utility->HardcopyStatus #define HideWin Utility->HideWin #define Help Utility->Help #define HelpSearch Utility->HelpSearch #define GetNthRelevantClass Utility->GetNthRelevantClass #define GetClassNameAndId Utility->GetClassNameAndId #define GetClassDim Utility->GetClassDim #define GetNameAndDim Utility->GetNameAndDim #define IsClassRelevant Utility->IsClassRelevant #define EnumClasses Utility->EnumClasses #define EnumVariables Utility->EnumVariables #define ClassGlobToLoc Utility->ClassGlobToLoc #define GetLocalClassVector Utility->GetLocalClassVector #define UpdateInitPoint Utility->UpdateInitPoint #define ColorNumber Utility->ColorNumber #define ColorSet Utility->ColorSet #define BlackIndex (*Utility->BlackIndex) #define WhiteIndex (*Utility->WhiteIndex) #define ColorIn Utility->ColorIn #define ColorOut Utility->ColorOut #define ColorAsk Utility->ColorAsk #define SetCurrentPen Utility->SetCurrentPen #define PtNearSpecial Utility->PtNearSpecial #define SetSpecialPoint Utility->SetSpecialPoint #define DrawSpecialPoint Utility->DrawSpecialPoint #define SpecialPointPrev Utility->SpecialPointPrev #define IsMarker Utility->IsMarker #define ReadSPList Utility->ReadSPList #define FreeSPList Utility->FreeSPList #define GetSPAttr Utility->GetSPAttr #define GetSPname Utility->GetSPname #define RecreateWindow Utility->RecreateWindow #define PushContext Utility->PushContext #define PopContext Utility->PopContext #define GdimEq1 Utility->GdimEq1 #define IsDimGMore1 Utility->IsDimGMore1 #define LockMenus Utility->LockMenus #define UnlockMenus Utility->UnlockMenus #define RefreshMenus Utility->RefreshMenus #define SetStatusOfItems Utility->SetStatusOfItems #define CreateNormalGroup Utility->CreateNormalGroup #define CreateHiddenGroup Utility->CreateHiddenGroup #define GetGroupSM Utility->GetGroupSM #define TerminalButtons Utility->TerminalButtons #define CreateNamesList Utility->CreateNamesList #define MultiNamesList Utility->MultiNamesList #define GetTitleAndSave Utility->GetTitleAndSave #define CountLinesAndErase_r Utility->CountLinesAndErase_r #define LibraryFuncAddress Utility->LibraryFuncAddress #define ccd (*Utility->ccd) #define IndirectValues (*Utility->IndirectValues) #define curveCurNum (*Utility->curveCurNum) #define CurCurve (*Utility->CurCurve) #define ComputeExpr Utility->ComputeExpr #define ParseName Utility->ParseName #define InvalidateBifData Utility->InvalidateBifData #define hcSetMode Utility->hcSetMode #define hcFontList (*Utility->hcFontList) #define hcFontNum (*Utility->hcFontNum) #define ReadVAList Utility->ReadVAList #define WriteVAList Utility->WriteVAList #define FreeVAList Utility->FreeVAList #define PushVisualAttr Utility->PushVisualAttr #define PopVisualAttr Utility->PopVisualAttr #define SaveVisualAttr Utility->SaveVisualAttr #define RestoreVisualAttr Utility->RestoreVisualAttr #define DuplicateWindow Utility->DuplicateWindow #define Rhs (*Utility->Rhs) #define StartCR Utility->StartCR #define EndCR Utility->EndCR #define DeactivateWindows Utility->DeactivateWindows #define ActivateWindows Utility->ActivateWindows #endif /* defined(KERNEL) */