View Full Version : آموزش: نمونه کد
behzadboloori
دوشنبه 19 تیر 1391, 08:13 صبح
سلام
راستش من از اینکه همش توی فروم دلفی دنبال کد میگشتم تا تبدیلش کنم به سی خسته شدم. سعس کردم حداقل چیزایی رو که خودم دارم بذارم توی فروم تا شاید دیگران هم کمک کنند.
مثل اساتید دیگه توی فرم دلفی لیستش رو هم براتون میذارم.
امروز 20-04-91 دیدم دوستان دیگه هم نمونه کد دارن اضافه میکنن. من اونا رو هم بر اساس همون چیزی خودشون برای عنوان انتخاب کردن، میذارم.
1- تبدیل تاریخ شمسی به میلادی
2- تبدیل تاریخ میلادی به شمسی
3- ایجاد کردن Image در زمان اجرا
4- ریختن اطلاعات گرید در اکسل
5- رسم درخت فیثاقورس (Ananas)
6- انتخاب کردن چند ضلعی محدب (Ananas)
behzadboloori
دوشنبه 19 تیر 1391, 08:14 صبح
1- تبدیل تاریخ شمسی به میلادی
TDateTime __fastcall TMainForm::ShToGeor(AnsiString MyDate) {
DWORD wYear, wMonth, wDay;
DWORD nDay = 0;
// int i=1;
//int Len = MyDate.Length();
AnsiString WYear = "\0", WMonth = "\0", WDay = "\0";
/* do
{
WYear+=MyDate.SubString(i,1);
i=i+1;
} while (MyDate.SubString(i,1)!="/" && i<Len);
i++;
WYear=WYear.Trim();
do
{
WMonth+=MyDate.SubString(i++,1);
} while (MyDate.SubString(i,1)!="/" && i<Len);
i++;
WMonth=WMonth.Trim();
do
{
WDay+=MyDate.SubString(i++,1);
} while (MyDate.SubString(i,1)!="\0" && i<=Len);
WDay=WDay.Trim(); */
WYear = MyDate.SubString(1, 2);
WMonth = MyDate.SubString(3, 2);
WDay = MyDate.SubString(5, 2);
try {
wYear = StrToInt(WYear);
wMonth = StrToInt(WMonth);
wDay = StrToInt(WDay);
}
catch(...) {
throw Exception(u"تاریخ وارد شده درست نیست");
}
if (wYear == 0 && wMonth == 0 && wDay == 0)
return 7751;
if (wYear < 1300 && wYear > 100)
throw Exception(u"تاریخ وارد شده درست نیست");
if (wYear < 100)
wYear += 1300;
if (wMonth <= 6 && wDay > 31)
throw Exception(u"تعداد روزهای ماه بیش از 31 روز است");
if (wMonth <= 12 && wMonth > 6 && wDay > 30)
throw Exception(u"تعداد روزهای ماه بیش از 30 روز است");
if (wMonth > 12)
throw Exception(u"تعداد ماه های سال بیش از 12 ماه است");
if (wMonth <= 6 && wDay <= 31)
nDay = (wMonth - 1) * 31 + wDay;
else if (wMonth <= 12 && wDay <= 30)
nDay = 186 + (wMonth - 7) * 30 + wDay;
TDateTime cnvDate;
// ÑæÒ ÂÎÑ ÓÇá ãíáÇÏí
if (wYear < 100)
cnvDate = EncodeDate(1300 + wYear + 621, 3, 20);
else
cnvDate = EncodeDate(wYear + 621, 3, 20);
// در صورتیکه در محاسبه میلادی به شمسی در سال کبیسه میلادی عدد یک اضافه شود در اینجا باید عدد یک کم شود
nDay += cnvDate.Val;
return TDateTime((double)nDay-Kabiseh);
behzadboloori
دوشنبه 19 تیر 1391, 08:15 صبح
2- تبدیل تاریخ میلادی به شمسی
AnsiString __fastcall TMainForm::GeorToSh(TDateTime MyDate, int type) {
if (MyDate.Val == 0)
return "\0";
else {
SYSTEMTIME SysTime;
WORD wYear, wMonth, wDay;
DecodeDate(MyDate, wYear, wMonth, wDay);
GetLocalTime(&SysTime);
SysTime.wYear = wYear;
SysTime.wMonth = wMonth;
SysTime.wDay = wDay;
TDateTime CurrDate = SystemTimeToDateTime(SysTime);
if (SysTime.wMonth < 3)
SysTime.wYear--;
// ÚÏÏ ÒíÑ ÑæÒ Çæá ÓÇá ãíáÇÏí ãíÈÇÔÏ
else if (SysTime.wMonth == 3 && SysTime.wDay < 21)
SysTime.wYear--;
SysTime.wMonth = 3;
// ÚÏÏ ÒíÑ ÑæÒ ÂÎÑ ÓÇá ãíáÇÏí ãíÈÇÔÏ
SysTime.wDay = 20;
TDateTime DateRef = EncodeDate(SysTime.wYear, SysTime.wMonth,
SysTime.wDay);
// عدد یک اضافه شده به انتهای محاسبه برای جبران سال کبیسه میلادی میباشد.برای درست محاسبه نمودن تاریخ شمسی به به میلادی در آن ماژول نیز باید تغییراتی داده شود
// باید تغییراتی داده شود
DWORD dwOffset = CurrDate.Val - DateRef.Val+Kabiseh;
SysTime.wYear -= 621;
if (dwOffset <= 186) {
SysTime.wMonth = dwOffset / 31 + (dwOffset % 31 > 0);
SysTime.wDay = dwOffset % 31;
if (SysTime.wDay == 0)
SysTime.wDay = 31;
}
else {
SysTime.wMonth = 6 + (dwOffset - 185) / 30 +
((dwOffset - 186) % 30 > 0);
SysTime.wDay = (dwOffset - 186) % 30;
if (SysTime.wDay == 0)
SysTime.wDay = 30;
}
SysTime.wDayOfWeek = (SysTime.wDayOfWeek + 2) % 7;
TVarRec args[3];
args[0] = SysTime.wYear - 1300;
args[1] = SysTime.wMonth;
args[2] = SysTime.wDay;
AnsiString aa = Format("%2d%2.2d%2.2d", args, 2);
if (type == 1) //like 90/09/09
return Format("%2d/%2.2d/%2.2d", args, 2);
else if (type == 0) //like 900909
return Format("%2d%2.2d%2.2d", args, 2);
else if (type == 2) //like 1309/09/09
return Format("13%2d/%2.2d/%2.2d", args, 2);
}
return 0;
}
behzadboloori
دوشنبه 19 تیر 1391, 08:17 صبح
3- ایجاد کردن Image در زمان اجرا
TImage *Image2=new TImage(PhotoDataForm->Panel2);
Image2->Top=10;
Image2->Left=10;
Image2->Height=50;
Image2->Width=50;
Image2->Parent=this->Panel2;
Image2->Enabled==true;
Image2->Visible=true;
Image2->Stretch=true;
Image2->Picture->LoadFromFile(Filenames);
behzadboloori
دوشنبه 19 تیر 1391, 08:21 صبح
4- ریختن اطلاعات گرید در اکسل
Variant xlsfile;
if (SaveDialog1->Execute())
{
xlsfile=SaveDialog1->FileName;
//Image1->Picture->LoadFromFile(CurrentFile);
}
if(!xlsfile.operator WideString().IsEmpty() ){
//declare variables
Variant XL,v0,v1,v2,v3;
//open excel application
XL=Variant::CreateObject("excel.application");
//set the application as invisible, you can reverse “false” to “true” to make it visible
XL.OlePropertySet("Visible",false);
//Get workbook
v0=XL.OlePropertyGet("Workbooks");
//add one work book
v0.OleProcedure("Add");
//select workbook number 1
v1=v0.OlePropertyGet("Item",1);
//Get worksheet
v2=v1.OlePropertyGet("WorkSheets");
// add one work sheet
v2.OleFunction("Add");
//select worksheet number 1
v3=v2.OlePropertyGet("Item",1);
//rename worksheet it to “example1″
v3.OlePropertySet("Name",L"املاک");
//UnicodeString zz="";
int _rec_count=ADOQuery1->RecordCount;
int _field_count=DBGrid1->Columns->Count;
Variant temp,zz;
// Output the Header
for(int j=1;j<=_field_count;j++) {
//temp=ADOQuery1->Fields->
temp=DBGrid1->Columns->Items[j-1]->Title->Caption;
//if(temp==vt
v3.OlePropertyGet("Cells").OlePropertyGet("Item",1,j).OlePropertySet("Value",temp.operator WideString());
}
//UnicodeString uu;
ProgressBar1->Min=0;
ProgressBar1->Max=_rec_count;
ProgressBar1->Step=1;
ProgressBar1->Position=0;
for(int k=1;k<=_rec_count;k++) {
ProgressBar1->Position++;
for(int j=1;j<=_field_count;j++) {
temp=DBGrid1->Fields[j-1]->Value;
if(temp.vt==258) //== VT_BSTR
v3.OlePropertyGet("Cells").OlePropertyGet("Item",k+1,j).OlePropertySet("Value",temp.operator WideString());
else if (temp.vt==3) //==VT_INT
v3.OlePropertyGet("Cells").OlePropertyGet("Item",k+1,j).OlePropertySet("Value",temp.intVal);
else if (temp.vt==4) //==VT_INT
v3.OlePropertyGet("Cells").OlePropertyGet("Item",k+1,j).OlePropertySet("Value",temp.intVal);
else if (temp.vt==5) //==VT_INT
v3.OlePropertyGet("Cells").OlePropertyGet("Item",k+1,j).OlePropertySet("Value",temp.operator double());
else if (temp.vt==6) //==VT_INT
v3.OlePropertyGet("Cells").OlePropertyGet("Item",k+1,j).OlePropertySet("Value",temp.operator float());
else if (temp.vt==7) //==VT_Date
{
temp=MainForm->GeorToSh(temp,2);
v3.OlePropertyGet("Cells").OlePropertyGet("Item",k+1,j).OlePropertySet("Value",temp.operator WideString());
}
}
ADOQuery1->Next();
StatusBar1->Panels->Items[0]->Text=IntToStr(ADOQuery1->RecNo);
}
MessageDlg(u"پایان عملیات", mtWarning, TMsgDlgButtons() << mbOK, 0);
ProgressBar1->Position=0;
// at last, write your output at row 2 column 3
//sprintf(temp,"%lf",x);
//this will stop asking you where you want to same your excel file or not
XL.OlePropertySet("DisplayAlerts",false);
//save your excel file at “d” and name it as “case1.xls”
XL.OlePropertyGet("Workbooks").OlePropertyGet("Item",1).OleProcedure("SaveAs",xlsfile.operator WideString());
//Close the work book
v1.OleProcedure("Close");
//quite the excel application
XL.OleProcedure("Quit");
//unassign variable
XL=Unassigned;
}
ProgressBar1->Visible=false;
Ananas
سه شنبه 20 تیر 1391, 02:27 صبح
رسم درخت فیثاقورس :
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TPoint MousePointA;
TPoint MousePointB;
TMouseButton MouseBtn;
TBitmap *bitm;
void Redraw();
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
typedef struct TVertex
{
union
{
struct {float x, y;};
float f[2];
};
} * PVertex;
typedef struct TEdge
{
TEdge() {};
TEdge(const float x1, const float y1, const float x2, const float y2)
{v1.x = x1; v1.y = y1; v2.x = x2; v2.y = y2;};
union
{
struct {TVertex v1, v2;};
TVertex v[2];
float f[4];
};
} *PEdge;
TEdge MackRectLine(const PEdge ped)
{
// ______
// | |
// | |
// |......|
//
TEdge ed;
ed.v2.x = ped->v2.x - ped->v1.x;
ed.v2.y = ped->v2.y - ped->v1.y;
ed.v1.x = ped->v1.x - ed.v2.y; // x * cos - y * sin;
ed.v1.y = ped->v1.y + ed.v2.x; // x * sin + y * cos;
ed.v2.x += ed.v1.x;
ed.v2.y += ed.v1.y;
return ed;
};
TVertex MackTriLine(const PEdge ped)
{
//
// /\
// / \
// /....\
//
TVertex v;
v.x = (ped->v2.x + ped->v1.x + ped->v1.y - ped->v2.y) / 2.0f;
v.y = (ped->v2.y + ped->v1.y + ped->v2.x - ped->v1.x) / 2.0f;
return v;
};
TColor ColorScale(const TColor clr, const scale)
{
return ((((clr & 0x000000ff) * scale) / 0xff) & 0xff) |
((((((clr & 0x0000ff00) >> 8) * scale) / 0xff) & 0xff) << 8) |
((((((clr & 0x00ff0000) >> 16) * scale) / 0xff) & 0xff) << 16);
};
TColor ColorLerp(const TColor clr1, const TColor clr2, const scale)
{
return ((((clr1 & 0x000000ff) * scale + (clr2 & 0x000000ff) * (0xff - scale)) / 0xff) & 0xff) |
((((((clr1 & 0x0000ff00) >> 8) * scale + ((clr2 & 0x0000ff00) >> 8) * (0xff - scale)) / 0xff) & 0xff) << 8) |
((((((clr1 & 0x00ff0000) >> 16) * scale + ((clr2 & 0x00ff0000) >> 16) * (0xff - scale)) / 0xff) & 0xff) << 16);
};
void DrawRectAndTriAngle(const PEdge ped, TCanvas *pcanv, int counter = 8,
const int colorstep = 8,
const TColor clrR1 = 0x0000ff00,
const TColor clrR2 = 0x00000000,
const TColor clrT1 = 0x000000ff,
const TColor clrT2 = 0x00000000)
{
if (counter <= 0)
{
return;
};
pcanv->Brush->Style = bsSolid;
TPoint p[5];
TEdge ed = MackRectLine(ped);
p[0] = Point(ed.v2.x, ed.v2.y);
p[1] = Point(ped->v2.x, ped->v2.y);
p[2] = Point(ped->v1.x, ped->v1.y);
p[3] = Point(ed.v1.x, ed.v1.y);
pcanv->Brush->Color = ColorLerp(clrR1, clrR2, (counter * 0xff) / colorstep);
pcanv->Pen->Color = pcanv->Brush->Color;
//pcanv->Polyline(p, 3);
p[4] = p[0];
pcanv->Polygon(p, 4);
p[1] = p[3];
TVertex v = MackTriLine(&ed);
p[2] = Point(v.x, v.y);
p[3] = p[0];
pcanv->Brush->Color = ColorLerp(clrT1, clrT2, (counter * 0xff) / colorstep);
pcanv->Pen->Color = pcanv->Brush->Color;
pcanv->Polygon(p, 4);
//-----------------------
TEdge ed0 = TEdge(ed.v1.x, ed.v1.y, v.x, v.y);
DrawRectAndTriAngle(&ed0, pcanv, counter - 1, colorstep, clrR1, clrR2, clrT1, clrT2);
ed0 = TEdge(v.x, v.y, ed.v2.x, ed.v2.y);
DrawRectAndTriAngle(&ed0, pcanv, counter - 1, colorstep, clrR1, clrR2, clrT1, clrT2);
};
void Redraw()
{
bitm->SetSize(Form1->ClientWidth, Form1->ClientHeight);
bitm->Canvas->Brush->Color = 0x00000000;
bitm->Canvas->Pen->Style = psClear;
bitm->Canvas->Rectangle(0, 0, Form1->ClientWidth, Form1->ClientHeight);
bitm->Canvas->Pen->Style = psSolid;
DrawRectAndTriAngle(
&TEdge(
MousePointA.X,
MousePointA.Y,
MousePointB.X,
MousePointB.Y),
bitm->Canvas, 10, 10,
0x00004080,
0x00008000,
0x0000ffff,
0x0000ff00);
Form1->Canvas->Draw(0, 0, bitm);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MousePointA = MousePointB = Point(Screen->Width / 2, (Screen->Height * 2) / 3);
bitm = new Graphics::TBitmap();
this->WindowState = wsMaximized;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
MouseBtn = Button;
if (MouseBtn == mbLeft)
{
MousePointA = Point(X, Y);
}
else
{
MousePointB = Point(X, Y);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (MouseBtn == mbLeft)
{
MousePointB = Point(X, Y);
}
else
{
MousePointA = Point(X, Y);
}
Redraw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
this->OnMouseUp(Sender, mbLeft, Shift, X, Y);
}
//---------------------------------------------------------------------------
Ananas
سه شنبه 20 تیر 1391, 02:40 صبح
انتخاب کردن چند ضلعی محدب. تشخیص اینکه نقطه داخل چند ضلعی محدب هست یا نه (چند ضلعی رو به شکل آرایه ای از نقطه ها از نوع TVec2D بسازید و با تابع V2DIsInNGon یک نقطه رو تست کنید که داخل چند ضلعی هست یا بیرون) :
#ifndef SELECT2D_NGON_DEFINED
#define SELECT2D_NGON_DEFINED
#include <cmath>
using namespace std;
typedef struct TVec2D
{
public:
TVec2D() {};
TVec2D(const float x_, const float y_) {x = x_; y = y_;};
void SetVal(const float x_, const float y_) {x = x_; y = y_;};
void SetNormalVal(const float x_, const float y_)
{
float l = 1.0f / sqrtf(x_ * x_ + y_ * y_ + 1.0e-30f);
x = x_ * l;
y = y_ * l;
};
float Length() {return sqrtf(x * x + y * y);};
void Normalize()
{
float l = 1.0f / sqrtf(x * x + y * y + 1.0e-30f);
x *= l;
y *= l;
};
void NormalBetween2Point(const TVec2D from_vec, const TVec2D to_vec)
{
x = to_vec.x - from_vec.x;
y = to_vec.y - from_vec.y;
float l = 1.0f / sqrtf(x * x + y * y + 1.0e-30f);
x *= l;
y *= l;
};
float x, y;
} *PVec2D;
float V2DDot(const TVec2D v1, const TVec2D v2)
{
return (v1.x * v2.x + v1.y * v2.y);
};
float sqrf(const float x)
{
return (x * x);
};
float V2DDistance(const TVec2D v1, const TVec2D v2)
{
return sqrtf(sqrf(v2.x - v1.x) + sqrf(v2.y - v1.y));
};
bool V2DIsInTriangle(const TVec2D V, const TVec2D * aV)
{
TVec2D v0, v1, v2, v3;
v1.NormalBetween2Point(aV[0], aV[2]);
v2.NormalBetween2Point(aV[0], aV[1]);
v3.NormalBetween2Point(aV[0], V);
if (V2DDot(v1, v2) > V2DDot(v1, v3)) {return false;} else
{
v0 = v2;
v1.SetVal(-v1.x,-v1.y);
v2.NormalBetween2Point(aV[2], aV[1]);
v3.NormalBetween2Point(aV[2], V);
if (V2DDot(v1, v2) > V2DDot(v1, v3)) {return false;} else
{
v2.SetVal(-v1.x, -v1.y);
v3.NormalBetween2Point(aV[0], V);
v1 = v0;
return (V2DDot(v1, v2) < V2DDot(v1, v3));
};
};
};
int FloorBy(const int x, const int LoopValue)
{
return (x % LoopValue);
};
bool V2DIsInNGon(const TVec2D V, const TVec2D * aV, const int edgeCount)
{
if (edgeCount < 3) {return false;};
TVec2D v0, v1, v2;
v2.NormalBetween2Point(aV[1], aV[0]);
for (int i = 0; i < edgeCount; i++)
{
v0.NormalBetween2Point(V, aV[FloorBy(i + 1, edgeCount)]);
v1.SetVal(-v2.x, -v2.y); //v1.NormalBetween2Point(aV[FloorBy(i, edgeCount)], aV[FloorBy(i + 1, edgeCount)]);
v2.NormalBetween2Point(aV[FloorBy(i + 2, edgeCount)], aV[FloorBy(i + 1, edgeCount)]);
if (V2DDot(v2, v1) > V2DDot(v0, v1)) {return false;};
}
return true;
};
#endif
Ananas
چهارشنبه 21 تیر 1391, 21:03 عصر
تابع محاسبه ی گاما و فاکتوریل اعشاری با فرمول استرلینگ و استفاده از اعدادبرنولی :
// --------------
// Be Name Khoda
// gamma_fns.h
// MHD_1391.
// --------------
#ifndef GAMMA_FUNCTIONS_DEFINED
#define GAMMA_FUNCTIONS_DEFINED
#include <math.h>
using namespace std;
#define G_INFINITY (1.0L / 0.0L)
#define G_MAX_GAMMA_INPUT 1725.0L // 1725! is very big.
#define G_LOOPCOUNT 10 // if (-10 < x < 10) then use (x +- 10)!
#define G_PI 3.1415926535897932384626433832795L
#define G_LN2PI_2 9.1893853320467274178032973640562E-1L // Ln(2 * pi) / 2
const long double G_BERNOLIS[13] = {1.0L, \ // array of Bernoli numbers.
1.6666666666666666666666666666666666E-1L, \
-3.3333333333333333333333333333333333E-2L, \
2.3809523809523809523809523809523809E-2L, \
-3.3333333333333333333333333333333333E-2L, \
7.5757575757575757575757575757575757E-2L, \
-2.5311355311355311355311355311355311E-1L, \
1.1666666666666666666666666666666666E+0L, \
-7.0921568627450980392156862745098039E+0L, \
5.4971177944862155388471177944862155E+1L, \
-5.2912424242424242424242424242424242E+2L, \
6.1921231884057971014492753623188405E+3L, \
-8.6580253113553113553113553113553113E+4L \
};
long double FactBernoli(const long double x) // factorial just using Bernoli Numbers.
{
long double y = G_LN2PI_2 + (x + 0.5L) * logl(fabsl(x)) - x;
long double x2 = x * x; // x ^ 2.
long double xn = 1.0L / x;
for (int i = 1; i < 9; i++)
{
xn *= x2;
y += G_BERNOLIS[i] / (4.0L * i * (i - 0.5L) * xn); // 2 * i (2 * i - 1) * xn
}
if (y = G_INFINITY) // y is very big and can not calculate exp.
return y; // exp(y) == Infinity.
else // can calculate exp.
return expl(y); // e ^ Ln(z!)
}
long double Factorial(const long double x) // complate true Factorial function.
{
if ((x > G_MAX_GAMMA_INPUT) || ((x < 0.0L) && (int(x) == x)))
return G_INFINITY;
if (x == 0)
return 1.0L;
long double y;
if ((-G_LOOPCOUNT < x) && (x < G_LOOPCOUNT))
{
if (x < 0.0L)
{
long double xn = x - G_LOOPCOUNT;
y = FactBernoli(xn); // (x - 10)!
for (int i = 0; i < G_LOOPCOUNT; i++) // x! = (x - n)! * (x * (x - 1) * (x - 2) * ... * (x - n + 1))
{
xn += 1.0L;
y *= xn; // x! == (x - 1)! * x
}
}
else // x > 0
{
long double xn = x + G_LOOPCOUNT;
y = FactBernoli(xn); // (x + 10)!
for (int i = 0; i < G_LOOPCOUNT; i++) // x! = (x + n)! / ((x + 1) * (x + 2) * ... * (x + n))
{
y /= xn; // x! == (x + 1)! / (x + 1)
xn -= 1.0L;
}
}
}
else // x < -max || max < x
y = FactBernoli(x);
if (x < 0.0L)
y /= sinl(-G_PI * x) * 2.0L;
return y;
}
long double Gamma(const long double x) // Gamma function.
{
return Factorial(x - 1.0L);
}
#endif
قبلا این کد رو با دلفی نوشته بودم بعد دیروز خواستم دوباره با استفاده از فرمول ریاضیش که تو اینترنت هم پیدا میشه بنویسمش. هر کاری کردم مثل کد بالا نشد و اشتباه زیاد داشت. بعد از چند ساعت می خواستم با مشت برم تو مانیتور. امروز فایل قبلیمو پیدا کردم و از روش تبدیل به C++ کردم.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.