text:
#include <PalmOS.h>
#include <FloatMgr.h>
#include <TraceMgr.h>

#include "MathLib.h"
#include "MemoCalc.h"
#include "MemoCalcFunctions.h"
#include "MemoCalcLexer.h"
#include "MemoCalcParser.h"

/***********************************************************************
 *
 *	Defines, Macros and Constants
 *
 ***********************************************************************/

#define sysFileCMemoCalc			'MeCa'
#define memoDBType					'DATA'
#define memoCalcDefaultCategoryName	"MemoCalc"
#define memoCalcCurrRecFtrNum		0

#define kEditFormTitle				"Expression editor"
#define kVarsEditLabel				"Vars"
#define kVarsListLabel				"List"
#define kErrorStr					"Error"
#define kExprTag					"<--expr-->"
#define kVarsTag					"<--vars-->"
#define kExprTagLen					10
#define kVarsTagLen					10

#define editorSaveMemo				0
#define editorDeleteMemo			1
#define editorDiscardMemo			2
#define editorSaveEmptyMemo			3

#define resultBaseDecimal			0
#define resultBaseHexadecimal		1

#define kMemoHeaderSize				20
#define kMemoHeaderStr				"MemoCalc XXXXXX\n"
#define kMemoHeaderFormat			"MemoCalc %06d\n"

/***********************************************************************
 *
 *	Global variables
 *
 ***********************************************************************/

/* **** **** MathLib **** **** */
extern UInt16 MathLibRef;

/* **** **** Application  **** */
static EventType sAppEvent;

/* **** **** Memo DB **** **** */
static DmOpenRef sMemoDB;
static UInt16 sMemoCalcCategory;

/* **** **** List View ** **** */
static UInt16 sCurrentRecIndex, sTopVisibleRecIndex, sSavedRecIndex;

/* **** **** Edit View ** **** */
static MemHandle sMemoH;
static Char ** sVarsStrTbl;
static Char * sEditViewTitleStr;
static Int16 sNVars;
static UInt16 sEditFieldFocus;
static UInt8 sEditorSavePolicy;
static UInt8 sEditorResultBase;
static Boolean sVarsOk, sVarsList;
static Char sMemoHeaderBuf[kMemoHeaderSize];

/***********************************************************************
 *
 *	Internal Functions
 *
 ***********************************************************************/

/***********************************************************************
 *
 * FUNCTION:	MemoCalcMathLibOpen
 *
 * DESCRIPTION:
 *
 * PARAMETERS:
 *
 * RETURNED:
 *
 ***********************************************************************/

static UInt16 MemoCalcMathLibOpen (void)
{
	UInt16 err = errNone;

	err = SysLibLoad(sysFileTLibrary, MathLibCreator, &MathLibRef);
	if (err)
	{
		MathLibRef = NULL;
		goto Exit;
	}
	err = MathLibOpen(MathLibRef, MathLibVersion);
	ErrFatalDisplayIf(err, "Can't open MathLib");
Exit:
	return err;
}

/***********************************************************************
 *
 * FUNCTION:	MemoCalcMathLibClose
 *
 * DESCRIPTION:
 *
 * PARAMETERS:
 *
 * RETURNED:
 *
 ***********************************************************************/

static UInt16 MemoCalcMathLibClose (void)
{
	UInt16 usecount;
	UInt16 err = errNone;

	if (!MathLibRef)
		goto Exit;
	err = MathLibClose(MathLibRef, &usecount);
	ErrFatalDisplayIf(err, "Can't close MathLib");
	if (usecount == 0)
		SysLibRemove(MathLibRef);
Exit:
	return err;
}

/***********************************************************************
 *
 * FUNCTION:	MemoCalcDBOpen
 *
 * DESCRIPTION: Open the default Memo database in rw mode
 *		Check if category memoCalcDefaultCategoryName exists, otherwise
 *		use dmAllCategories
 *
 * PARAMETERS:  DmOpenRef *dbPP
 *
 * RETURNED:	error code
 *
 ***********************************************************************/

static UInt16 MemoCalcDBOpen (DmOpenRef *dbPP, UInt16 *memoCalcCategoryP)
{
	UInt16 err = errNone;
	*dbPP = DmOpenDatabaseByTypeCreator(memoDBType, sysFileCMemo, dmModeReadWrite);
	if (*dbPP == NULL)
	{
		err = dmErrCantOpen;
		goto Exit;
	}

	*memoCalcCategoryP = CategoryFind (*dbPP, memoCalcDefaultCategoryName);

Exit:
	return err;
}

/***********************************************************************
 *
 * FUNCTION:	MemoCalcDBClose
 *
 * DESCRIPTION: Close the default Memo database
 *
 * PARAMETERS:  none
 *
 * RETURNED:	error code
 *
 ***********************************************************************/

static UInt16 MemoCalcDBClose (DmOpenRef *dbPP)
{
	UInt16 err;
	err = DmCloseDatabase(*dbPP);
	*dbPP = NULL;
	return err;
}

/***********************************************************************
 *
 * FUNCTION:	StartApplication
 *
 * DESCRIPTION: Default initialization for the MemoCalc application.
 *
 * PARAMETERS:  none
 *
 * RETURNED:	error code
 *
 ***********************************************************************/

static UInt16 StartApplication (void)
{
	UInt32 ftr = 0;
	UInt16 err = 0;

// Initializing globals
	// MathLib
	MathLibRef = NULL;
	// Application
	MemSet(&sAppEvent, sizeof(EventType), 0);
	// Memo DB
	sMemoDB = NULL;
	sMemoCalcCategory = dmAllCategories;

// Run init code
	err = MemoCalcMathLibOpen();
	err = MemoCalcDBOpen(&sMemoDB, &sMemoCalcCategory);
	if (err)
		goto Exit;

	// List View
	if (FtrGet(sysFileCMemoCalc, memoCalcCurrRecFtrNum, &ftr)
	|| DmFindRecordByID(sMemoDB, ftr, &sCurrentRecIndex))
		sCurrentRecIndex = dmMaxRecordIndex;
	sSavedRecIndex = sCurrentRecIndex;
	sTopVisibleRecIndex = 0;

Exit:
	return err;
}

/***********************************************************************
 *
 * FUNCTION:	StopApplication
 *
 * DESCRIPTION: Default cleanup code for the MemoCalc application.
 *
 * PARAMETERS:  none
 *
 * RETURNED:	error code
 *
 ***********************************************************************/

static UInt16 StopApplication (void)
{
	UInt16 err;
	FrmCloseAllForms();
	err = MemoCalcDBClose(&sMemoDB);
	MemoCalcMathLibClose();
	return err;
}

/***********************************************************************
 *
 * FUNCTION:	MemoCalcUIUpdateScrollBar
 *
 * DESCRIPTION:
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void MemoCalcUIUpdateScrollBar (FormPtr frmP, UInt16 fieldID, UInt16 barID)
{
	UInt16 scrollPos, textHeight, fieldHeight, maxValue;
	FieldPtr fldP;
	ScrollBarPtr barP;

	fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, fieldID));
	barP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, barID));

	FldGetScrollValues (fldP, &scrollPos, &textHeight, &fieldHeight);

	if (textHeight > fieldHeight)
		maxValue = (textHeight - fieldHeight) + FldGetNumberOfBlankLines(fldP);
	else if (scrollPos)
		maxValue = scrollPos;
	else
		maxValue = 0;

	SclSetScrollBar(barP, (Int16)scrollPos, 0, (Int16)maxValue, fieldHeight-1);
}

/***********************************************************************
 *
 * FUNCTION:	MemoCalcUIScroll
 *
 * DESCRIPTION:
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void MemoCalcUIScroll (FormPtr frmP, Int16 linesToScroll, UInt16 fieldID, UInt16 barID)
{
	FieldPtr fldP;

	fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, fieldID));

	if (linesToScroll < 0)
		FldScrollField (fldP, (UInt16)(-linesToScroll), winUp);
	else if (linesToScroll > 0)
		FldScrollField (fldP, linesToScroll, winDown);

	MemoCalcUIUpdateScrollBar(frmP, fieldID, barID);
}

/***********************************************************************
 *
 * FUNCTION:	EditViewToggleExprButtons
 *
 * DESCRIPTION:
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void EditViewToggleExprButtons (FormPtr frmP)
{

	sEditFieldFocus = FrmGetObjectIndex(frmP, ExprField);
	if (FrmGetFocus(frmP) == sEditFieldFocus)
	{
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bpls));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Btim));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bdiv));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bopn));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bcls));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bclr));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bequ));
		if (MathLibRef)
		{
			FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bexp));
			FrmShowObject(frmP, FrmGetObjectIndex(frmP, FunctionsTrigger));
		}
	}
	else
	{
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bpls));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Btim));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bdiv));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bopn));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bcls));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bclr));
		if (MathLibRef)
		{
			FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bexp));
			FrmHideObject(frmP, FrmGetObjectIndex(frmP, FunctionsTrigger));
		}
		if (FrmGetFocus(frmP) == FrmGetObjectIndex(frmP, VarsField))
		{
			sEditFieldFocus = FrmGetObjectIndex(frmP, VarsField);
			FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bequ));
		}
	}

	FrmUpdateForm(EditView, frmRedrawUpdateCode);
}

/***********************************************************************
 *
 * FUNCTION:	EditViewToggleVarsView
 *
 * DESCRIPTION:
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void EditViewToggleVarsView (FormPtr frmP)
{
	ControlPtr varsCtlP;
	ListPtr varsLstP;
	FieldPtr varsFldP;
	Char * varsStr;
	Int16 iVar, iChar;
	UInt16 valStart, valEnd;

	if (sVarsStrTbl)
	{
		while(sNVars)
			MemPtrFree(sVarsStrTbl[--sNVars]);
		MemPtrFree(sVarsStrTbl);
		sVarsStrTbl = NULL;
	}

	varsCtlP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsButton));
	varsFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsField));
	varsStr = FldGetTextPtr(varsFldP);
	sVarsOk = (MakeVarsStringList(varsStr, &sVarsStrTbl, &sNVars) == 0);
	sVarsList = sVarsList && sVarsOk && sNVars;

	varsLstP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsList));

	if (sVarsList)
	{
		if (sVarsStrTbl)
			LstSetListChoices(varsLstP, sVarsStrTbl, sNVars);

		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bequ));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, VarsField));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, VarsScrollBar));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, VarsLabel));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, VarsList));

		FrmSetFocus(frmP, (sEditFieldFocus = FrmGetObjectIndex(frmP, ExprField)));
		CtlSetLabel(varsCtlP, kVarsEditLabel);
	}
	else
	{
		valStart = valEnd = 0;
		iVar = LstGetSelection(varsLstP);
		if (sVarsOk && varsStr && iVar != noListSelection)
		{	// select variable value in the field
			iChar = 0;
			while (varsStr[iChar])
			{
				if (varsStr[iChar] == '=')
				{
					iChar++;
					if (iVar)
						iVar--;
					else
					{
						while (isSeparator(varsStr[iChar]))
							iChar++;
						valStart = iChar;
						while (isNumber(varsStr[iChar]) || varsStr[iChar] == '.' || varsStr[iChar] == '-')
							iChar++;
						valEnd = iChar;
						break;
					}
				}
				iChar++;
			}
		}

		FrmHideObject(frmP, FrmGetObjectIndex(frmP, VarsList));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, Bequ));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, VarsField));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, VarsScrollBar));
		FrmShowObject(frmP, FrmGetObjectIndex(frmP, VarsLabel));

		CtlSetLabel(varsCtlP, kVarsListLabel);

		if (FrmGetFocus(frmP) != FrmGetObjectIndex(frmP, ExprField))
			FrmSetFocus(frmP, (sEditFieldFocus = FrmGetObjectIndex(frmP, VarsField)));

		if (valStart < valEnd)
			FldSetSelection(varsFldP, valStart, valEnd);

		MemoCalcUIUpdateScrollBar(frmP, VarsField, VarsScrollBar);
	}

	EditViewToggleExprButtons(frmP);
}

/***********************************************************************
 *
 * FUNCTION:	EditViewEval
 *
 * DESCRIPTION:
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void EditViewEval (FormPtr frmP)
{
	static Char resultBuf[kFlpBufSize];
	FieldPtr exprFldP, varsFldP, resultFldP;
	Char * exprStr, * varsStr;
	FlpCompDouble result;
	UInt8 err = 0;

	exprFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprField));
	varsFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsField));
	resultFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ResultField));

	exprStr = FldGetTextPtr(exprFldP);
	varsStr = FldGetTextPtr(varsFldP);

	if (exprStr == NULL || *exprStr == '\0')
		result.d = 0;
	else
		err = Eval(exprStr, varsStr, &(result.d));
	sVarsOk = !(err & missingVarError);

	if (err)
		StrCopy(resultBuf, kErrorStr);
	else {
		switch (sEditorResultBase) {
			case resultBaseDecimal:
				FlpCmpDblToA(&result, resultBuf);
			break;
			case resultBaseHexadecimal:
				StrPrintF(resultBuf,"0x%08lx",(long)result.d);
			break;
			default:
				StrCopy(resultBuf, kErrorStr);
		}
	}

	FldSetTextPtr(resultFldP, resultBuf);
	FrmUpdateForm(EditView, frmRedrawUpdateCode);
}

/***********************************************************************
 *
 * FUNCTION:	EditViewSave
 *
 * DESCRIPTION:
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void EditViewSave (FormPtr frmP)
{
	MemHandle exprH, varsH;
	Char * memoStr, * exprStr, * varsStr, * tmpStr;
	FieldPtr exprFldP, varsFldP;
	UInt32 ftr;
	UInt16 memoLen, exprLen, varsLen, titleLen, attr;
	Boolean defaultTitle;

	memoLen = exprLen = varsLen = titleLen = 0;
	memoStr = exprStr = varsStr = tmpStr = NULL;
	defaultTitle = 0;

	if (sEditViewTitleStr)
	{
		FrmSetTitle(frmP, kEditFormTitle);
		MemPtrFree(sEditViewTitleStr);
		sEditViewTitleStr = NULL;
	}

	if (sMemoH)
	{
		memoStr = (Char*) MemHandleLock(sMemoH);
		titleLen = memoLen = StrLen(memoStr);
		tmpStr = StrStr(memoStr, kVarsTag);
		if (tmpStr)
			titleLen = (UInt32)tmpStr - (UInt32)memoStr;
		else
		{
			tmpStr = StrStr(memoStr, kExprTag);
			if (tmpStr)
				titleLen = (UInt32)tmpStr - (UInt32)memoStr;
		}
	}

	exprFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprField));
	exprH = FldGetTextHandle(exprFldP);
	if (exprH)
	{
		exprStr = (Char*) MemHandleLock(exprH);
		exprLen = StrLen(exprStr);
	}

	varsFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsField));
	varsH = FldGetTextHandle(varsFldP);
	if (varsH)
	{
		varsStr = (Char*) MemHandleLock(varsH);
		varsLen = StrLen(varsStr);
	}

	memoLen = titleLen + kVarsTagLen + varsLen + kExprTagLen + exprLen;

	if (sEditorSavePolicy == editorDiscardMemo)
		goto Cleanup;

	if (sCurrentRecIndex != dmMaxRecordIndex)
	{
		if (sMemoH)
			MemHandleUnlock(sMemoH);
		DmReleaseRecord(sMemoDB, sCurrentRecIndex, true);
		DmResizeRecord(sMemoDB, sCurrentRecIndex, memoLen + 1 );
		sMemoH = DmGetRecord(sMemoDB, sCurrentRecIndex);
	}
	else
	{
		if (titleLen == 0) {
			memoLen += titleLen = StrLen(kMemoHeaderStr);
			sMemoH = DmNewRecord(sMemoDB, &sCurrentRecIndex, memoLen + 1 );
			memoStr = (Char*) MemHandleLock(sMemoH);
			StrPrintF(sMemoHeaderBuf,kMemoHeaderFormat, sCurrentRecIndex);
			DmWrite(memoStr, 0, sMemoHeaderBuf, titleLen);
			MemHandleUnlock(sMemoH);
			defaultTitle = 1;
		}
		else
			sMemoH = DmNewRecord(sMemoDB, &sCurrentRecIndex, memoLen + 1 );
		if (sMemoCalcCategory != dmAllCategories)
		{
			DmRecordInfo(sMemoDB, sCurrentRecIndex, &attr, NULL, NULL);
			attr = attr & ~dmRecAttrCategoryMask;
			attr = attr | sMemoCalcCategory;
			DmSetRecordInfo(sMemoDB, sCurrentRecIndex, &attr, NULL);
		}
	}

	memoStr = (Char*) MemHandleLock(sMemoH);

	DmWrite(memoStr, titleLen, kVarsTag, kVarsTagLen);
	if (varsLen)
	{
		DmWrite(memoStr, titleLen + kVarsTagLen, varsStr, varsLen);
	}

	DmWrite(memoStr, titleLen + kVarsTagLen + varsLen, kExprTag, kExprTagLen);
	if (exprLen)
	{
		DmWrite(memoStr, titleLen + kVarsTagLen + varsLen + kExprTagLen, exprStr, exprLen);
	}

	DmSet(memoStr, memoLen, 1, 0);

Cleanup:
	if (exprH)
		MemHandleUnlock(exprH);
	if (varsH)
		MemHandleUnlock(varsH);
	if (sMemoH)
	{
		MemHandleUnlock(sMemoH);
		sMemoH = NULL;
	}
	if (sCurrentRecIndex == dmMaxRecordIndex
	||	DmRecordInfo(sMemoDB, sCurrentRecIndex, NULL, &ftr, NULL))
		ftr = (UInt32)(sCurrentRecIndex = dmMaxRecordIndex);
	FtrSet(sysFileCMemoCalc, memoCalcCurrRecFtrNum, ftr);
	if (sCurrentRecIndex != dmMaxRecordIndex)
	{
		DmReleaseRecord(sMemoDB, sCurrentRecIndex, true);
		if (sEditorSavePolicy == editorDeleteMemo
		|| (sEditorSavePolicy == editorSaveMemo && (exprLen + varsLen == 0) && (titleLen == 0 || defaultTitle)))
		{
			DmDeleteRecord(sMemoDB, sCurrentRecIndex);
			DmMoveRecord(sMemoDB, sCurrentRecIndex, DmNumRecords(sMemoDB));
			FtrSet(sysFileCMemoCalc, memoCalcCurrRecFtrNum, (UInt32)dmMaxRecordIndex);
			sSavedRecIndex = dmMaxRecordIndex;
		}
		else
			sSavedRecIndex = sCurrentRecIndex;
		sCurrentRecIndex = dmMaxRecordIndex;
	}
	if (sVarsStrTbl)
	{
		while(sNVars)
			MemPtrFree(sVarsStrTbl[--sNVars]);
		MemPtrFree(sVarsStrTbl);
		sVarsStrTbl = NULL;
	}
}

/***********************************************************************
 *
 * FUNCTION:	EditViewInit
 *
 * DESCRIPTION: Initialize edit view form, load current record
 *
 * PARAMETERS:  Pointer to the edit view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void EditViewInit (FormPtr frmP)
{
	ListPtr funcsLstP;
	MemHandle exprH, varsH;
	Char * memoStr, * exprStr, *varsStr, * tmpStr, ** funcsStrTbl;
	FieldPtr exprFldP, varsFldP;
	UInt16 titleLen = 0;
	Int16 nFuncs = 0;
	UInt8 err = 0;

	FrmSetTitle(frmP, kEditFormTitle);

	if (!MathLibRef)
	{
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, Bexp));
		FrmHideObject(frmP, FrmGetObjectIndex(frmP, FunctionsTrigger));
	}
	else
	{
		funcsLstP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FunctionsList));
		GetFuncsStringList(&funcsStrTbl, &nFuncs);
		LstSetListChoices(funcsLstP, funcsStrTbl, nFuncs);
	}

	sMemoH = NULL;
	sVarsStrTbl = NULL;
	sEditViewTitleStr = NULL;
	sNVars = 0;
	sEditorSavePolicy = editorSaveMemo;
	sEditorResultBase = resultBaseDecimal;
	sVarsList = sVarsOk = true;

	if (sCurrentRecIndex != dmMaxRecordIndex)
	{
		sMemoH = DmGetRecord(sMemoDB, sCurrentRecIndex);
		memoStr = (Char*) MemHandleLock(sMemoH);
		titleLen = StrLen(memoStr);
		exprStr = StrStr(memoStr, kExprTag);
		if (exprStr)
		{
			exprStr += kExprTagLen;
			exprH = MemHandleNew(1 + (UInt32)titleLen -((UInt32)exprStr - (UInt32)memoStr));
			tmpStr = MemHandleLock(exprH);
			StrNCopy(tmpStr, exprStr, (UInt32)titleLen -((UInt32)exprStr - (UInt32)memoStr));
			tmpStr[(UInt16)((UInt32)titleLen -((UInt32)exprStr - (UInt32)memoStr))] = nullChr;
			MemHandleUnlock(exprH);
			exprFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprField));
			FldSetTextHandle(exprFldP, exprH);
			titleLen = (UInt16) ((UInt32)exprStr - kExprTagLen - (UInt32)memoStr);
		}
		varsStr = StrStr(memoStr, kVarsTag);
		if (varsStr && exprStr && varsStr < exprStr)
		{
			varsStr += kVarsTagLen;
			varsH = MemHandleNew(1 + (UInt32)exprStr - kExprTagLen - (UInt32)varsStr);
			tmpStr = MemHandleLock(varsH);
			StrNCopy(tmpStr, varsStr, (UInt32)exprStr - kExprTagLen - (UInt32)varsStr);
			tmpStr[(UInt16)((UInt32)exprStr - kExprTagLen - (UInt32)varsStr)] = nullChr;
			MemHandleUnlock(varsH);
			varsFldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsField));
			FldSetTextHandle(varsFldP, varsH);
			titleLen = (UInt16) ((UInt32)varsStr - kVarsTagLen - (UInt32)memoStr);
		}
		if (titleLen)
		{
			tmpStr = StrStr(memoStr, "\n");
			if (tmpStr && (UInt32)tmpStr < ((UInt32)memoStr + titleLen))
				titleLen = (UInt16) ((UInt32)tmpStr - (UInt32)memoStr);
			sEditViewTitleStr = MemPtrNew(1 + titleLen);
			StrNCopy(sEditViewTitleStr, memoStr, titleLen);
			sEditViewTitleStr[titleLen] = nullChr;
			FrmSetTitle(frmP, sEditViewTitleStr);
		}
		MemHandleUnlock(sMemoH);
	}

	MemoCalcUIUpdateScrollBar(frmP, ExprField, ExprScrollBar);
	FrmSetFocus(frmP, (sEditFieldFocus = FrmGetObjectIndex(frmP, ExprField)));
	EditViewToggleVarsView(frmP);
}

/***********************************************************************
 *
 * FUNCTION:	EditViewHandleEvent
 *
 * DESCRIPTION: Edit view form event handler
 *
 * PARAMETERS:  event pointer
 *
 * RETURNED:	true if the event was handled
 *
 ***********************************************************************/

static Boolean EditViewHandleEvent (EventType * evtP)
{
	FormPtr frmP;
	FieldPtr fldP;
	Char * str;
	WChar ascii;
	UInt16 focus;
	Boolean handled = false;
	static UInt8 sEditViewTapCount;

	switch (evtP->eType)
	{
		case frmOpenEvent:
			frmP = FrmGetActiveForm();
			EditViewInit(frmP);
			FrmDrawForm(frmP);
			handled = true;
		break;

		case frmCloseEvent:
			frmP = FrmGetActiveForm();
			EditViewSave(frmP);
		break;

		case fldEnterEvent:
			frmP = FrmGetActiveForm();
			EditViewToggleExprButtons(frmP);
		break;

		case fldChangedEvent:
			if (evtP->data.fldChanged.fieldID != VarsField && evtP->data.fldChanged.fieldID != ExprField)
				break;
			frmP = FrmGetActiveForm();
			MemoCalcUIUpdateScrollBar(frmP, evtP->data.fldChanged.fieldID,
			evtP->data.fldChanged.fieldID == VarsField ? VarsScrollBar : ExprScrollBar);
			if (evtP->data.fldChanged.fieldID == VarsField)
				LstSetSelection(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsList)), noListSelection);
			handled = true;
		break;

		case penDownEvent:
			sEditViewTapCount = evtP->tapCount;
		break;

		case keyDownEvent:
			if (evtP->data.keyDown.chr != vchrPageUp && evtP->data.keyDown.chr != vchrPageDown)
				break;
			sEditorSavePolicy = editorSaveMemo;
			frmP = FrmGetActiveForm();
			EditViewSave(frmP);
			sCurrentRecIndex = sSavedRecIndex;
			if (DmSeekRecordInCategory(sMemoDB, &sCurrentRecIndex, 1, evtP->data.keyDown.chr == vchrPageDown ? dmSeekForward : dmSeekBackward, sMemoCalcCategory))
			{
				sCurrentRecIndex = sSavedRecIndex;
				SndPlaySystemSound(sndError);
			}
			EditViewInit(frmP);
			handled = true;
		break;

		case popSelectEvent:
			if (MathLibRef)
			{
				str = LstGetSelectionText(evtP->data.popSelect.listP, evtP->data.popSelect.selection);
				frmP = FrmGetActiveForm();
				if (FrmGetFocus(frmP) != FrmGetObjectIndex(frmP, ExprField))
					FrmSetFocus(frmP, FrmGetObjectIndex(frmP, ExprField));
				while (str && *str)
				{
					EvtEnqueueKey((WChar) *str, 0, 0);
					str++;
				}
				EvtEnqueueKey((WChar) '(', 0, 0);
				EvtEnqueueKey((WChar) ')', 0, 0);
				EvtEnqueueKey((WChar) chrLeftArrow, 0, 0);
			}
			handled = true;
		break;

		case lstExitEvent:
			LstSetSelection(evtP->data.lstExit.pList, noListSelection);
			handled = true;
		break;

		case lstSelectEvent:
			if (sEditViewTapCount > 1 && evtP->data.lstSelect.listID == VarsList)
			{
				str = LstGetSelectionText(evtP->data.lstSelect.pList, evtP->data.lstSelect.selection);
				frmP = FrmGetActiveForm();
				if (FrmGetFocus(frmP) != FrmGetObjectIndex(frmP, ExprField))
					FrmSetFocus(frmP, FrmGetObjectIndex(frmP, ExprField));
				while (str && *str && *str != '=')
				{
					EvtEnqueueKey((WChar) *str, 0, 0);
					str++;
				}
				handled = true;
			}
		break;

		case sclRepeatEvent:
			frmP = FrmGetActiveForm();
			MemoCalcUIScroll(frmP, evtP->data.sclRepeat.newValue - evtP->data.sclRepeat.value,
			evtP->data.sclRepeat.scrollBarID == VarsScrollBar ? VarsField : ExprField,
						evtP->data.sclRepeat.scrollBarID);
		break;

		case ctlSelectEvent:
			ascii = 0;
			switch (evtP->data.ctlSelect.controlID)
			{
				case DoneButton:
					sEditorSavePolicy = editorSaveMemo;
					FrmGotoForm(ListView);
					handled = true;
				break;

				case EvalButton:
					frmP = FrmGetActiveForm();
					EditViewEval(frmP);
					handled = true;
				break;

				case VarsButton:
					sVarsList = !sVarsList;
					frmP = FrmGetActiveForm();
					if (!sVarsList)
						FrmSetFocus(frmP, noFocus);
					EditViewToggleVarsView(frmP);
					handled = true;
				break;

				case Bclr:
					frmP = FrmGetActiveForm();
					fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprField));
					FldDelete(fldP, 0, FldGetTextLength(fldP));
					handled = true;
				break;

				case Bequ:
					ascii = (WChar) '=';
				break;
				case B0:
					ascii = (WChar) '0';
				break;
				case B1:
					ascii = (WChar) '1';
				break;
				case B2:
					ascii = (WChar) '2';
				break;
				case B3:
					ascii = (WChar) '3';
				break;
				case B4:
					ascii = (WChar) '4';
				break;
				case B5:
					ascii = (WChar) '5';
				break;
				case B6:
					ascii = (WChar) '6';
				break;
				case B7:
					ascii = (WChar) '7';
				break;
				case B8:
					ascii = (WChar) '8';
				break;
				case B9:
					ascii = (WChar) '9';
				break;
				case Bdot:
					ascii = (WChar) '.';
				break;
				case Bpls:
					ascii = (WChar) '+';
				break;
				case Bmin:
					ascii = (WChar) '-';
				break;
				case Btim:
					ascii = (WChar) '*';
				break;
				case Bdiv:
					ascii = (WChar) '/';
				break;
				case Bexp:
					ascii = (WChar) '^';
				break;
				case Bopn:
					ascii = (WChar) '(';
				break;
				case Bcls:
					ascii = (WChar) ')';
				break;
				case Bdel:
					ascii = (WChar) chrBackspace;
				break;
			}
			if (ascii)
			{
				frmP = FrmGetActiveForm();
				if (sVarsList)
					FrmSetFocus(frmP, (sEditFieldFocus = FrmGetObjectIndex(frmP, ExprField)));
				else
					FrmSetFocus(frmP, sEditFieldFocus);
				EvtEnqueueKey(ascii, 0, 0);
				handled = true;
			}
		break;

		case menuEvent:
			frmP = FrmGetActiveForm();
			focus = FrmGetFocus(frmP);
			switch (evtP->data.menu.itemID)
			{
				case EditViewRecordNewMenu:
					sEditorSavePolicy = editorSaveMemo;
					EditViewSave(frmP);
					fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprField));
					FldDelete(fldP, 0, FldGetTextLength(fldP));
					fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, VarsField));
					FldDelete(fldP, 0, FldGetTextLength(fldP));
					EditViewInit(frmP);
					handled = true;
					break;

				case EditViewRecordEditMenu:
					sEditorSavePolicy = editorSaveEmptyMemo;
					FrmGotoForm(MemoView);
					handled = true;
					break;

				case EditViewRecordOpenMenu:
					sEditorSavePolicy = editorSaveMemo;
					FrmGotoForm(ListView);
					handled = true;
					break;

				case EditViewRecordDeleteMenu:
					sEditorSavePolicy = editorDeleteMemo;
					FrmGotoForm(ListView);
					handled = true;
					break;

				case EditViewRecordDiscardMenu:
					sEditorSavePolicy = editorDiscardMemo;
		 			MemSet(&sAppEvent, sizeof(EventType), 0);
			 		sAppEvent.eType = appStopEvent;
			 		EvtAddEventToQueue(&sAppEvent);
					handled = true;
					break;

				case EditViewEditCutMenu:
					if ((focus != noFocus) && (fldP = FrmGetObjectPtr(frmP, focus)))
						FldCut(fldP);
					handled = true;
					break;

				case EditViewEditCopyMenu:
					if ((focus != noFocus) && (fldP = FrmGetObjectPtr(frmP, focus)))
						FldCopy(fldP);
					handled = true;
					break;

				case EditViewEditPasteMenu:
					if ((focus != noFocus) && (fldP = FrmGetObjectPtr(frmP, focus)))
						FldPaste(fldP);
					handled = true;
					break;

				case EditViewEditSelectAllMenu:
					if ((focus != noFocus) && (fldP = FrmGetObjectPtr(frmP, focus)))
						FldSetSelection(fldP, 0, FldGetTextLength(fldP));
					handled = true;
					break;

				case EditViewEditUndoMenu:
					if ((focus != noFocus) && (fldP = FrmGetObjectPtr(frmP, focus)))
						FldUndo(fldP);
					handled = true;
					break;

				case EditViewEditKeyboardMenu:
					SysKeyboardDialog(kbdDefault);
					handled = true;
					break;

				case EditViewOptionsAboutMenu:
					MenuEraseStatus(NULL);
					frmP = FrmInitForm(AboutDialog);
					FrmDoDialog(frmP);
					FrmDeleteForm(frmP);
					handled = true;
				break;

				case EditViewOptionsHexMenu:
					sEditorResultBase = resultBaseHexadecimal;
					frmP = FrmGetActiveForm();
					EditViewEval(frmP);
					handled = true;
					break;

				case EditViewOptionsDecMenu:
					sEditorResultBase = resultBaseDecimal;
					frmP = FrmGetActiveForm();
					EditViewEval(frmP);
					handled = true;
					break;

			}
		break;
	}

	return handled;
}

/***********************************************************************
 *
 * FUNCTION:	ListViewDrawRecord
 *
 * DESCRIPTION: Table callback to draw records in the list view
 *
 * PARAMETERS:  tblP, row, col, rec¨P
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void ListViewDrawRecord (void * tblP, Int16 row, Int16 col, RectanglePtr recP)
{
	MemHandle memoH;
	Char * memoP, * memoTitleP, * tmpP;
	UInt16 recIndex, titleLen, titleStrLen;

	recIndex = TblGetRowID(tblP, row);

	if ((memoH = DmQueryRecord(sMemoDB, recIndex)) == NULL)
		return;
	memoP = MemHandleLock(memoH);
	tmpP = StrChr (memoP, linefeedChr);
	if (tmpP)
	{
		titleStrLen = (1 + tmpP - memoP) * sizeof(Char);
		memoTitleP = MemPtrNew(titleStrLen);
		StrNCopy(memoTitleP, memoP, titleStrLen);
		memoTitleP[titleStrLen-1] = nullChr;
	}
	else
		memoTitleP = memoP;

	titleLen = FntWordWrap(memoTitleP, recP->extent.x);

	WinDrawChars (memoTitleP, titleLen, recP->topLeft.x, recP->topLeft.y);
	MemHandleUnlock(memoH);
	if (tmpP)
		MemPtrFree(memoTitleP);
}

/***********************************************************************
 *
 * FUNCTION:	ListViewUpdateScrollers
 *
 * DESCRIPTION: Update the scroll arrows
 *
 * PARAMETERS:  Pointer to the list view form, top and bottom indexes
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void ListViewUpdateScrollers (FormPtr frmP, UInt16 topIndex, UInt16 bottomIndex)
{
	UInt16 recIndex;
	Boolean scrollableUp = false;
	Boolean scrollableDown = false;

	recIndex = topIndex;
	if (DmSeekRecordInCategory(sMemoDB, &recIndex, 1, dmSeekBackward, sMemoCalcCategory) == errNone)
		scrollableUp = true;

	recIndex = bottomIndex;
	if (DmSeekRecordInCategory(sMemoDB, &recIndex, 1, dmSeekForward, sMemoCalcCategory) == errNone)
		scrollableDown = true;

	FrmUpdateScrollers(frmP, FrmGetObjectIndex(frmP, UpButton), FrmGetObjectIndex(frmP, DownButton), scrollableUp, scrollableDown);
}

/***********************************************************************
 *
 * FUNCTION:	ListViewLoadTable
 *
 * DESCRIPTION: Load MemoDB records into the list view form
 *
 * PARAMETERS:  Pointer to the list view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void ListViewLoadTable (FormPtr frmP)
{
	TablePtr tblP;
	MemHandle recH;
	UInt32 recID;
	UInt16 recIndex;
	UInt16 nRows, row;

	tblP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprTable));

	recIndex = sTopVisibleRecIndex;

	// Store record unique ID in table data (UInt32)
	nRows = TblGetNumberOfRows(tblP);
	for (row = 0; row < nRows; row++)
	{
		recH = DmQueryNextInCategory(sMemoDB, &recIndex, sMemoCalcCategory);
		// Set the table row usable only if the record was found
		if (recH)
		{
			TblSetRowID(tblP, row, recIndex);
			DmRecordInfo(sMemoDB, recIndex, NULL, &recID, NULL);

			// Initialize row and force redraw only if this row has changed
			if ((TblGetRowData(tblP, row) != recID) || (! TblRowUsable(tblP, row)))
			{
				TblSetRowUsable(tblP, row, true);
				TblSetRowData(tblP, row, recID);
				TblMarkRowInvalid(tblP, row);
			}
			recIndex++;
		}
		else
		{
			TblSetRowUsable(tblP, row, false);
		}
	}

	TblDrawTable(tblP);
	ListViewUpdateScrollers(frmP, sTopVisibleRecIndex, recIndex-1);
}

/***********************************************************************
 *
 * FUNCTION:	ListViewScroll
 *
 * DESCRIPTION: Scrolls list view
 *
 * PARAMETERS:  Form pointer, direction
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void ListViewScroll (FormPtr frmP, Int16 direction)
{
	TablePtr tblP;
	UInt16 offset;
	UInt16 recIndex = sTopVisibleRecIndex;

	tblP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprTable));
	offset = (UInt16) (TblGetNumberOfRows(tblP) - 1);

	if (DmSeekRecordInCategory(sMemoDB, &recIndex, offset, direction, sMemoCalcCategory) == errNone)
	{
		sTopVisibleRecIndex = recIndex;
		ListViewLoadTable(frmP);
	}
}

/***********************************************************************
 *
 * FUNCTION:	ListViewInit
 *
 * DESCRIPTION: Initialize list view globals, call ListViewLoadTable
 *
 * PARAMETERS:  Pointer to the list view form
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void ListViewInit (FormPtr frmP)
{
	TablePtr tblP;
	UInt16 lastVisibleRecIndex;
	UInt16 nRows, row;

	tblP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprTable));
	nRows = TblGetNumberOfRows(tblP);
	TblSetCustomDrawProcedure (tblP, 0, ListViewDrawRecord);
	TblSetColumnUsable(tblP, 0, true);

	// Make sure sCurrentRecIndex is between sTopVisibleRecIndex and lastVisibleRecIndex
	if (sCurrentRecIndex != dmMaxRecordIndex)
	{
		if (sTopVisibleRecIndex > sCurrentRecIndex)
			sTopVisibleRecIndex = sCurrentRecIndex;
		else
		{
			lastVisibleRecIndex = sTopVisibleRecIndex;
			DmSeekRecordInCategory (sMemoDB, &lastVisibleRecIndex, nRows-1, dmSeekForward, sMemoCalcCategory);
			if (lastVisibleRecIndex < sCurrentRecIndex)
				sTopVisibleRecIndex = sCurrentRecIndex;
		}
	}

	for (row = 0; row < nRows; row++)
	{
		TblSetItemStyle(tblP, row, 0, customTableItem);
	}

}

/***********************************************************************
 *
 * FUNCTION:	ListViewHandleEvent
 *
 * DESCRIPTION: List view form event handler
 *
 * PARAMETERS:  event pointer
 *
 * RETURNED:	true if the event was handled
 *
 ***********************************************************************/

static Boolean ListViewHandleEvent (EventType * evtP)
{
	FormPtr frmP;
	TablePtr tblP;
	Boolean handled = false;

	switch (evtP->eType)
	{
		case frmOpenEvent:
			frmP = FrmGetActiveForm();
			ListViewInit(frmP);
			FrmDrawForm(frmP);
	ListViewLoadTable(frmP);
			handled = true;
		break;

		case tblSelectEvent:
			frmP = FrmGetActiveForm();
			tblP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ExprTable));
			sCurrentRecIndex = TblGetRowID(tblP, evtP->data.tblSelect.row);
			FrmGotoForm(EditView);
			handled = true;
		break;

		case ctlSelectEvent:
			switch (evtP->data.ctlSelect.controlID)
			{
				case NewButton:
					sCurrentRecIndex = dmMaxRecordIndex;
					FrmGotoForm(EditView);
					handled = true;
				break;
			}
		break;

		case ctlRepeatEvent:
			switch (evtP->data.ctlRepeat.controlID)
			{
				case UpButton:
					frmP = FrmGetActiveForm();
					ListViewScroll(frmP, dmSeekBackward);
				break;

				case DownButton:
					frmP = FrmGetActiveForm();
					ListViewScroll(frmP, dmSeekForward);
				break;
			}
		break;

		case menuEvent:
			switch (evtP->data.menu.itemID)
			{
				case ListViewRecordNewMenu:
					MenuEraseStatus(NULL);
					sCurrentRecIndex = dmMaxRecordIndex;
					FrmGotoForm(EditView);
					handled = true;
				break;

				case ListViewRecordQuitMenu:
		 			MemSet(&sAppEvent, sizeof(EventType), 0);
			 		sAppEvent.eType = appStopEvent;
			 		EvtAddEventToQueue(&sAppEvent);
					handled = true;
				break;

				case ListViewOptionsAboutMenu:
					MenuEraseStatus(NULL);
					frmP = FrmInitForm(AboutDialog);
					FrmDoDialog(frmP);
					handled = true;
				break;
			}
		break;
	}

	return handled;
}

/***********************************************************************
 *
 * FUNCTION:	MemoViewHandleEvent
 *
 * DESCRIPTION: Memo view form event handler
 *
 * PARAMETERS:  event pointer
 *
 * RETURNED:	true if the event was handled
 *
 ***********************************************************************/

static Boolean MemoViewHandleEvent (EventType * evtP)
{
	FormPtr frmP;
	FieldPtr fldP;
	Boolean handled = false;

	switch (evtP->eType)
	{
		case frmOpenEvent:
			sCurrentRecIndex = sSavedRecIndex;
			sMemoH = DmGetRecord(sMemoDB, sCurrentRecIndex);
			frmP = FrmGetActiveForm();
			fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, MemoViewEditField));
			FldSetTextHandle(fldP, sMemoH);
			MemoCalcUIUpdateScrollBar(frmP, MemoViewEditField, MemoViewScrollBar);
			FrmSetFocus(frmP, FrmGetObjectIndex(frmP, MemoViewEditField));
			FldSetInsertionPoint(fldP, 0);
			FrmDrawForm(frmP);
			handled = true;
		break;

		case frmCloseEvent:
			frmP = FrmGetActiveForm();
			fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, MemoViewEditField));
			FldSetTextHandle(fldP, NULL);
			DmReleaseRecord(sMemoDB, sCurrentRecIndex, true);
		break;

		case fldChangedEvent:
			frmP = FrmGetActiveForm();
			MemoCalcUIUpdateScrollBar(frmP, MemoViewEditField, MemoViewScrollBar);
			handled = true;
		break;

		case sclRepeatEvent:
			frmP = FrmGetActiveForm();
			MemoCalcUIScroll(frmP, evtP->data.sclRepeat.newValue - evtP->data.sclRepeat.value,
				MemoViewEditField, MemoViewScrollBar);
		break;

		case ctlSelectEvent:
			switch (evtP->data.ctlSelect.controlID)
			{
				case MemoViewOkButton:
					FrmGotoForm(EditView);
					handled = true;
				break;
			}
		break;
	}

	return handled;
}

/***********************************************************************
 *
 * FUNCTION:	ApplicationHandleEvent
 *
 * DESCRIPTION: Load form resources and set the form event handler
 *
 * PARAMETERS:  event pointer
 *
 * RETURNED:	true if the event was handled
 *
 ***********************************************************************/

static Boolean ApplicationHandleEvent (EventType * evtP)
{
	FormPtr frmP;
	UInt16 formID;

	if (evtP->eType != frmLoadEvent)
		return false;

	formID = evtP->data.frmLoad.formID;
	frmP = FrmInitForm(formID);
	FrmSetActiveForm(frmP);

	switch (formID)
	{
	case ListView:
		FrmSetEventHandler (frmP, ListViewHandleEvent);
		break;

	case EditView:
		FrmSetEventHandler (frmP, EditViewHandleEvent);
		break;

	case MemoView:
		FrmSetEventHandler (frmP, MemoViewHandleEvent);
		break;

	}
	return true;
}

/***********************************************************************
 *
 * FUNCTION:	EventLoop
 *
 * DESCRIPTION: Main event loop for the MemoCalc application.
 *
 * PARAMETERS:  none
 *
 * RETURNED:	nothing
 *
 ***********************************************************************/

static void EventLoop (void)
{
	EventType evt;
	UInt16 err;

	do
	{
		EvtGetEvent(&evt, evtWaitForever);
		if (! SysHandleEvent(&evt))
			if (! MenuHandleEvent (NULL, &evt, &err))
				if (! ApplicationHandleEvent(&evt))
					FrmDispatchEvent (&evt);
	}
	while (evt.eType != appStopEvent);
}

/***********************************************************************
 *
 * FUNCTION:	PilotMain
 *
 * DESCRIPTION: Main entry point for the MemoCalc application.
 *
 * PARAMETERS:  launch code, command block pointer, launch flags
 *
 * RETURNED:	error code
 *
 ***********************************************************************/

UInt32 PilotMain (UInt16 launchCode, MemPtr cmdPBP, UInt16 launchFlags)
{
	UInt16 err = errNone;

	switch (launchCode)
	{
		case sysAppLaunchCmdNormalLaunch:
			err = StartApplication();
			if (err != errNone)
				break;
			FrmGotoForm(EditView);
			EventLoop();
			err = StopApplication();
		break;
	}

	return (UInt32) err;
}


text:
#include "qsizegrip.h"

#ifndef QT_NO_SIZEGRIP

#include "qapplication.h"
#include "qevent.h"
#include "qpainter.h"
#include "qstyle.h"
#include "qstyleoption.h"
#include "qlayout.h"
#include "qdebug.h"
#include <QDesktopWidget>

#if defined(Q_WS_X11)
#include <private/qt_x11_p.h>
#elif defined (Q_WS_WIN)
#include "qt_windows.h"
#endif
#ifdef Q_WS_MAC
#include <private/qt_mac_p.h>
#endif

#include <private/qwidget_p.h>
#include <QtGui/qabstractscrollarea.h>

#define SZ_SIZEBOTTOMRIGHT  0xf008
#define SZ_SIZEBOTTOMLEFT   0xf007
#define SZ_SIZETOPLEFT      0xf004
#define SZ_SIZETOPRIGHT     0xf005

QT_BEGIN_NAMESPACE

static QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
{
    while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
        w = w->parentWidget();
    return w;
}

class QSizeGripPrivate : public QWidgetPrivate
{
    Q_DECLARE_PUBLIC(QSizeGrip)
public:
    void init();
    QPoint p;
    QRect r;
    int d;
    int dxMax;
    int dyMax;
    Qt::Corner m_corner;
    bool gotMousePress;
    QWidget *tlw;
#ifdef Q_WS_MAC
    void updateMacSizer(bool hide) const;
#endif
    Qt::Corner corner() const;
    inline bool atBottom() const
    {
        return m_corner == Qt::BottomRightCorner || m_corner == Qt::BottomLeftCorner;
    }

    inline bool atLeft() const
    {
        return m_corner == Qt::BottomLeftCorner || m_corner == Qt::TopLeftCorner;
    }

    void updateTopLevelWidget()
    {
        Q_Q(QSizeGrip);
        QWidget *w = qt_sizegrip_topLevelWidget(q);
        if (tlw == w)
            return;
        if (tlw)
            tlw->removeEventFilter(q);
        tlw = w;
        if (tlw)
            tlw->installEventFilter(q);
    }

    // This slot is invoked by QLayout when the size grip is added to
    // a layout or reparented after the tlw is shown. This re-implementation is basically
    // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
    // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
    void _q_showIfNotHidden()
    {
        Q_Q(QSizeGrip);
        bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
        updateTopLevelWidget();
        if (tlw && showSizeGrip) {
            Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
#ifndef Q_WS_MAC
            sizeGripNotVisibleState |= Qt::WindowMaximized;
#endif
            // Don't show the size grip if the tlw is maximized or in full screen mode.
            showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
        }
        if (showSizeGrip)
            q->setVisible(true);
    }
};

#ifdef Q_WS_MAC
void QSizeGripPrivate::updateMacSizer(bool hide) const
{
    Q_Q(const QSizeGrip);
    if (QApplication::closingDown() || !parent)
        return;
    QWidget *topLevelWindow = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
    if(topLevelWindow && topLevelWindow->isWindow())
        QWidgetPrivate::qt_mac_update_sizer(topLevelWindow, hide ? -1 : 1);
}
#endif

Qt::Corner QSizeGripPrivate::corner() const
{
    Q_Q(const QSizeGrip);
    QWidget *tlw = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
    const QPoint sizeGripPos = q->mapTo(tlw, QPoint(0, 0));
    bool isAtBottom = sizeGripPos.y() >= tlw->height() / 2;
    bool isAtLeft = sizeGripPos.x() <= tlw->width() / 2;
    if (isAtLeft)
        return isAtBottom ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
    else
        return isAtBottom ? Qt::BottomRightCorner : Qt::TopRightCorner;
}

/*!
    \class QSizeGrip

    \brief The QSizeGrip class provides a resize handle for resizing top-level windows.

    \ingroup mainwindow-classes
    \ingroup basicwidgets

    This widget works like the standard Windows resize handle. In the
    X11 version this resize handle generally works differently from
    the one provided by the system if the X11 window manager does not
    support necessary modern post-ICCCM specifications.

    Put this widget anywhere in a widget tree and the user can use it
    to resize the top-level window or any widget with the Qt::SubWindow
    flag set. Generally, this should be in the lower right-hand corner.
    Note that QStatusBar already uses this widget, so if you have a
    status bar (e.g., you are using QMainWindow), then you don't need
    to use this widget explicitly.

    On some platforms the size grip automatically hides itself when the
    window is shown full screen or maximised.

    \table 50%
    \row \o \inlineimage plastique-sizegrip.png Screenshot of a Plastique style size grip
    \o A size grip widget at the bottom-right corner of a main window, shown in the
    \l{Plastique Style Widget Gallery}{Plastique widget style}.
    \endtable

    The QSizeGrip class inherits QWidget and reimplements the \l
    {QWidget::mousePressEvent()}{mousePressEvent()} and \l
    {QWidget::mouseMoveEvent()}{mouseMoveEvent()} functions to feature
    the resize functionality, and the \l
    {QWidget::paintEvent()}{paintEvent()} function to render the
    size grip widget.

    \sa QStatusBar QWidget::windowState()
*/

/*!
    Constructs a resize corner as a child widget of  the given \a
    parent.
*/
QSizeGrip::QSizeGrip(QWidget * parent)
    : QWidget(*new QSizeGripPrivate, parent, 0)
{
    Q_D(QSizeGrip);
    d->init();
}

#ifdef QT3_SUPPORT
/*!
    \obsolete

    Constructs a resize corner with the given \a name, as a child
    widget of the given \a parent.
*/
QSizeGrip::QSizeGrip(QWidget * parent, const char* name)
    : QWidget(*new QSizeGripPrivate, parent, 0)
{
    Q_D(QSizeGrip);
    setObjectName(QString::fromAscii(name));
    d->init();
}
#endif

void QSizeGripPrivate::init()
{
    Q_Q(QSizeGrip);
    dxMax = 0;
    dyMax = 0;
    tlw = 0;
    m_corner = q->isLeftToRight() ? Qt::BottomRightCorner : Qt::BottomLeftCorner;
    gotMousePress = false;

#if !defined(QT_NO_CURSOR) && !defined(Q_WS_MAC)
    q->setCursor(m_corner == Qt::TopLeftCorner || m_corner == Qt::BottomRightCorner
                 ? Qt::SizeFDiagCursor : Qt::SizeBDiagCursor);
#endif
    q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
    updateTopLevelWidget();
}

/*!
    Destroys this size grip.
*/
QSizeGrip::~QSizeGrip()
{
}

/*!
  \reimp
*/
QSize QSizeGrip::sizeHint() const
{
    QStyleOption opt(0);
    opt.init(this);
    return (style()->sizeFromContents(QStyle::CT_SizeGrip, &opt, QSize(13, 13), this).
            expandedTo(QApplication::globalStrut()));
}

/*!
    Paints the resize grip.

    Resize grips are usually rendered as small diagonal textured lines
    in the lower-right corner. The paint event is passed in the \a
    event parameter.
*/
void QSizeGrip::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    Q_D(QSizeGrip);
    QPainter painter(this);
    QStyleOptionSizeGrip opt;
    opt.init(this);
    opt.corner = d->m_corner;
    style()->drawControl(QStyle::CE_SizeGrip, &opt, &painter, this);
}

/*!
    \fn void QSizeGrip::mousePressEvent(QMouseEvent * event)

    Receives the mouse press events for the widget, and primes the
    resize operation. The mouse press event is passed in the \a event
    parameter.
*/
void QSizeGrip::mousePressEvent(QMouseEvent * e)
{
    if (e->button() != Qt::LeftButton) {
        QWidget::mousePressEvent(e);
        return;
    }

    Q_D(QSizeGrip);
    QWidget *tlw = qt_sizegrip_topLevelWidget(this);
    d->p = e->globalPos();
    d->gotMousePress = true;
    d->r = tlw->geometry();

#ifdef Q_WS_X11
    // Use a native X11 sizegrip for "real" top-level windows if supported.
    if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
        && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)
        && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
        XEvent xev;
        xev.xclient.type = ClientMessage;
        xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE);
        xev.xclient.display = X11->display;
        xev.xclient.window = tlw->winId();
        xev.xclient.format = 32;
        xev.xclient.data.l[0] = e->globalPos().x();
        xev.xclient.data.l[1] = e->globalPos().y();
        if (d->atBottom())
            xev.xclient.data.l[2] = d->atLeft() ? 6 : 4; // bottomleft/bottomright
        else
            xev.xclient.data.l[2] = d->atLeft() ? 0 : 2; // topleft/topright
        xev.xclient.data.l[3] = Button1;
        xev.xclient.data.l[4] = 0;
        XUngrabPointer(X11->display, X11->time);
        XSendEvent(X11->display, QX11Info::appRootWindow(x11Info().screen()), False,
                   SubstructureRedirectMask | SubstructureNotifyMask, &xev);
        return;
    }
#endif // Q_WS_X11
#ifdef Q_WS_WIN
    if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
        uint orientation = 0;
        if (d->atBottom())
            orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT;
        else
            orientation = d->atLeft() ? SZ_SIZETOPLEFT : SZ_SIZETOPRIGHT;

        ReleaseCapture();
        PostMessage(tlw->winId(), WM_SYSCOMMAND, orientation, 0);
        return;
    }
#endif // Q_WS_WIN

    // Find available desktop/workspace geometry.
    QRect availableGeometry;
    bool hasVerticalSizeConstraint = true;
    bool hasHorizontalSizeConstraint = true;
    if (tlw->isWindow())
        availableGeometry = QApplication::desktop()->availableGeometry(tlw);
    else {
        const QWidget *tlwParent = tlw->parentWidget();
        // Check if tlw is inside QAbstractScrollArea/QScrollArea.
        // If that's the case tlw->parentWidget() will return the viewport
        // and tlw->parentWidget()->parentWidget() will return the scroll area.
#ifndef QT_NO_SCROLLAREA
        QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(tlwParent->parentWidget());
        if (scrollArea) {
            hasHorizontalSizeConstraint = scrollArea->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
            hasVerticalSizeConstraint = scrollArea->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
        }
#endif // QT_NO_SCROLLAREA
        availableGeometry = tlwParent->contentsRect();
    }

    // Find frame geometries, title bar height, and decoration sizes.
    const QRect frameGeometry = tlw->frameGeometry();
    const int titleBarHeight = qMax(tlw->geometry().y() - frameGeometry.y(), 0);
    const int bottomDecoration = qMax(frameGeometry.height() - tlw->height() - titleBarHeight, 0);
    const int leftRightDecoration = qMax((frameGeometry.width() - tlw->width()) / 2, 0);

    // Determine dyMax depending on whether the sizegrip is at the bottom
    // of the widget or not.
    if (d->atBottom()) {
        if (hasVerticalSizeConstraint)
            d->dyMax = availableGeometry.bottom() - d->r.bottom() - bottomDecoration;
        else
            d->dyMax = INT_MAX;
    } else {
        if (hasVerticalSizeConstraint)
            d->dyMax = availableGeometry.y() - d->r.y() + titleBarHeight;
        else
            d->dyMax = -INT_MAX;
    }

    // In RTL mode, the size grip is to the left; find dxMax from the desktop/workspace
    // geometry, the size grip geometry and the width of the decoration.
    if (d->atLeft()) {
        if (hasHorizontalSizeConstraint)
            d->dxMax = availableGeometry.x() - d->r.x() + leftRightDecoration;
        else
            d->dxMax = -INT_MAX;
    } else {
        if (hasHorizontalSizeConstraint)
            d->dxMax = availableGeometry.right() - d->r.right() - leftRightDecoration;
        else
            d->dxMax = INT_MAX;
    }
}

/*!
    \fn void QSizeGrip::mouseMoveEvent(QMouseEvent * event)
    Resizes the top-level widget containing this widget. The mouse
    move event is passed in the \a event parameter.
*/
void QSizeGrip::mouseMoveEvent(QMouseEvent * e)
{
    if (e->buttons() != Qt::LeftButton) {
        QWidget::mouseMoveEvent(e);
        return;
    }

    Q_D(QSizeGrip);
    QWidget* tlw = qt_sizegrip_topLevelWidget(this);
    if (!d->gotMousePress || tlw->testAttribute(Qt::WA_WState_ConfigPending))
        return;

#ifdef Q_WS_X11
    if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
        && tlw->isTopLevel() && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)
        && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth())
        return;
#endif
#ifdef Q_WS_WIN
    if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId()
        && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
        MSG msg;
        while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
        return;
    }
#endif

    QPoint np(e->globalPos());

    // Don't extend beyond the available geometry; bound to dyMax and dxMax.
    QSize ns;
    if (d->atBottom())
        ns.rheight() = d->r.height() + qMin(np.y() - d->p.y(), d->dyMax);
    else
        ns.rheight() = d->r.height() - qMax(np.y() - d->p.y(), d->dyMax);

    if (d->atLeft())
        ns.rwidth() = d->r.width() - qMax(np.x() - d->p.x(), d->dxMax);
    else
        ns.rwidth() = d->r.width() + qMin(np.x() - d->p.x(), d->dxMax);

    ns = QLayout::closestAcceptableSize(tlw, ns);

    QPoint p;
    QRect nr(p, ns);
    if (d->atBottom()) {
        if (d->atLeft())
            nr.moveTopRight(d->r.topRight());
        else
            nr.moveTopLeft(d->r.topLeft());
    } else {
        if (d->atLeft())
            nr.moveBottomRight(d->r.bottomRight());
        else
            nr.moveBottomLeft(d->r.bottomLeft());
    }

    tlw->setGeometry(nr);
}

/*!
  \reimp
*/
void QSizeGrip::mouseReleaseEvent(QMouseEvent *mouseEvent)
{
    if (mouseEvent->button() == Qt::LeftButton) {
        Q_D(QSizeGrip);
        d->gotMousePress = false;
        d->p = QPoint();
    } else {
        QWidget::mouseReleaseEvent(mouseEvent);
    }
}

/*!
  \reimp
*/
void QSizeGrip::moveEvent(QMoveEvent * /*moveEvent*/)
{
    Q_D(QSizeGrip);
    // We're inside a resize operation; no update necessary.
    if (!d->p.isNull())
        return;

    d->m_corner = d->corner();
#if !defined(QT_NO_CURSOR) && !defined(Q_WS_MAC)
    setCursor(d->m_corner == Qt::TopLeftCorner || d->m_corner == Qt::BottomRightCorner
              ? Qt::SizeFDiagCursor : Qt::SizeBDiagCursor);
#endif
}

/*!
  \reimp
*/
void QSizeGrip::showEvent(QShowEvent *showEvent)
{
#ifdef Q_WS_MAC
    d_func()->updateMacSizer(false);
#endif
    QWidget::showEvent(showEvent);
}

/*!
  \reimp
*/
void QSizeGrip::hideEvent(QHideEvent *hideEvent)
{
#ifdef Q_WS_MAC
    d_func()->updateMacSizer(true);
#endif
    QWidget::hideEvent(hideEvent);
}

/*!
    \reimp
*/
void QSizeGrip::setVisible(bool visible)
{
    QWidget::setVisible(visible);
}

/*! \reimp */
bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
{
    Q_D(QSizeGrip);
    if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
        || e->type() != QEvent::WindowStateChange
		|| o != d->tlw) {
        return QWidget::eventFilter(o, e);
    }
    Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
#ifndef Q_WS_MAC
    sizeGripNotVisibleState |= Qt::WindowMaximized;
#endif
    // Don't show the size grip if the tlw is maximized or in full screen mode.
    setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
    setAttribute(Qt::WA_WState_ExplicitShowHide, false);
    return QWidget::eventFilter(o, e);
}

/*!
    \reimp
*/
bool QSizeGrip::event(QEvent *event)
{
    return QWidget::event(event);
}

#ifdef Q_WS_WIN
/*! \reimp */
bool QSizeGrip::winEvent( MSG *m, long *result )
{
    return QWidget::winEvent(m, result);
}
#endif

QT_END_NAMESPACE

#include "moc_qsizegrip.cpp"

#endif //QT_NO_SIZEGRIP

redpajama_set_name: RedPajamaGithub


text:
package zeonClient.utils;

import net.minecraft.network.Packet;

public final class WConnection
{
	public static void sendPacket(Packet packet)
	{
		WMinecraft.getConnection().sendPacket(packet);
	}

	public static void sendPacketBypass(Packet packet)
	{
		//WMinecraft.getConnection().sendPacketBypass(packet);
	}
}


text:
<?php

namespace Magento\Catalog\Test\TestCase\Category;

use Magento\Catalog\Test\Fixture\Category;
use Magento\Catalog\Test\Page\Adminhtml\CatalogCategoryEdit;
use Magento\Catalog\Test\Page\Adminhtml\CatalogCategoryIndex;
use Magento\Mtf\TestCase\Injectable;

/**
 * Test Creation for CreateCategoryEntity
 *
 * Test Flow:
 * 1. Login as admin
 * 2. Navigate to the Products>Inventory>Categories
 * 3. Click on 'Add Category' button
 * 4. Fill out all data according to data set
 * 5. Save category
 * 6. Verify created category
 *
 * @group Category_Management_(MX)
 * @ZephyrId MAGETWO-23411
 */
class CreateCategoryEntityTest extends Injectable
{
    /* tags */
    const MVP = 'yes';
    const DOMAIN = 'MX';
    const TEST_TYPE = 'acceptance_test';
    /* end tags */

    /**
     * Catalog category index page
     *
     * @var CatalogCategoryIndex
     */
    protected $catalogCategoryIndex;

    /**
     * Catalog category edit page
     *
     * @var CatalogCategoryEdit
     */
    protected $catalogCategoryEdit;

    /**
     * Inject pages
     *
     * @param CatalogCategoryIndex $catalogCategoryIndex
     * @param CatalogCategoryEdit $catalogCategoryEdit
     * @return void
     */
    public function __inject(CatalogCategoryIndex $catalogCategoryIndex, CatalogCategoryEdit $catalogCategoryEdit)
    {
        $this->catalogCategoryIndex = $catalogCategoryIndex;
        $this->catalogCategoryEdit = $catalogCategoryEdit;
    }

    /**
     * Create category
     *
     * @param Category $category
     * @param string $addCategory
     * @return void
     */
    public function test(Category $category, $addCategory)
    {
        $this->catalogCategoryIndex->open();
        $this->catalogCategoryIndex->getTreeCategories()->selectCategory($category, false);
        $this->catalogCategoryIndex->getTreeCategories()->$addCategory();
        $this->catalogCategoryEdit->getEditForm()->fill($category);
        $this->catalogCategoryEdit->getFormPageActions()->save();
    }
}


text:
<?php

namespace SumoCoders\FrameworkCoreBundle\EventListener;

use SumoCoders\FrameworkCoreBundle\Event\ConfigureMenuEvent;
use SumoCoders\FrameworkCoreBundle\EventListener\DefaultMenuListener;

class MenuListener extends DefaultMenuListener
{
    public function onConfigureMenu(ConfigureMenuEvent $event)
    {
        $menu = $event->getMenu();

        if ($this->getSecurityAuthorizationChecker()->isGranted('ROLE_ADMIN')) {
            $menuItem = $event->getFactory()->createItem(
                'navigation.translations',
                array(
                    'route' => 'jms_translation_index',
                )
            );
            $menuItem->setLinkAttributes(
                array(
                    'class' => 'menu-item',
                )
            );

            $menu->addChild($menuItem);
        }
    }
}


text:
package codegen

import (
	"path/filepath"
	"sort"
	"strings"
	"unicode"

	"strconv"

	"github.com/fatih/camelcase"
	"github.com/juju/errors"
)

type (
	Import struct {
		Alias string
		Path  string
	}

	Imports map[string]Import

	Field struct {
		Order int
		Name  string
		Type  string
		Tag   string
	}

	Fields map[string]Field

	Struct struct {
		Imports Imports
		Name    string
		Fields  Fields
	}

	Structs map[string]Struct

	Func struct {
		PkgPath   string
		Name      string
		Method    []string
		Protected bool
		Pattern   string
		Query     []string
		In        *Struct
		Out       *Struct
	}

	Funcs []Func

	Service struct {
		Import Import
		Funcs  Funcs
	}

	Services []Service

	ByOrder []Field
)

func (a ByOrder) Len() int           { return len(a) }
func (a ByOrder) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByOrder) Less(i, j int) bool { return a[i].Order < a[j].Order }

func (i Import) GetPathAsAlias() string {
	r := strings.NewReplacer("/", "", ".", "")
	return strings.ToLower(r.Replace(i.Path))
}

func (f Func) GetFullName() string {
	return f.PkgPath + ":" + f.Name
}

func (f Func) GetPkgPath() string {
	return f.PkgPath
}

func (f Func) GetOnlyPkgName() string {
	return filepath.Base(f.PkgPath)
}

func (f Func) GetMethod() []string {
	return f.Method
}

func (f Func) GetQuery() []string {
	return f.Query
}

func (f Func) GetPattern() string {
	return f.Pattern
}

func (f Func) GetHandlerName() string {
	return f.Name + "Handler"
}
func (f Func) GetProtected() bool {
	return f.Protected
}

func (fld Field) GetVarName() string {
	return makeFirstUpperCase(fld.Name)
}

func (fld Field) GetVarValue(data map[string]string) (interface{}, error) {
	// if value exists in variables
	if val, ok := data[fld.Name]; ok {
		switch fld.Type {
		case "string":
			return val, nil
		case "*string":
			return &val, nil
		case "*int":
			i, err := strconv.Atoi(val)
			return &i, err
		case "int":
			i, err := strconv.Atoi(val)
			return i, err
		case "int8":
			i, err := strconv.ParseInt(val, 10, 8)
			return int8(i), err
		case "*int8":
			i, err := strconv.ParseInt(val, 10, 8)
			icst := int8(i)
			return &icst, err
		case "int16":
			i, err := strconv.ParseInt(val, 10, 16)
			return int16(i), err
		case "*int16":
			i, err := strconv.ParseInt(val, 10, 16)
			icst := int16(i)
			return &icst, err
		case "int32":
			i, err := strconv.ParseInt(val, 10, 32)
			return int32(i), err
		case "*int32":
			i, err := strconv.ParseInt(val, 10, 32)
			icst := int32(i)
			return &icst, err
		case "int64":
			i, err := strconv.ParseInt(val, 10, 64)
			return i, err
		case "*int64":
			i, err := strconv.ParseInt(val, 10, 64)
			return &i, err
		case "float32":
			i, err := strconv.ParseFloat(val, 32)
			return float32(i), err
		case "*float32":
			i, err := strconv.ParseFloat(val, 32)
			icst := float32(i)
			return &icst, err
		case "float64":
			i, err := strconv.ParseFloat(val, 64)
			return i, err
		case "*float64":
			i, err := strconv.ParseFloat(val, 64)
			icst := float64(i)
			return &icst, err
		case "bool":
			b, err := strconv.ParseBool(val)
			return b, err
		case "*bool":
			b, err := strconv.ParseBool(val)
			return &b, err
		default:
			return nil, errors.Trace(errors.Errorf("Value is complext type!Expected only primitives!"))
		}
	}

	return nil, nil
}

func (fld Field) GetVarType() string {
	return fld.Type
}

func (fld Field) GetTag() string {
	return "`json:\"" + makeTagName(fld.Name) + ",omitempty\"`"
}

func (fld Field) GetOutVarName() string {
	return makeTagName(fld.Name)
}

func (s Struct) GetName() string {
	return s.Name
}

func (s Struct) GetFieldsSlice() []Field {
	fs := []Field{}
	for _, f := range s.Fields {
		fs = append(fs, f)
	}

	sort.Sort(ByOrder(fs))

	return fs
}

func makeTagName(s string) string {
	a := []rune(s)

	if len(a) <= 3 {
		return strings.ToLower(string(a))
	}

	spl := camelcase.Split(string(a))

	if len(spl) > 1 {
		fixed := []string{}
		for _, v := range spl {
			fixed = append(fixed, makeFirstUpperCase(strings.ToLower(v)))
		}
		x := makeFirstLowerCase(strings.Join(fixed, ""))
		return x
	}

	return makeFirstLowerCase(strings.Title(string(a)))
}

func makeFirstLowerCase(s string) string {
	a := []rune(s)
	a[0] = unicode.ToLower(a[0])
	return string(a)
}

func makeFirstUpperCase(s string) string {
	a := []rune(s)
	a[0] = unicode.ToUpper(a[0])
	return string(a)
}


text:
<xml>
<AppId><![CDATA[<%= result.appid %>]]></AppId>
<Package><![CDATA[<%= result.package %>]]></Package>
<TimeStamp><%= result.timestamp %></TimeStamp>
<NonceStr><![CDATA[<%= result.noncestr %>]]></NonceStr>
<RetCode><%= result.retcode %></RetCode>
<RetErrMsg><![CDATA[<%= result.reterrmsg %>]]></RetErrMsg>
<AppSignature><![CDATA[<%= result.appsignature %>]]></AppSignature>
<SignMethod><![CDATA[sha1]]></SignMethod>
</xml>


text:
/**
 * @file         group_aggr.cc
 * @date         May 30, 2004
 * @brief        Group by aggregation operator
 */
#include <stdio.h>

#ifndef _DEBUG_
#include "common/debug.h"
#endif

#ifndef _GROUP_AGGR_
#include "execution/operators/group_aggr.h"
#endif

#define LOCK_OUTPUT_TUPLE(t)   (outStore -> addRef ((t)))
#define LOCK_INPUT_TUPLE(t)    (inStore -> addRef ((t)))
#define UNLOCK_OUTPUT_TUPLE(t) (outStore -> decrRef ((t)))
#define UNLOCK_INPUT_TUPLE(t)  (inStore -> decrRef ((t)))

using namespace Execution;

// Xing: The array keeps the LUB info. [0] is the current aggregation level, [1-4]
// are the counts of the tuple levels in the synopsis.
//unsigned int aggrLUBLevel[5] = {0};
// Xing: For minus output
int oldAggrLevel;

GroupAggr::GroupAggr (unsigned int id, std::ostream &_LOG)
	: LOG (_LOG)
{
	this -> id                  = id;
	this -> inputQueue          = 0;
	this -> outputQueue         = 0;
	this -> inputSynopsis       = 0;
	this -> outputSynopsis      = 0;
	this -> outStore            = 0;
	this -> inStore             = 0;
	this -> evalContext         = 0;
	this -> plusEval            = 0;
	this -> updateEval          = 0;
	this -> minusEval           = 0;
	this -> bScanNotReq         = 0;
	this -> initEval            = 0;
	this -> emptyGroupEval      = 0;
	this -> lastInputTs         = 0;
	this -> lastOutputTs        = 0;
	this -> bStalled            = false;
	// Xing: initialize the LUB level info
	this ->aggrLUBLevel[5]		= 0;
}

GroupAggr::~GroupAggr ()
{
	if (evalContext)
		delete evalContext;
	if (plusEval)
		delete plusEval;
	if (updateEval)
		delete updateEval;
	if (bScanNotReq)
		delete bScanNotReq;
	if (minusEval)
		delete minusEval;
	if (initEval)
		delete initEval;
	if (emptyGroupEval)
		delete emptyGroupEval;
}

int GroupAggr::setInputQueue (Queue *inputQueue)
{
	ASSERT (inputQueue);

	this -> inputQueue = inputQueue;
	return 0;
}

int GroupAggr::setOutputQueue (Queue *outputQueue)
{
	ASSERT (outputQueue);

	this -> outputQueue = outputQueue;
	return 0;
}

int GroupAggr::setOutputSynopsis (RelationSynopsis *synopsis,
								  unsigned int scanId)
{
	ASSERT (synopsis);

	this -> outputSynopsis = synopsis;
	this -> outScanId = scanId;
	return 0;
}

int GroupAggr::setInputSynopsis (RelationSynopsis *synopsis,
								 unsigned int scanId)
{
	this -> inputSynopsis = synopsis;
	this -> inScanId = scanId;
	return 0;
}

int GroupAggr::setOutStore (StorageAlloc *store)
{
	ASSERT (store);

	this -> outStore = store;
	return 0;
}

int GroupAggr::setInStore (StorageAlloc *store)
{
	ASSERT (store);

	this -> inStore = store;
	return 0;
}

int GroupAggr::setPlusEvaluator (AEval *plusEval)
{
	ASSERT (plusEval);

	this -> plusEval = plusEval;
	return 0;
}

int GroupAggr::setMinusEvaluator (AEval *minusEval)
{
	this -> minusEval = minusEval;
	return 0;
}

int GroupAggr::setEmptyGroupEvaluator (BEval *emptyGroupEval)
{
	this -> emptyGroupEval = emptyGroupEval;
	return 0;
}

int GroupAggr::setInitEvaluator (AEval *initEval)
{
	ASSERT (initEval);

	this -> initEval = initEval;
	return 0;
}

int GroupAggr::setUpdateEvaluator (AEval *updateEval)
{
	this -> updateEval = updateEval;
	return 0;
}

int GroupAggr::setRescanEvaluator (BEval *eval)
{
	this -> bScanNotReq = eval;
	return 0;
}

int GroupAggr::setEvalContext (EvalContext *evalContext)
{
	ASSERT (evalContext);

	this -> evalContext = evalContext;
	return 0;
}

int GroupAggr::run (TimeSlice timeSlice)
{
	int rc;
	unsigned int numElements;
	Element      inputElement;

#ifdef _MONITOR_
	startTimer ();
#endif

	// We have a stall and cannot clear it. Note the use of short-circuit
	// evaluation ..
	if (bStalled) {
		if (!outputQueue -> enqueue (stalledElement)) {
#ifdef _MONITOR_
			stopTimer ();
			logOutTs (lastOutputTs);
#endif
			return 0;
		}

		bStalled = false;
	}

	numElements = timeSlice;
	for (unsigned int e = 0 ; (e < numElements) && !bStalled ; e++) {

		// No space in output queue -- no scope for any processing
		if (outputQueue -> isFull())
			break;

		// Get the next input element
		if (!inputQueue -> dequeue (inputElement))
			break;

		lastInputTs = inputElement.timestamp;

		// Heartbeats can be ignored
		if (inputElement.kind == E_HEARTBEAT)
			continue;

		if (inputElement.kind == E_PLUS) {
			rc = processPlus (inputElement);
			if (rc != 0) return rc;
		}

		else {
			ASSERT (inputElement.kind == E_MINUS);
			rc = processMinus (inputElement);
			if (rc != 0) return rc;
		}

		UNLOCK_INPUT_TUPLE (inputElement.tuple);
	}

	// process heartbeats
	if (!outputQueue -> isFull() && (lastOutputTs < lastInputTs)) {
		outputQueue -> enqueue (Element::Heartbeat (lastInputTs));
		lastOutputTs = lastInputTs;
	}

#ifdef _MONITOR_
	stopTimer ();
	logOutTs (lastOutputTs);
#endif

	return 0;
}

int GroupAggr::processPlus (Element inputElement)
{
	int rc;
	Tuple          inpTuple;        // input tuple
	Tuple          oldAggrTuple;    // existing aggr for the tuple's group
	Tuple          newAggrTuple;    // new aggr for the tuple's group
	TupleIterator *scan;
	bool           bGroupExists;
	Element        plusElement, minusElement;

	// Xing: Currrent aggr level For minus usage. When a tuple expires from the window,
	// we should attach the LUB level with the expiring minus tuple
	oldAggrLevel = aggrLUBLevel[0];

	ASSERT (!bStalled);

	inpTuple = inputElement.tuple;

	// Bind the input tuple
	evalContext -> bind (inpTuple, INPUT_ROLE);

	// Get a scan that produces the group's aggregation tuple if it
	// exists.
	if ((rc = outputSynopsis -> getScan (outScanId, scan)) != 0)
		return rc;

	bGroupExists = scan -> getNext (oldAggrTuple);

#ifdef _DM_
	// There should be only one aggregation tuple per group
	Tuple dummy;
	ASSERT (!scan -> getNext (dummy));
#endif

	if ((rc = outputSynopsis -> releaseScan (outScanId, scan)) != 0)
		return rc;

	// We have seen a tuple belonging to this group before
	if (bGroupExists) {

		// We will create a new aggregation tuple for this group.
		// We should not overwrite the oldAggrTuple since someone
		// downstream might be reading it ...
		rc = outStore -> newTuple (newAggrTuple);
		if (rc != 0) return rc;

		// Plus evaluator does the job of computing the new aggregation
		// tuple from  the new input tuple and the old aggregation tuple.
		evalContext -> bind (oldAggrTuple, OLD_OUTPUT_ROLE);
		evalContext -> bind (newAggrTuple, NEW_OUTPUT_ROLE);
		plusEval -> eval ();

		// We insert the new aggr. tuple into the synopsis & delete the
		// old one
		rc = outputSynopsis -> insertTuple (newAggrTuple);
		// Xing: Update the plus level
		//updatePlusLUBLevel(inputElement.level);
		aggrLUBLevel[1111 & inputElement.level]++;
		if (inputElement.level > aggrLUBLevel[0])
			aggrLUBLevel[0] = inputElement.level;

		if (rc != 0) return rc;
		LOCK_OUTPUT_TUPLE (newAggrTuple);

		rc = outputSynopsis -> deleteTuple (oldAggrTuple);

		if (rc != 0) return rc;

		// Send a plus element corr. to newAggrTuple, and a minus element
		// corr. to oldAggrTuple.  We will never be blocked on the first
		// enqueue, since we have ensured that the queue is non-full
		// before coming here.
		ASSERT (!outputQueue -> isFull());

		// Plus element:
		plusElement.kind      = E_PLUS;
		plusElement.tuple     = newAggrTuple;
		plusElement.timestamp = inputElement.timestamp;
		// Xing: Update level
		plusElement.level     = aggrLUBLevel[0];

		outputQueue -> enqueue (plusElement);
		lastOutputTs = inputElement.timestamp;

		// Minus element:
		minusElement.kind      = E_MINUS;
		minusElement.tuple     = oldAggrTuple;
		minusElement.timestamp = inputElement.timestamp;
		// Xing: Use the old level
		minusElement.level     = oldAggrLevel;

		// We could get stalled now though ...
		if (!outputQueue -> enqueue (minusElement)) {
			bStalled = true;
			stalledElement = minusElement;
		}
	}

	// This is the first tuple belonging to this group
	else {
		// We create a new aggregation tuple for this new group.
		rc = outStore -> newTuple (newAggrTuple);
		if (rc != 0) return rc;

		evalContext -> bind (newAggrTuple, NEW_OUTPUT_ROLE);
		initEval -> eval ();

		// Insert the new aggregation tuple into the synopsis
		rc = outputSynopsis -> insertTuple (newAggrTuple);
		// Xing: Update the plus level
		//updatePlusLUBLevel(inputElement.level);
		aggrLUBLevel[1111 & inputElement.level]++;
		if (inputElement.level > aggrLUBLevel[0])
			aggrLUBLevel[0] = inputElement.level;

		if (rc != 0) return rc;
		LOCK_OUTPUT_TUPLE (newAggrTuple);

		// Send a plus element corresponding to this tuple. We will never
		// be blocked, since we have ensured that the queue is non-full
		// before coming here.
		ASSERT (!outputQueue -> isFull());

		plusElement.kind      = E_PLUS;
		plusElement.tuple     = newAggrTuple;
		plusElement.timestamp = inputElement.timestamp;
		// Xing: Update level
		plusElement.level     = aggrLUBLevel[0];

		outputQueue -> enqueue (plusElement);
		lastOutputTs = inputElement.timestamp;
	}

	// Maintain the input synopsis if it exists
	if (inputSynopsis) {
		rc = inputSynopsis -> insertTuple (inpTuple);
		if (rc != 0) return rc;

		LOCK_INPUT_TUPLE (inpTuple);
	}

	return 0;
}

int GroupAggr::processMinus (Element inputElement)
{
	int rc;
	Tuple          inpTuple;        // input tuple
	Tuple          oldAggrTuple;    // existing aggr for the tuple's group
	Tuple          newAggrTuple;    // new aggr for the tuple's group
	TupleIterator *scan;
	bool           bGroupExists;
	Element        plusElement, minusElement;

	ASSERT (!bStalled);

	inpTuple = inputElement.tuple;

	evalContext -> bind (inpTuple, INPUT_ROLE);

	// Maintain the input synopsis if it exists.  This should be done
	// before the rest of the processing since later code assumes that the
	// input synopsis is up-to-date for its correctness.
	if (inputSynopsis) {
		rc = inputSynopsis -> deleteTuple (inpTuple);
		if (rc != 0) return rc;

		UNLOCK_INPUT_TUPLE (inpTuple);
	}

	// Perform a scan to locate the current aggregation tuple for
	// the group to which the inpTuple belongs to, if it exists
	rc = outputSynopsis -> getScan (outScanId, scan);
	if (rc != 0) return rc;

	// Since we have got a MINUS tuple now, the PLUS tuple for it should
	// have arrived earlier, implying that there should be an output entry
	// for this group.
	bGroupExists = scan -> getNext (oldAggrTuple);
	ASSERT (bGroupExists);

	// There should be only one aggregation tuple per group
#ifdef _DM_
	Tuple dummy;
	ASSERT (!scan -> getNext (dummy));
#endif
	rc = outputSynopsis -> releaseScan (outScanId, scan);
	if (rc != 0) return rc;

	evalContext -> bind (oldAggrTuple, OLD_OUTPUT_ROLE);

	// There are two possibilities: the group becomes empty after this
	// minus tuple is processed, or otherwise.  emptyGroupEval (a slight
	// misnomer) checks if there is only one element in this group.
	if (emptyGroupEval -> eval()) {

		// delete the old aggregation tuple from our synopsis
		rc = outputSynopsis -> deleteTuple (oldAggrTuple);
		// Xing: Update the minus level
		// updateMinusLUBLevel(inputElement.level);
		aggrLUBLevel[1111 & inputElement.level]--;
			// From high to low level, if the count is not null, it is the LUB level
			// it should be stored in aggrLUBLevel[0]: from current LUB level
		// Only if the minus level equals the LUBlevel, we need to update
		if(inputElement.level == aggrLUBLevel[0] && aggrLUBLevel[inputElement.level] == 0){
			for(int k=aggrLUBLevel[0]-1; k>=1; k--){
				if(aggrLUBLevel[k]!=0){
				aggrLUBLevel[0] = k;
			//	printf("aggrLevel 1 %d: \n", aggrLUBLevel[1]);
			//	printf("Minus LUB current level %d: \n", aggrLUBLevel[0]);
				break;
				}
			}
		}

		if (rc != 0) return rc;

		// Minus element:
		minusElement.kind      = E_MINUS;
		minusElement.tuple     = oldAggrTuple;
		minusElement.timestamp = inputElement.timestamp;
		// Xing: update level info
		minusElement.level     = oldAggrLevel;

		// We have ensured before coming here that the output queue is
		// nonfull
		ASSERT (!outputQueue -> isFull());
		outputQueue -> enqueue (minusElement);
		lastOutputTs = minusElement.timestamp;
	}

	// The group remains active.
	else {

		// We will create a new aggregation tuple for this group.
		// We should not overwrite the oldAggrTuple since someone
		// downstream might be reading it ...
		rc = outStore -> newTuple (newAggrTuple);
		if (rc != 0) return rc;

		// Produce the new aggr. tuple for the group.
		rc = produceOutputTupleForMinus (newAggrTuple);
		if (rc != 0) return rc;

		// Insert the new aggr. tuple into the output synopsis and delete
		// the old one
		rc = outputSynopsis -> insertTuple (newAggrTuple);
		if (rc != 0) return rc;
		LOCK_OUTPUT_TUPLE (newAggrTuple);

		rc = outputSynopsis -> deleteTuple (oldAggrTuple);
		if (rc != 0) return rc;
		// Xing: Update the minus level
		// updateMinusLUBLevel(inputElement.level);
		aggrLUBLevel[1111 & inputElement.level]--;
					// From high to low level, if the count is not null, it is the LUB level
					// it should be stored in aggrLUBLevel[0]: from current LUB level
		// Only if the minus level equals the LUBlevel, we need to update
				if(inputElement.level == aggrLUBLevel[0] && aggrLUBLevel[inputElement.level] == 0){
					for(int k=aggrLUBLevel[0]-1; k>=1; k--){
						if(aggrLUBLevel[k]!=0){
						aggrLUBLevel[0] = k;
					//	printf("aggrLevel 1 %d: \n", aggrLUBLevel[1]);
					//	printf("Minus LUB current level %d: \n", aggrLUBLevel[0]);
						break;
						}
					}
				}

		// Send a plus element corr. to newAggrTuple, and a minus element
		// corr. to oldAggrTuple.  We will never be blocked on the first
		// enqueue, since we have ensured that the queue is non-full
		// before coming here.
		ASSERT (!outputQueue -> isFull());

		// Plus element:
		plusElement.kind      = E_PLUS;
		plusElement.tuple     = newAggrTuple;
		plusElement.timestamp = inputElement.timestamp;
		// Xing: update level info
		plusElement.level     = aggrLUBLevel[0];

		outputQueue -> enqueue (plusElement);
		lastOutputTs = inputElement.timestamp;

		// Minus element:
		minusElement.kind      = E_MINUS;
		minusElement.tuple     = oldAggrTuple;
		minusElement.timestamp = inputElement.timestamp;
		// Xing: update level info
		minusElement.level     = oldAggrLevel;

		// We could get stalled now though ...
		if (!outputQueue -> enqueue (minusElement)) {
			bStalled = true;
			stalledElement = minusElement;
		}
	}

	return 0;
}

int GroupAggr::produceOutputTupleForMinus (Tuple newAggrTuple)
{
	int rc;
	TupleIterator *inScan;
	Tuple inTuple;
	bool bNotEmpty;

	evalContext -> bind (newAggrTuple, NEW_OUTPUT_ROLE);

	// Assert: At this point, evalContext contains the new input tuple
	// (MINUS) and the old aggr. tuple for the input tuples group bound.

	// We first determine if we need to scan the entire inner relation to
	// update the new aggregation tuple (this can happen if we have MAX or
	// MIN aggregation functions) or if we can incrementatlly produce the
	// new Aggr. tuple for the group from the old aggr. tuple and the new
	// input tuple.

	// Scan required: We will essentially redo the steps that we used for
	// computing the aggr. tuple for the group in response to PLUS tuples.
	if (bScanNotReq -> eval ()) {
		minusEval -> eval ();
	}

	else {
		// scan iterator that returns all tuples in input synopsis
		// corresponding to the present group.
		if ((rc = inputSynopsis -> getScan (inScanId, inScan)) != 0)
			return rc;

		// If we come here the synopsis can't be empty
		bNotEmpty = inScan -> getNext (inTuple);
		ASSERT (bNotEmpty);

		// initialize newAggrTuple
		evalContext -> bind (inTuple, INPUT_ROLE);
		initEval -> eval ();

		// Inplace update of newAggrTuple
		while (inScan -> getNext (inTuple)) {
			evalContext -> bind (inTuple, INPUT_ROLE);
			updateEval -> eval ();
		}

		if ((rc = inputSynopsis -> releaseScan (inScanId, inScan)) != 0)
			return rc;
	}

	return 0;
}
// Xing: update the LUB level group
//void GroupAggr::updatePlusLUBLevel(int level){
//	aggrLUBLevel[1111 & level]++;
	// From high to low level, if the count is not null, it is the LUB level
	// it should be stored in aggrLUBLevel[0]. Note that at least there are one tuple in that level
	//if(level > aggrLUBLevel[0])
	//	aggrLUBLevel[0] = level;
//}
// XingL update the aggrLevel array
/*void GroupAggr::updateMinusLUBLevel(int level){
	aggrLUBLevel[1111 & level]--;
	// From high to low level, if the count is not null, it is the LUB level
	// it should be stored in aggrLUBLevel[0]: from current LUB level
	for(int k=4; k>=1; k--){
		if(aggrLUBLevel[k]!=0){
		aggrLUBLevel[0] = k;
	//	printf("aggrLevel 1 %d: \n", aggrLUBLevel[1]);
	//	printf("Minus LUB current level %d: \n", aggrLUBLevel[0]);
		break;
		}
	}

}
*/
// Xing: get the current level
/*unsigned int GroupAggr::getLUBLevel(){
	return aggrLUBLevel[0];
}
*/


text:
    struct InstanceDef
    {
        float4 posAndShadowing;
        float2 sinCosTheta;
    };

    StructuredBuffer<InstanceDef> InstanceOffsets : register(t15);

    float3 InstanceWorldPosition(VSInput input, out float3 objectCentreWorld)
    {
        float3 localPosition = GetLocalPosition(input);
        objectCentreWorld = InstanceOffsets[input.instanceId].posAndShadowing.xyz;
        float2 sc = InstanceOffsets[input.instanceId].sinCosTheta;
        float2x2 rotMat = float2x2(float2(sc.y, -sc.x), float2(sc.x, sc.y));
        float scale = .75f + .25f * sc.x;       // add cheap scale component (directly related to rotation)
        return float3(
            objectCentreWorld.xy + scale * mul(rotMat, localPosition.xy),
            objectCentreWorld.z +  scale * localPosition.z);
    }

    float GetInstanceShadowing(VSInput input)
    {
        return InstanceOffsets[input.instanceId].posAndShadowing.w;
    }

#endif


text:
<?xml version="1.0" encoding="UTF-8"?>
<ipxact:component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ipxact="http://www.accellera.org/XMLSchema/IPXACT/1685-2014" xmlns:kactus2="http://kactus2.cs.tut.fi" xsi:schemaLocation="http://www.accellera.org/XMLSchema/IPXACT/1685-2014 http://www.accellera.org/XMLSchema/IPXACT/1685-2014/index.xsd">
	<ipxact:vendor>tut.fi</ipxact:vendor>
	<ipxact:library>cpu.subsystem</ipxact:library>
	<ipxact:name>core_example</ipxact:name>
	<ipxact:version>1.0</ipxact:version>
	<ipxact:busInterfaces>
		<ipxact:busInterface>
			<ipxact:name>local_data</ipxact:name>
			<ipxact:busType vendor="tut.fi" library="interface" name="local_memory" version="1.1"/>
			<ipxact:abstractionTypes>
				<ipxact:abstractionType>
					<ipxact:abstractionRef vendor="tut.fi" library="interface" name="local_memory.absDef" version="1.1"/>
					<ipxact:portMaps>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>address</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>local_address_o</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>write_data</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>local_write_data</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>write</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>local_write_o</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>read_data</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>local_read_data</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
					</ipxact:portMaps>
				</ipxact:abstractionType>
			</ipxact:abstractionTypes>
			<ipxact:master/>
		</ipxact:busInterface>
		<ipxact:busInterface>
			<ipxact:name>peripheral_access</ipxact:name>
			<ipxact:busType vendor="tut.fi" library="interface" name="peripheral_control" version="1.0"/>
			<ipxact:abstractionTypes>
				<ipxact:abstractionType>
					<ipxact:abstractionRef vendor="tut.fi" library="interface" name="peripheral_control.absDef" version="1.0"/>
					<ipxact:portMaps>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>address</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>mem_address_o</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>data_ms</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>mem_data_o</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>data_sm</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>mem_data_i</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>we</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>mem_we_o</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>slave_rdy</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>mem_slave_rdy</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>master_rdy</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>mem_master_rdy</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
					</ipxact:portMaps>
				</ipxact:abstractionType>
			</ipxact:abstractionTypes>
			<ipxact:master/>
		</ipxact:busInterface>
		<ipxact:busInterface>
			<ipxact:name>instructions</ipxact:name>
			<ipxact:busType vendor="tut.fi" library="interface" name="local_memory" version="1.1"/>
			<ipxact:abstractionTypes>
				<ipxact:abstractionType>
					<ipxact:abstractionRef vendor="tut.fi" library="interface" name="local_memory.absDef" version="1.1"/>
					<ipxact:portMaps>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>address</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>iaddr_o</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
						<ipxact:portMap>
							<ipxact:logicalPort>
								<ipxact:name>read_data</ipxact:name>
							</ipxact:logicalPort>
							<ipxact:physicalPort>
								<ipxact:name>instruction_feed</ipxact:name>
							</ipxact:physicalPort>
						</ipxact:portMap>
					</ipxact:portMaps>
				</ipxact:abstractionType>
			</ipxact:abstractionTypes>
			<ipxact:master/>
		</ipxact:busInterface>
	</ipxact:busInterfaces>
	<ipxact:model>
		<ipxact:views>
			<ipxact:view>
				<ipxact:name>hierarchical_verilog</ipxact:name>
				<ipxact:designInstantiationRef>design</ipxact:designInstantiationRef>
				<ipxact:designConfigurationInstantiationRef>CoreExample.hierarchical.designcfg_1.0</ipxact:designConfigurationInstantiationRef>
			</ipxact:view>
		</ipxact:views>
		<ipxact:instantiations>
			<ipxact:designInstantiation>
				<ipxact:name>design</ipxact:name>
				<ipxact:designRef vendor="tut.fi" library="cpu.subsystem" name="core_example.design" version="1.0">
					<ipxact:configurableElementValues>
						<ipxact:configurableElementValue referenceId="uuid_6252a87b_fe78_4b09_9381_e67cf5d578f1">uuid_9d887d27_b1b6_4b29_b7c1_b9916038a6b4</ipxact:configurableElementValue>
						<ipxact:configurableElementValue referenceId="uuid_11e311ec_728c_41e5_a8bd_5a5c19862e23">uuid_ad551e0e_7aa5_4972_bb1d_ec97505a773e</ipxact:configurableElementValue>
						<ipxact:configurableElementValue referenceId="uuid_32a4e121_f983_437b_9ff4_b512d71f8267">uuid_113582c5_e9f8_4d52_9820_49dd1672e4a8</ipxact:configurableElementValue>
						<ipxact:configurableElementValue referenceId="uuid_bf948d2f_e2d7_497a_b33c_5e35aad3f1c3">uuid_3795f09f_a36f_477f_a331_5e2aaca9fb60</ipxact:configurableElementValue>
						<ipxact:configurableElementValue referenceId="uuid_c9e87023_cbe0_4790_8754_d38e8e83e2fe">uuid_240da555_796c_42e9_b09d_9769b11e8ac7</ipxact:configurableElementValue>
						<ipxact:configurableElementValue referenceId="uuid_5c010f8b_47c3_4bfd_9e82_0253bc69ef28">uuid_6e1d17f1_eadc_4bdc_886b_00a3c4016028</ipxact:configurableElementValue>
					</ipxact:configurableElementValues>
				</ipxact:designRef>
			</ipxact:designInstantiation>
			<ipxact:designConfigurationInstantiation>
				<ipxact:name>CoreExample.hierarchical.designcfg_1.0</ipxact:name>
				<ipxact:designConfigurationRef vendor="tut.fi" library="cpu.subsystem" name="core_example.verilog.designcfg" version="1.0"/>
			</ipxact:designConfigurationInstantiation>
		</ipxact:instantiations>
		<ipxact:ports>
			<ipxact:port>
				<ipxact:name>instruction_feed</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>in</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_113582c5_e9f8_4d52_9820_49dd1672e4a8-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>mem_address_o</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_6e1d17f1_eadc_4bdc_886b_00a3c4016028-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>mem_data_o</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_240da555_796c_42e9_b09d_9769b11e8ac7-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>mem_data_i</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>in</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_240da555_796c_42e9_b09d_9769b11e8ac7-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>mem_we_o</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>0</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>clk_i</ipxact:name>
				<ipxact:description>The mandatory clock, as this is synchronous logic.</ipxact:description>
				<ipxact:wire>
					<ipxact:direction>in</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>0</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:adHocVisible/>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>rst_i</ipxact:name>
				<ipxact:description>The mandatory reset, as this is synchronous logic.</ipxact:description>
				<ipxact:wire>
					<ipxact:direction>in</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>0</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:adHocVisible/>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>mem_slave_rdy</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>in</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>0</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>mem_master_rdy</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>0</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>iaddr_o</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_3795f09f_a36f_477f_a331_5e2aaca9fb60-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
				<ipxact:vendorExtensions>
					<kactus2:portTags></kactus2:portTags>
				</ipxact:vendorExtensions>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>local_address_o</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_6e1d17f1_eadc_4bdc_886b_00a3c4016028-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>local_write_data</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_240da555_796c_42e9_b09d_9769b11e8ac7-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>local_write_o</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>out</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>0</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
			<ipxact:port>
				<ipxact:name>local_read_data</ipxact:name>
				<ipxact:wire>
					<ipxact:direction>in</ipxact:direction>
					<ipxact:vectors>
						<ipxact:vector>
							<ipxact:left>uuid_240da555_796c_42e9_b09d_9769b11e8ac7-1</ipxact:left>
							<ipxact:right>0</ipxact:right>
						</ipxact:vector>
					</ipxact:vectors>
				</ipxact:wire>
			</ipxact:port>
		</ipxact:ports>
	</ipxact:model>
	<ipxact:description>Test arrangement for the example CPU with data memory, instuction memory, clock source, and SPI slave.</ipxact:description>
	<ipxact:parameters>
		<ipxact:parameter parameterId="uuid_240da555_796c_42e9_b09d_9769b11e8ac7" resolve="user" usageCount="5">
			<ipxact:name>DATA_WIDTH</ipxact:name>
			<ipxact:description>Width for data in registers and instructions.</ipxact:description>
			<ipxact:value>32</ipxact:value>
		</ipxact:parameter>
		<ipxact:parameter parameterId="uuid_6e1d17f1_eadc_4bdc_886b_00a3c4016028" resolve="user" usageCount="3">
			<ipxact:name>ADDR_WIDTH</ipxact:name>
			<ipxact:description>Width of the addresses.</ipxact:description>
			<ipxact:value>$clog2(uuid_9d887d27_b1b6_4b29_b7c1_b9916038a6b4)</ipxact:value>
		</ipxact:parameter>
		<ipxact:parameter parameterId="uuid_9d887d27_b1b6_4b29_b7c1_b9916038a6b4" resolve="user" usageCount="3">
			<ipxact:name>SUPPORTED_MEMORY</ipxact:name>
			<ipxact:description>How much the system supports memory in total.</ipxact:description>
			<ipxact:value>512</ipxact:value>
		</ipxact:parameter>
		<ipxact:parameter parameterId="uuid_ad551e0e_7aa5_4972_bb1d_ec97505a773e" resolve="user" usageCount="2">
			<ipxact:name>PERIPHERAL_BASE</ipxact:name>
			<ipxact:description>The first address for peripherals.</ipxact:description>
			<ipxact:value>128</ipxact:value>
		</ipxact:parameter>
		<ipxact:parameter parameterId="uuid_113582c5_e9f8_4d52_9820_49dd1672e4a8" resolve="user" usageCount="2">
			<ipxact:name>INSTRUCTION_WIDTH</ipxact:name>
			<ipxact:description>Total width of an instruction</ipxact:description>
			<ipxact:value>28</ipxact:value>
		</ipxact:parameter>
		<ipxact:parameter parameterId="uuid_3795f09f_a36f_477f_a331_5e2aaca9fb60" resolve="user" usageCount="2">
			<ipxact:name>INSTRUCTION_ADDRESS_WIDTH</ipxact:name>
			<ipxact:description>Width of an instruction address.</ipxact:description>
			<ipxact:value>8</ipxact:value>
		</ipxact:parameter>
	</ipxact:parameters>
	<ipxact:vendorExtensions>
		<kactus2:version>3,4,4,0</kactus2:version>
		<kactus2:kts_attributes>
			<kactus2:kts_productHier>IP</kactus2:kts_productHier>
			<kactus2:kts_implementation>HW</kactus2:kts_implementation>
			<kactus2:kts_firmness>Mutable</kactus2:kts_firmness>
		</kactus2:kts_attributes>
	</ipxact:vendorExtensions>
</ipxact:component>


text:
import Vue from 'vue';
import App from './App';
import $ from 'jquery';

Vue.transition('slide', {
  enterClass: 'fadeInLeft',
  leaveClass: 'slideOutLeftBig',
});
Vue.transition('arrowUp', {
  enterClass: 'fadeInDown',
  leaveClass: 'fadeOutUp',
});
Vue.transition('arrowDown', {
  enterClass: 'fadeInUp',
  leaveClass: 'fadeOutDown',
});
Vue.transition('pageClose', {
  enterClass: 'fadeInDownLeft',
  leaveClass: 'fadeOutUpRight',
});
Vue.transition('pageCopy', {
  enterClass: 'fadeInUpLeft',
  leaveClass: 'fadeOutDownRight',
});

Vue.directive('hover', {
  update: function update(value) {
    const self = this;
    const BODY = {
      width: $(window).width(),
      height: $(window).height(),
    };

    const mouseMoveFunc = function mouseMoveFunc(event) {
      const hoverTips = document.querySelector('#ls-hover-tips');
      const eClientX = event.clientX + 15;
      const eClientY = event.clientY + 15;
      if (!hoverTips) {
        $('head').eq(0).append(`

        `);
        $('body').append(`

${value || self.expression}

        `);
      } else {
        const hoverTipsBox = hoverTips.getBoundingClientRect();
        const $left = (BODY.width > eClientX + 150) ? eClientX : (eClientX - hoverTipsBox.width);
        hoverTips.style.display = 'block';
        hoverTips.style.left = `${$left}px`;
        hoverTips.style.top = `${eClientY}px`;
        hoverTips.innerHTML = `

${value || self.expression}

        `;

        const hoverTimeout = function hoverTimeout() {
          hoverTips.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
        };

        setTimeout(hoverTimeout, 1);
      }
    };

    const mouseLeaveFunc = function mouseLeaveFunc() {
      const hoverTips = document.querySelector('#ls-hover-tips');
      if (!!hoverTips && $('#ls-hover-tips').is(':visible')) {
        hoverTips.style.display = 'none';
      }
    };

    this.el.addEventListener('mousemove', mouseMoveFunc, false);
    this.el.addEventListener('mouseleave', mouseLeaveFunc, false);
  },
});

/* eslint-disable no-new */
new Vue({
  el: 'body',
  components: { App },
});